mirror of
https://github.com/journeyman-cc/smeagol.git
synced 2026-04-12 18:05:06 +00:00
Merge branch 'feature/13' into develop
This commit is contained in:
commit
6b6c7fb014
11 changed files with 498 additions and 159 deletions
210
README.md
210
README.md
|
|
@ -1,91 +1,119 @@
|
|||

|
||||
|
||||
# Welcome to Smeagol!
|
||||
Smeagol is a simple Wiki engine inspired by [Gollum](https://github.com/gollum/gollum/wiki). Gollum is a Wiki engine written in Ruby, which uses a number of simple text formats including [Markdown](http://daringfireball.net/projects/markdown/), and which uses [Git](http://git-scm.com/) to provide versioning and backup. I needed a new Wiki for a project and thought Gollum would be ideal - but unfortunately it doesn't provide user authentication, which I needed, and it was simpler for me to reimplement the bits I did need in Clojure than to modify Gollum.
|
||||
|
||||
So at this stage Smeagol is a Wiki engine written in Clojure which uses Markdown as its text format, which does have user authentication, and which uses Git as its versioning and backup system.
|
||||
|
||||
## Status
|
||||
Smeagol is now a fully working small Wiki engine, and meets my own immediate needs.
|
||||
|
||||
## Markup syntax
|
||||
Smeagol uses the Markdown format as provided by [markdown-clj](https://github.com/yogthos/markdown-clj), with the addition that anything enclosed in double square brackets, \[\[like this\]\], will be treated as a link into the wiki itself.
|
||||
|
||||
## Security and authentication
|
||||
Security is now greatly improved. There is a file called *passwd* in the *resources* directory, which contains a clojure map which maps usernames to maps with plain-text passwords and emails thus:
|
||||
|
||||
{:admin {:password "admin" :email "admin@localhost" :admin true}
|
||||
:adam {:password "secret" :email "adam@localhost"}}
|
||||
|
||||
that is to say, the username is a keyword and the corresponding password is a string. However, since version 0.5.0, users can now change their own passwords, and when the user changes their password their new password is encrypted using the [scrypt](http://www.tarsnap.com/scrypt.html) one-way encryption scheme. The password file is now no longer either in the *resources/public* directory so cannot be downloaded through the browser, nor in the git archive to which the Wiki content is stored, so that even if that git archive is remotely clonable an attacker cannot get the password file that way.
|
||||
|
||||
## Images
|
||||
Smeagol does not currently have any mechanism to upload images. You can, however, link to images already available on the web, like this:
|
||||
|
||||

|
||||
|
||||
## Todo
|
||||
* Mechanism to add users through the user interface;
|
||||
|
||||
## Advertisement
|
||||
If you like what you see here, I am available for work on open source Clojure projects. Contact me via [WEFT](http://www.weft.scot/).
|
||||
|
||||
### Phoning home
|
||||
Smeagol currently requests the WEFT logo in the page footer from my home site. This is mainly so I can get a feel for how many people are using the product. If you object to this, edit the file
|
||||
|
||||
resources/templates/base.html
|
||||
|
||||
and replace the line
|
||||
|
||||
<img height="16" width="16" alt="The Web Engineering Factory & Toolworks" src="http://www.weft.scot/images/weft.logo.64.png"> Developed by <a href="http://www.weft.scot/">WEFT</a>
|
||||
|
||||
with the line
|
||||
|
||||
<img height="16" width="16" alt="The Web Engineering Factory & Toolworks" src="img/weft.logo.64.png"> Developed by <a href="http://www.weft.scot/">WEFT</a>
|
||||
|
||||
## License
|
||||
Copyright © 2014-2015 Simon Brooke. Licensed under the GNU General Public License,
|
||||
version 2.0 or (at your option) any later version. If you wish to incorporate
|
||||
parts of Smeagol into another open source project which uses a less restrictive
|
||||
license, please contact me; I'm open to dual licensing it.
|
||||
|
||||
## Prerequisites
|
||||
You will need [Leiningen](https://github.com/technomancy/leiningen) 2.0 or above installed.
|
||||
|
||||
You will need [node](https://nodejs.org/en/) and [bower](https://bower.io/) installed.
|
||||
|
||||
## Running
|
||||
To start a web server for the application, run:
|
||||
|
||||
lein bower install
|
||||
lein ring server
|
||||
|
||||
Alternatively, if you want to deploy to a servlet container (which I would strongly recommend), the simplest thing is to run:
|
||||
|
||||
lein bower install
|
||||
lein ring uberwar
|
||||
|
||||
(a command which I'm sure Smeagol would entirely appreciate) and deploy the resulting war file.
|
||||
|
||||
## Experimental Docker image
|
||||
|
||||
You can now run Smeagol as a [Docker](http://www.docker.com) image. To run my Docker image, use
|
||||
|
||||
docker run simonbrooke/smeagol
|
||||
|
||||
Smeagol will run, obviously, on the IP address of your Docker image, on port 8080. To find the IP address, start the image using the command above and then use
|
||||
|
||||
docker inspect --format '{{ .NetworkSettings.IPAddress }}' $(docker ps -q)
|
||||
|
||||
Suppose this prints '10.10.10.10', then the URL to browse to will be http://10.10.10.10:8080/smeagol/
|
||||
|
||||
This image is _experimental_, but it does seem to work fairly well. What it does **not** yet do, however, is push the git repository to a remote location, so when you tear the Docker image down your edits will be lost. My next objective for this image is for it to have a cammand line parameter being the git address of a repository from which it can initialise the Wiki content, and to which it will periodically push local changes to the Wiki content.
|
||||
|
||||
To build your own Docker image, run:
|
||||
|
||||
lein clean
|
||||
lein bower install
|
||||
lein ring uberwar
|
||||
lein docker build
|
||||
|
||||
This will build a new Docker image locally; you can, obviously, push it to your own Docker repository if you wish.
|
||||

|
||||
|
||||
# Welcome to Smeagol!
|
||||
Smeagol is a simple Wiki engine inspired by [Gollum](https://github.com/gollum/gollum/wiki). Gollum is a Wiki engine written in Ruby, which uses a number of simple text formats including [Markdown](http://daringfireball.net/projects/markdown/), and which uses [Git](http://git-scm.com/) to provide versioning and backup. I needed a new Wiki for a project and thought Gollum would be ideal - but unfortunately it doesn't provide user authentication, which I needed, and it was simpler for me to reimplement the bits I did need in Clojure than to modify Gollum.
|
||||
|
||||
So at this stage Smeagol is a Wiki engine written in Clojure which uses Markdown as its text format, which does have user authentication, and which uses Git as its versioning and backup system.
|
||||
|
||||
## Status
|
||||
Smeagol is now a fully working small Wiki engine, and meets my own immediate needs.
|
||||
|
||||
## Markup syntax
|
||||
Smeagol uses the Markdown format as provided by [markdown-clj](https://github.com/yogthos/markdown-clj), with the addition that anything enclosed in double square brackets, \[\[like this\]\], will be treated as a link into the wiki itself.
|
||||
|
||||
## Security and authentication
|
||||
Security is now greatly improved. There is a file called *passwd* in the *resources* directory, which contains a clojure map which maps usernames to maps with plain-text passwords and emails thus:
|
||||
|
||||
{:admin {:password "admin" :email "admin@localhost" :admin true}
|
||||
:adam {:password "secret" :email "adam@localhost"}}
|
||||
|
||||
that is to say, the username is a keyword and the corresponding password is a string. However, since version 0.5.0, users can now change their own passwords, and when the user changes their password their new password is encrypted using the [scrypt](http://www.tarsnap.com/scrypt.html) one-way encryption scheme. The password file is now no longer either in the *resources/public* directory so cannot be downloaded through the browser, nor in the git archive to which the Wiki content is stored, so that even if that git archive is remotely clonable an attacker cannot get the password file that way.
|
||||
|
||||
## Images
|
||||
Smeagol does not currently have any mechanism to upload images. You can, however, link to images already available on the web, like this:
|
||||
|
||||

|
||||
|
||||
## Now with data visualisation
|
||||
|
||||
Inspired by [visdown](http://visdown.amitkaps.com/) and [vega-lite](https://vega.github.io/vega-lite/docs/), you can now embed visualisations into Smeagol pages, like this:
|
||||
|
||||
### Flight punctuality at London airports
|
||||
|
||||
Example cribbed in its entirety from [here](http://visdown.amitkaps.com/london):
|
||||
```vis
|
||||
data:
|
||||
url: "data/london.csv"
|
||||
transform:
|
||||
-
|
||||
filter: datum.year == 2016
|
||||
mark: rect
|
||||
encoding:
|
||||
x:
|
||||
type: nominal
|
||||
field: source
|
||||
y:
|
||||
type: nominal
|
||||
field: dest
|
||||
color:
|
||||
type: quantitative
|
||||
field: flights
|
||||
aggregate: sum
|
||||
```
|
||||
|
||||
Note that this visualisation will not be rendered in the GitHub wiki, as it doesn't have Smeagol's data visualisation magic. This is what it should look like:
|
||||
|
||||

|
||||
|
||||
## Advertisement
|
||||
If you like what you see here, I am available for work on open source Clojure projects.
|
||||
|
||||
### Phoning home
|
||||
Smeagol currently requests the WEFT logo in the page footer from my home site. This is mainly so I can get a feel for how many people are using the product. If you object to this, edit the file
|
||||
|
||||
resources/templates/base.html
|
||||
|
||||
and replace the line
|
||||
|
||||
<img height="16" width="16" alt="The Web Engineering Factory & Toolworks" src="http://www.weft.scot/images/weft.logo.64.png"> Developed by <a href="http://www.weft.scot/">WEFT</a>
|
||||
|
||||
with the line
|
||||
|
||||
<img height="16" width="16" alt="The Web Engineering Factory & Toolworks" src="img/weft.logo.64.png"> Developed by <a href="http://www.weft.scot/">WEFT</a>
|
||||
|
||||
## License
|
||||
Copyright © 2014-2015 Simon Brooke. Licensed under the GNU General Public License,
|
||||
version 2.0 or (at your option) any later version. If you wish to incorporate
|
||||
parts of Smeagol into another open source project which uses a less restrictive
|
||||
license, please contact me; I'm open to dual licensing it.
|
||||
|
||||
## Prerequisites
|
||||
You will need [Leiningen](https://github.com/technomancy/leiningen) 2.0 or above installed.
|
||||
|
||||
You will need [node](https://nodejs.org/en/) and [bower](https://bower.io/) installed.
|
||||
|
||||
## Running
|
||||
To start a web server for the application, run:
|
||||
|
||||
lein bower install
|
||||
lein ring server
|
||||
|
||||
Alternatively, if you want to deploy to a servlet container (which I would strongly recommend), the simplest thing is to run:
|
||||
|
||||
lein bower install
|
||||
lein ring uberwar
|
||||
|
||||
(a command which I'm sure Smeagol would entirely appreciate) and deploy the resulting war file.
|
||||
|
||||
## Experimental Docker image
|
||||
|
||||
You can now run Smeagol as a [Docker](http://www.docker.com) image. To run my Docker image, use
|
||||
|
||||
docker run simonbrooke/smeagol
|
||||
|
||||
Smeagol will run, obviously, on the IP address of your Docker image, on port 8080. To find the IP address, start the image using the command above and then use
|
||||
|
||||
docker inspect --format '{{ .NetworkSettings.IPAddress }}' $(docker ps -q)
|
||||
|
||||
Suppose this prints '10.10.10.10', then the URL to browse to will be http://10.10.10.10:8080/smeagol/
|
||||
|
||||
This image is _experimental_, but it does seem to work fairly well. What it does **not** yet do, however, is push the git repository to a remote location, so when you tear the Docker image down your edits will be lost. My next objective for this image is for it to have a cammand line parameter being the git address of a repository from which it can initialise the Wiki content, and to which it will periodically push local changes to the Wiki content.
|
||||
|
||||
To build your own Docker image, run:
|
||||
|
||||
lein clean
|
||||
lein bower install
|
||||
lein ring uberwar
|
||||
lein docker build
|
||||
|
||||
This will build a new Docker image locally; you can, obviously, push it to your own Docker repository if you wish.
|
||||
|
|
|
|||
36
project.clj
36
project.clj
|
|
@ -1,30 +1,30 @@
|
|||
(defproject smeagol "0.5.0-rc3"
|
||||
(defproject smeagol "0.5.1-SNAPSHOT"
|
||||
:description "A simple Git-backed Wiki inspired by Gollum"
|
||||
:url "https://github.com/simon-brooke/smeagol"
|
||||
:dependencies [[org.clojure/clojure "1.7.0"]
|
||||
:dependencies [[org.clojure/clojure "1.8.0"]
|
||||
[org.clojure/core.memoize "0.5.9"]
|
||||
[com.taoensso/encore "2.91.1"]
|
||||
[lib-noir "0.9.9" :exclusions [org.clojure/tools.reader]]
|
||||
[com.cemerick/url "0.1.1"]
|
||||
[ring-server "0.4.0"]
|
||||
[selmer "1.10.9"]
|
||||
|
||||
[org.clojure/data.json "0.2.6"]
|
||||
[org.clojure/tools.logging "0.4.0"]
|
||||
[com.taoensso/timbre "4.10.0"]
|
||||
[clj-jgit "0.8.9"]
|
||||
[clj-yaml "0.4.0"]
|
||||
[com.cemerick/url "0.1.1"]
|
||||
[com.fzakaria/slf4j-timbre "0.3.7"]
|
||||
[com.taoensso/encore "2.91.1"]
|
||||
[com.taoensso/timbre "4.10.0"]
|
||||
[com.taoensso/tower "3.0.2" :exclusions [com.taoensso/encore]]
|
||||
[crypto-password "0.2.0"]
|
||||
[environ "1.1.0"]
|
||||
[im.chit/cronj "1.4.4"]
|
||||
[lib-noir "0.9.9" :exclusions [org.clojure/tools.reader]]
|
||||
[markdown-clj "0.9.99" :exclusions [com.keminglabs/cljx]]
|
||||
[noir-exception "0.2.5"]
|
||||
[org.slf4j/slf4j-api "1.7.25"]
|
||||
[org.slf4j/log4j-over-slf4j "1.7.25"]
|
||||
[org.slf4j/jul-to-slf4j "1.7.25"]
|
||||
[org.slf4j/jcl-over-slf4j "1.7.25"]
|
||||
|
||||
[com.taoensso/tower "3.0.2" :exclusions [com.taoensso/encore]]
|
||||
[markdown-clj "0.9.99" :exclusions [com.keminglabs/cljx]]
|
||||
[crypto-password "0.2.0"]
|
||||
[clj-jgit "0.8.9"]
|
||||
[environ "1.1.0"]
|
||||
[im.chit/cronj "1.4.4"]
|
||||
[noir-exception "0.2.5"]
|
||||
[prone "1.1.4"]]
|
||||
[prone "1.1.4"]
|
||||
[ring-server "0.4.0"]
|
||||
[selmer "1.10.9"]]
|
||||
|
||||
:repl-options {:init-ns smeagol.repl}
|
||||
:jvm-opts ["-server"]
|
||||
|
|
|
|||
|
|
@ -24,8 +24,39 @@ Smeagol does not currently have any mechanism to upload images. You can, however
|
|||
|
||||

|
||||
|
||||
## Now with data visualisation
|
||||
|
||||
Inspired by [visdown](http://visdown.amitkaps.com/) and [vega-lite](https://vega.github.io/vega-lite/docs/), you can now embed visualisations into Smeagol pages, like this:
|
||||
|
||||
### Flight punctuality at London airports
|
||||
|
||||
Example cribbed in its entirety from [here](http://visdown.amitkaps.com/london):
|
||||
```vis
|
||||
data:
|
||||
url: "data/london.csv"
|
||||
transform:
|
||||
-
|
||||
filter: datum.year == 2016
|
||||
mark: rect
|
||||
encoding:
|
||||
x:
|
||||
type: nominal
|
||||
field: source
|
||||
y:
|
||||
type: nominal
|
||||
field: dest
|
||||
color:
|
||||
type: quantitative
|
||||
field: flights
|
||||
aggregate: sum
|
||||
```
|
||||
|
||||
Note that this visualisation will not be rendered in the GitHub wiki, as it doesn't have Smeagol's data visualisation magic. This is what it should look like:
|
||||
|
||||

|
||||
|
||||
## Advertisement
|
||||
If you like what you see here, I am available for work on open source Clojure projects. Contact me via [WEFT](http://www.weft.scot/).
|
||||
If you like what you see here, I am available for work on open source Clojure projects.
|
||||
|
||||
### Phoning home
|
||||
Smeagol currently requests the WEFT logo in the page footer from my home site. This is mainly so I can get a feel for how many people are using the product. If you object to this, edit the file
|
||||
|
|
|
|||
|
|
@ -197,6 +197,11 @@ th {
|
|||
border: thin solid silver;
|
||||
}
|
||||
|
||||
|
||||
.data-visualisation {
|
||||
padding: 0.25em 5%;
|
||||
}
|
||||
|
||||
.error {
|
||||
width: 100%;
|
||||
background-color: red;
|
||||
|
|
@ -231,6 +236,10 @@ th {
|
|||
color: white;
|
||||
}
|
||||
|
||||
.vega-bindings, .vega-actions {
|
||||
font-size: 66%;
|
||||
}
|
||||
|
||||
.warn {
|
||||
color: maroon;
|
||||
}
|
||||
|
|
|
|||
158
resources/public/data/london.csv
Normal file
158
resources/public/data/london.csv
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
"source","dest","airline","flights","onTimePerf","delayAverage","year"
|
||||
"LHR","ORD","AA",2490,66.33,21.11,2010
|
||||
"LHR","ORD","BA",1413,57.63,23.3,2010
|
||||
"LHR","ORD","UA",2105,73.24,14.57,2010
|
||||
"LHR","ORD","VS",218,77.06,11.1,2010
|
||||
"LHR","LAX","AA",706,66.38,17.66,2010
|
||||
"LHR","LAX","BA",1914,50.18,31.01,2010
|
||||
"LHR","LAX","UA",698,81.81,13.62,2010
|
||||
"LHR","LAX","VS",1285,56.86,21.92,2010
|
||||
"LHR","JFK","AA",3205,67.36,20.31,2010
|
||||
"LHR","JFK","BA",4181,66.59,20.84,2010
|
||||
"LHR","JFK","DL",1611,62.12,23.74,2010
|
||||
"LHR","JFK","KU",305,46.56,38.75,2010
|
||||
"LHR","JFK","VS",2067,59.62,23.69,2010
|
||||
"LHR","EWR","BA",1828,70.25,17.67,2010
|
||||
"LHR","EWR","CO",2697,69.28,18.87,2010
|
||||
"LHR","EWR","VS",1399,65.62,23.15,2010
|
||||
"LHR","IAD","BA",2011,62.11,21.71,2010
|
||||
"LHR","IAD","UA",2094,74.67,14.11,2010
|
||||
"LHR","IAD","VS",700,66.24,19.75,2010
|
||||
"LCY","JFK","BA",1012,89.12,5.67,2010
|
||||
"LHR","ORD","AA",2532,76.87,13.34,2011
|
||||
"LHR","ORD","BA",1440,76.32,14.42,2011
|
||||
"LHR","ORD","UA",2106,79.36,15.2,2011
|
||||
"LHR","ORD","VS",302,82.72,8.66,2011
|
||||
"LHR","LAX","AA",730,75.48,13.66,2011
|
||||
"LHR","LAX","BA",1984,63.46,18.47,2011
|
||||
"LHR","LAX","UA",698,83.52,11.7,2011
|
||||
"LHR","LAX","VS",1397,79,11.2,2011
|
||||
"LHR","JFK","AA",2917,75.8,14.77,2011
|
||||
"LHR","JFK","BA",4944,73.56,14.65,2011
|
||||
"LHR","JFK","DL",2144,80.91,13.05,2011
|
||||
"LHR","JFK","KU",302,52.65,30.02,2011
|
||||
"LHR","JFK","VS",2104,76.32,15.09,2011
|
||||
"LHR","EWR","BA",2129,80.7,11.24,2011
|
||||
"LHR","EWR","CO",3503,78.42,14.19,2011
|
||||
"LHR","EWR","VS",1410,77.52,13.39,2011
|
||||
"LHR","IAD","BA",2157,74.08,14.11,2011
|
||||
"LHR","IAD","UA",2516,80.79,14,2011
|
||||
"LHR","IAD","VS",711,82.42,9.73,2011
|
||||
"LCY","JFK","BA",1031,92.05,4.12,2011
|
||||
"LHR","ORD","AA",2523,72.07,20.03,2012
|
||||
"LHR","ORD","BA",1445,70.03,17.73,2012
|
||||
"LHR","ORD","UA",2102,76.08,15.35,2012
|
||||
"LHR","ORD","VS",308,83.77,8.31,2012
|
||||
"LHR","LAX","AA",714,75.35,12.03,2012
|
||||
"LHR","LAX","BA",1874,63.48,18.34,2012
|
||||
"LHR","LAX","UA",693,76.16,14.88,2012
|
||||
"LHR","LAX","VS",1324,76.13,14.08,2012
|
||||
"LHR","JFK","AA",3367,75.72,12.75,2012
|
||||
"LHR","JFK","BA",5129,69.28,17.68,2012
|
||||
"LHR","JFK","DL",2151,77.63,13.59,2012
|
||||
"LHR","JFK","KU",307,52.12,32.02,2012
|
||||
"LHR","JFK","VS",2227,81.9,11.32,2012
|
||||
"LHR","EWR","BA",1920,73.02,15.88,2012
|
||||
"LHR","EWR","CO",612,84.48,9.24,2012
|
||||
"LHR","EWR","UA",2872,69.76,17.91,2012
|
||||
"LHR","EWR","VS",1421,76.14,16.68,2012
|
||||
"LHR","IAD","BA",2014,71.45,16.23,2012
|
||||
"LHR","IAD","UA",2444,69.04,18.98,2012
|
||||
"LHR","IAD","VS",703,87.06,7.71,2012
|
||||
"LCY","JFK","BA",474,91.33,3.74,2012
|
||||
"LCY","JFK","BA",537,89.37,4.71,2012
|
||||
"LHR","ORD","AA",2513,74.69,15.29,2013
|
||||
"LHR","ORD","BA",1440,65.35,20.84,2013
|
||||
"LHR","ORD","UA",2110,78.39,14.13,2013
|
||||
"LHR","ORD","VS",324,83.02,9.05,2013
|
||||
"LHR","LAX","AA",728,76.48,12.56,2013
|
||||
"LHR","LAX","BA",1864,59.5,27.43,2013
|
||||
"LHR","LAX","UA",702,85.47,9.86,2013
|
||||
"LHR","LAX","VS",1288,79,13.76,2013
|
||||
"LHR","JFK","AA",2991,76.4,13.73,2013
|
||||
"LHR","JFK","BA",5350,66.97,18.95,2013
|
||||
"LHR","JFK","DL",2166,82.09,10.81,2013
|
||||
"LHR","JFK","KU",306,62.42,21.53,2013
|
||||
"LHR","JFK","VS",2825,81.91,10.53,2013
|
||||
"LHR","EWR","BA",1838,71.44,16.72,2013
|
||||
"LHR","EWR","UA",3494,80.59,12.36,2013
|
||||
"LHR","EWR","VS",1419,81.66,11.7,2013
|
||||
"LHR","IAD","BA",2012,71.02,18.67,2013
|
||||
"LHR","IAD","UA",2496,80.39,12.82,2013
|
||||
"LHR","IAD","VS",702,86.89,7.1,2013
|
||||
"LCY","JFK","BA",945,90.64,4.58,2013
|
||||
"LGW","LAX","DY",105,72.38,36.83,2014
|
||||
"LGW","JFK","DY",156,51.92,27.79,2014
|
||||
"LHR","ORD","AA",2476,73.5,22.09,2014
|
||||
"LHR","ORD","BA",1444,65.28,18.7,2014
|
||||
"LHR","ORD","UA",2110,77.56,13.68,2014
|
||||
"LHR","ORD","VS",348,81.32,8.86,2014
|
||||
"LHR","LAX","AA",728,76.79,18.56,2014
|
||||
"LHR","LAX","BA",1450,56.84,23.1,2014
|
||||
"LHR","LAX","DL",127,92.13,6.92,2014
|
||||
"LHR","LAX","UA",698,85.1,8.53,2014
|
||||
"LHR","LAX","VS",1217,80.99,12.58,2014
|
||||
"LHR","JFK","AA",2287,78.18,14.74,2014
|
||||
"LHR","JFK","BA",6018,71.29,16.59,2014
|
||||
"LHR","JFK","DL",2123,82.13,11.19,2014
|
||||
"LHR","JFK","KU",310,48.22,33.17,2014
|
||||
"LHR","JFK","VS",2820,79.77,12.45,2014
|
||||
"LHR","EWR","BA",1943,71.46,19.7,2014
|
||||
"LHR","EWR","UA",3485,78.3,15.19,2014
|
||||
"LHR","EWR","VS",1420,86.6,8.37,2014
|
||||
"LHR","IAD","BA",1807,74.58,15.31,2014
|
||||
"LHR","IAD","UA",2130,81.13,13.61,2014
|
||||
"LHR","IAD","VS",695,89.06,6.9,2014
|
||||
"LCY","JFK","BA",1003,91.23,4.43,2014
|
||||
"LGW","LAX","DY",328,66.46,21.41,2015
|
||||
"LGW","JFK","DY",543,64.09,31.78,2015
|
||||
"LHR","ORD","AA",2062,72.09,27.59,2015
|
||||
"LHR","ORD","BA",1442,71.4,16.24,2015
|
||||
"LHR","ORD","UA",2099,83.94,10.37,2015
|
||||
"LHR","ORD","VS",330,78.79,11.61,2015
|
||||
"LHR","LAX","AA",1265,75.42,14.5,2015
|
||||
"LHR","LAX","BA",1450,66.9,17.67,2015
|
||||
"LHR","LAX","DL",540,79.44,10.97,2015
|
||||
"LHR","LAX","UA",704,89.2,7.5,2015
|
||||
"LHR","LAX","VS",1230,80.81,12.74,2015
|
||||
"LHR","JFK","AA",2130,77.45,15.21,2015
|
||||
"LHR","JFK","BA",5994,77.84,13.61,2015
|
||||
"LHR","JFK","DL",2069,80.75,13.51,2015
|
||||
"LHR","JFK","KU",310,59.22,32.67,2015
|
||||
"LHR","JFK","VS",3363,76.35,13.82,2015
|
||||
"LHR","EWR","BA",1459,76.47,14.03,2015
|
||||
"LHR","EWR","DL",381,95.54,2.88,2015
|
||||
"LHR","EWR","UA",3493,79.23,16.31,2015
|
||||
"LHR","EWR","VS",871,81.75,10.7,2015
|
||||
"LHR","IAD","BA",1421,76.89,12.03,2015
|
||||
"LHR","IAD","UA",2126,81.74,14.02,2015
|
||||
"LHR","IAD","VS",703,85.49,12.59,2015
|
||||
"LCY","JFK","BA",937,92.74,4.52,2015
|
||||
"LTN","EWR","DJT",316,81.53,18.18,2015
|
||||
"LGW","LAX","DY",421,59.86,23.64,2016
|
||||
"LGW","LAX","DI",38,65.79,14.39,2016
|
||||
"LGW","JFK","BA",486,69.75,18.02,2016
|
||||
"LGW","JFK","DY",689,65.31,28.18,2016
|
||||
"LGW","JFK","DI",39,69.23,15.49,2016
|
||||
"LHR","ORD","AA",2453,71.82,26.15,2016
|
||||
"LHR","ORD","BA",1443,68.88,17.58,2016
|
||||
"LHR","ORD","UA",2085,82.25,14.2,2016
|
||||
"LHR","ORD","VS",333,89.79,5.07,2016
|
||||
"LHR","LAX","AA",1411,68.25,19.46,2016
|
||||
"LHR","LAX","BA",1452,54.34,24.89,2016
|
||||
"LHR","LAX","UA",700,87,8.48,2016
|
||||
"LHR","LAX","VS",1376,79.58,10.13,2016
|
||||
"LHR","JFK","AA",2623,76.82,21.41,2016
|
||||
"LHR","JFK","BA",5625,69.97,17.15,2016
|
||||
"LHR","JFK","DL",2081,80.37,13.42,2016
|
||||
"LHR","JFK","KU",253,19.76,71.96,2016
|
||||
"LHR","JFK","VS",3489,79.67,11.44,2016
|
||||
"LHR","EWR","AI",118,65.25,21.14,2016
|
||||
"LHR","EWR","BA",1444,76.11,13.49,2016
|
||||
"LHR","EWR","UA",3472,79.03,15.71,2016
|
||||
"LHR","EWR","VS",722,82.27,9.48,2016
|
||||
"LHR","IAD","BA",1415,71.59,17.44,2016
|
||||
"LHR","IAD","UA",2134,82.05,13.24,2016
|
||||
"LHR","IAD","VS",699,84.69,8.02,2016
|
||||
"LCY","JFK","BA",921,90.01,5.26,2016
|
||||
"LTN","EWR","DJT",333,87.05,8.44,2016
|
||||
|
BIN
resources/public/data/london.png
Normal file
BIN
resources/public/data/london.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.7 KiB |
|
|
@ -6,7 +6,6 @@
|
|||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link href="{{servlet-context}}/content/stylesheet.css" media="screen" rel="stylesheet" type="text/css" />
|
||||
<link href="{{servlet-context}}/css/print.css" media="print" rel="stylesheet" type="text/css" />
|
||||
{% block extra-headers %}
|
||||
{% endblock %}
|
||||
</head>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,18 @@
|
|||
{% extends "templates/base.html" %}
|
||||
|
||||
{% block extra-headers %}
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/vega/3.0.0-rc2/vega.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/vega-lite/2.0.0-beta.10/vega-lite.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/vega-embed/3.0.0-beta.19/vega-embed.js"></script>
|
||||
|
||||
<style media="screen">
|
||||
/* Add space between Vega-Embed links */
|
||||
.vega-actions a {
|
||||
margin-right: 5px;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div id="content" class="wiki">
|
||||
{% if editable %}
|
||||
|
|
|
|||
133
src/smeagol/formatting.clj
Normal file
133
src/smeagol/formatting.clj
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
(ns ^{:doc "Format Semagol's enhanced markdown format."
|
||||
:author "Simon Brooke"}
|
||||
smeagol.formatting
|
||||
(:require [clojure.string :as cs]
|
||||
[cemerick.url :refer (url url-encode url-decode)]
|
||||
[noir.io :as io]
|
||||
[noir.session :as session]
|
||||
[markdown.core :as md]
|
||||
[smeagol.authenticate :as auth]
|
||||
[clj-yaml.core :as yaml]
|
||||
[clojure.data.json :as json]))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;
|
||||
;;;; Smeagol: a very simple Wiki engine.
|
||||
;;;;
|
||||
;;;; This program is free software; you can redistribute it and/or
|
||||
;;;; modify it under the terms of the GNU General Public License
|
||||
;;;; as published by the Free Software Foundation; either version 2
|
||||
;;;; of the License, or (at your option) any later version.
|
||||
;;;;
|
||||
;;;; This program is distributed in the hope that it will be useful,
|
||||
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;;;; GNU General Public License for more details.
|
||||
;;;;
|
||||
;;;; You should have received a copy of the GNU General Public License
|
||||
;;;; along with this program; if not, write to the Free Software
|
||||
;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
;;;; USA.
|
||||
;;;;
|
||||
;;;; Copyright (C) 2017 Simon Brooke
|
||||
;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;
|
||||
;;;; Right, doing the data visualisation thing is tricky. Doing it in the
|
||||
;;;; pipeline doesn't work, because the md-to-html-string filter messes up
|
||||
;;;; both YAML and JSON notation. So we need to extract the visualisation YAML
|
||||
;;;; fragments from the Markdown text and replace them with tokens we will
|
||||
;;;; recognise afterwards, perform md-to-html-string, and then replace our
|
||||
;;;; tokens with the transformed visualisation specification.
|
||||
;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Error to show if text to be rendered is nil.
|
||||
(def no-text-error "No text: does the file exist?")
|
||||
|
||||
|
||||
(defn local-links
|
||||
"Rewrite text in `html-src` surrounded by double square brackets as a local link into this wiki."
|
||||
[^String html-src]
|
||||
(if html-src
|
||||
(cs/replace html-src #"\[\[[^\[\]]*\]\]"
|
||||
#(let [text (clojure.string/replace %1 #"[\[\]]" "")
|
||||
encoded (url-encode text)
|
||||
;; I use '\_' to represent '_' in wiki markup, because
|
||||
;; '_' is meaningful in Markdown. However, this needs to
|
||||
;; be stripped out when interpreting local links.
|
||||
munged (cs/replace encoded #"%26%2395%3B" "_")]
|
||||
(format "<a href='wiki?page=%s'>%s</a>" munged text)))
|
||||
no-text-error))
|
||||
|
||||
|
||||
(defn yaml->vis
|
||||
"Transcode this YAML fragment into the source for a Vega visualisation with this index."
|
||||
[^String yaml-src ^Integer index]
|
||||
(str
|
||||
"<div class='data-visualisation' id='vis" index "'></div>\n"
|
||||
"<script>\n//<![CDATA[\nvar vl"
|
||||
index
|
||||
" = "
|
||||
(json/write-str
|
||||
(assoc (yaml/parse-string yaml-src) (keyword "$schema") "https://vega.github.io/schema/vega-lite/v2.json"))
|
||||
";\nvega.embed('#vis" index "', vl" index ");\n//]]\n</script>"))
|
||||
|
||||
|
||||
(defn process-text
|
||||
"Process this `text`, assumed to be markdown potentially containing both local links
|
||||
and YAML visualisation specifications, and return a map comprising JSON visualisation
|
||||
specification, and HTML text with markers for where those should be reinserted.
|
||||
|
||||
The map has two top-level keys: `:visualisations`, a map of constructed keywords to
|
||||
visualisation specifications, and `:text`, an HTML text string with the keywords
|
||||
present where the corresponding visualisation should be inserted."
|
||||
([text]
|
||||
(process-text 0 {:visualisations {}} (cs/split text #"```") '()))
|
||||
([index result fragments processed]
|
||||
(cond
|
||||
(empty? fragments)
|
||||
(assoc result :text (local-links (md/md-to-html-string (cs/join "\n\n" (reverse processed)))))
|
||||
(clojure.string/starts-with? (first fragments) "vis")
|
||||
(let [kw (keyword (str "visualisation-" index))]
|
||||
(process-text
|
||||
(+ index 1)
|
||||
(assoc
|
||||
result
|
||||
:visualisations
|
||||
(assoc
|
||||
(:visualisations result)
|
||||
kw
|
||||
(yaml->vis
|
||||
(subs (first fragments) 3)
|
||||
index)))
|
||||
(rest fragments)
|
||||
(cons kw processed)))
|
||||
true
|
||||
(process-text (+ index 1) result (rest fragments) (cons (first fragments) processed)))))
|
||||
|
||||
|
||||
(defn reintegrate-visualisations
|
||||
"Given a map of the form produced by `process-text`, return a string of HTML text
|
||||
with the visualisations (if any) reintegrated."
|
||||
([processed-text]
|
||||
(reintegrate-visualisations (:visualisations processed-text) (:text processed-text)))
|
||||
([visualisations text]
|
||||
(let [ks (keys visualisations)]
|
||||
(if (empty? (keys visualisations))
|
||||
text
|
||||
(let [kw (first ks)]
|
||||
(reintegrate-visualisations
|
||||
(dissoc visualisations kw)
|
||||
(cs/replace
|
||||
text
|
||||
(str kw)
|
||||
(cs/replace (kw visualisations) "\\/" "/"))))))))
|
||||
|
||||
|
||||
(defn md->html
|
||||
"Take this markdown source, and return HTML."
|
||||
[md-src]
|
||||
(reintegrate-visualisations (process-text md-src)))
|
||||
|
||||
|
||||
|
|
@ -14,6 +14,7 @@
|
|||
[taoensso.timbre :as timbre]
|
||||
[smeagol.authenticate :as auth]
|
||||
[smeagol.diff2html :as d2h]
|
||||
[smeagol.formatting :refer [md->html]]
|
||||
[smeagol.layout :as layout]
|
||||
[smeagol.util :as util]
|
||||
[smeagol.history :as hist]
|
||||
|
|
@ -98,7 +99,7 @@
|
|||
(merge (util/standard-params request)
|
||||
{:title (str (:edit-title-prefix layout/config) " " page)
|
||||
:page page
|
||||
:side-bar (util/local-links (util/md->html side-bar))
|
||||
:side-bar (md->html (io/slurp-resource side-bar))
|
||||
:content (if exists? (io/slurp-resource (str "/content/" page suffix)) "")
|
||||
:exists exists?}))))))
|
||||
|
||||
|
|
@ -124,8 +125,7 @@
|
|||
(merge (util/standard-params request)
|
||||
{:title page
|
||||
:page page
|
||||
:side-bar (util/local-links (util/md->html "/content/_side-bar.md"))
|
||||
:content (util/local-links (util/md->html file-name))
|
||||
:content (md->html (io/slurp-resource file-name))
|
||||
:editable true})))
|
||||
true (response/redirect (str "/edit?page=" page)))))
|
||||
|
||||
|
|
@ -138,11 +138,12 @@
|
|||
page (url-decode (or (:page params) (:default-page-title layout/config)))
|
||||
file-name (str page ".md")
|
||||
repo-path (str (io/resource-path) "/content/")]
|
||||
(timbre/info (format "Showing history of page '%s'" page))
|
||||
(layout/render "history.html"
|
||||
(merge (util/standard-params request)
|
||||
{:title (str "History of " page)
|
||||
:page page
|
||||
:history (hist/find-history repo-path file-name)}))))
|
||||
:history (md->html (hist/find-history repo-path file-name))}))))
|
||||
|
||||
|
||||
(defn version-page
|
||||
|
|
@ -152,15 +153,14 @@
|
|||
page (url-decode (or (:page params) (:default-page-title layout/config)))
|
||||
version (:version params)
|
||||
file-name (str page ".md")
|
||||
repo-path (str (io/resource-path) "/content/")]
|
||||
repo-path (str (io/resource-path) "/content/")
|
||||
content (hist/fetch-version repo-path file-name version)]
|
||||
(timbre/info (format "Showing version '%s' of page '%s'" version page))
|
||||
(layout/render "wiki.html"
|
||||
(merge (util/standard-params request)
|
||||
{:title (str (:vers-col-hdr layout/config) " " version " of " page)
|
||||
:page page
|
||||
:content (util/local-links
|
||||
(md/md-to-html-string
|
||||
(hist/fetch-version
|
||||
repo-path file-name version)))}))))
|
||||
:content (md->html content)}))))
|
||||
|
||||
|
||||
(defn diff-page
|
||||
|
|
@ -171,6 +171,7 @@
|
|||
version (:version params)
|
||||
file-name (str page ".md")
|
||||
repo-path (str (io/resource-path) "/content/")]
|
||||
(timbre/info (format "Showing diff between version '%s' of page '%s' and current" version page))
|
||||
(layout/render "wiki.html"
|
||||
(merge (util/standard-params request)
|
||||
{:title (str (:diff-title-prefix layout/config)" " version " of " page)
|
||||
|
|
@ -201,10 +202,7 @@
|
|||
(layout/render "auth.html"
|
||||
(merge (util/standard-params request)
|
||||
{:title (if user (str (:logout-link layout/config) " " user) (:login-link layout/config))
|
||||
:redirect-to ((:headers request) "referer")
|
||||
:side-bar (util/local-links (util/md->html "/content/_side-bar.md"))
|
||||
:header (util/local-links (util/md->html "/content/_header.md"))
|
||||
:user user})))))
|
||||
:redirect-to ((:headers request) "referer")})))))
|
||||
|
||||
|
||||
(defn passwd-page
|
||||
|
|
@ -221,8 +219,6 @@
|
|||
(layout/render "passwd.html"
|
||||
(merge (util/standard-params request)
|
||||
{:title (str (:chpass-title-prefix layout/config) " " user)
|
||||
:side-bar (util/local-links (util/md->html "/content/_side-bar.md"))
|
||||
:header (util/local-links (util/md->html "/content/_header.md"))
|
||||
:message (if changed? (:chpass-success layout/config))
|
||||
:error (cond
|
||||
(nil? oldpass) nil
|
||||
|
|
|
|||
|
|
@ -1,12 +1,9 @@
|
|||
(ns ^{:doc "Miscellaneous utility functions supporting Smeagol."
|
||||
:author "Simon Brooke"}
|
||||
smeagol.util
|
||||
(:require [clojure.string :as cs]
|
||||
[cemerick.url :refer (url url-encode url-decode)]
|
||||
[noir.io :as io]
|
||||
[noir.session :as session]
|
||||
[markdown.core :as md]
|
||||
[smeagol.authenticate :as auth]))
|
||||
(:require [noir.session :as session]
|
||||
[smeagol.authenticate :as auth]
|
||||
[smeagol.formatting :refer [md->html]]))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;;
|
||||
|
|
@ -31,38 +28,13 @@
|
|||
;;;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defn md->html
|
||||
"reads a markdown file from public/md and returns an HTML string"
|
||||
[filename]
|
||||
(md/md-to-html-string (io/slurp-resource filename)))
|
||||
|
||||
|
||||
;; Error to show if text to be rendered is nil.
|
||||
(def no-text-error "No text: does the file exist?")
|
||||
|
||||
|
||||
(defn local-links
|
||||
"Rewrite text in `html-src` surrounded by double square brackets as a local link into this wiki."
|
||||
[^String html-src]
|
||||
(if html-src
|
||||
(cs/replace html-src #"\[\[[^\[\]]*\]\]"
|
||||
#(let [text (clojure.string/replace %1 #"[\[\]]" "")
|
||||
encoded (url-encode text)
|
||||
;; I use '\_' to represent '_' in wiki markup, because
|
||||
;; '_' is meaningful in Markdown. However, this needs to
|
||||
;; be stripped out when interpreting local links.
|
||||
munged (cs/replace encoded #"%26%2395%3B" "_")]
|
||||
(format "<a href='wiki?page=%s'>%s</a>" munged text)))
|
||||
no-text-error))
|
||||
|
||||
|
||||
(defn standard-params
|
||||
"Return a map of standard parameters to pass to the template renderer."
|
||||
[request]
|
||||
(let [user (session/get :user)]
|
||||
{:user user
|
||||
:admin (auth/get-admin user)
|
||||
:side-bar (local-links (md->html "/content/_side-bar.md"))
|
||||
:header (local-links (md->html "/content/_header.md"))
|
||||
:side-bar (md->html (io/slurp-resource "/content/_side-bar.md"))
|
||||
:header (md->html (io/slurp-resource "/content/_header.md"))
|
||||
:version (System/getProperty "smeagol.version")}))
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue