From 27022af1e6d68788f6790a10cd45aac750202460 Mon Sep 17 00:00:00 2001 From: Martin Zimmermann Date: Thu, 12 Sep 2013 19:10:03 +0200 Subject: [PATCH] update README, added docs/API.md draft --- README.md | 154 ++++++++++++++++++++++------------ docs/API.md | 104 +++++++++++++++++++++++ isso/js/app/api.js | 4 +- isso/js/build.count.js | 2 +- isso/js/build.embed.js | 6 +- isso/js/{main.js => embed.js} | 0 6 files changed, 212 insertions(+), 58 deletions(-) create mode 100644 docs/API.md rename isso/js/{main.js => embed.js} (100%) diff --git a/README.md b/README.md index 586f35f..2068131 100644 --- a/README.md +++ b/README.md @@ -10,13 +10,15 @@ Isso comes into play. [1]: https://github.com/posativ/acrylamid [2]: https://disqus.com/ +**[Screenshot](http://posativ.org/~tmp/isso-preview.png)** + Features -------- * [CRUD](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete) comments -* SQLite -* quite nice, but unfinished client-side JS +* SQLite backend +* client-side JS (currently 12.5kb minified and gzipped) Roadmap @@ -24,75 +26,123 @@ Roadmap - Ping/TrackBack™ support - simple admin interface -- spam filtering using [http:bl][3] - -[3]: https://www.projecthoneypot.org/ +- spam filtering Installation ------------ -Probably `git clone https://github.com/posativ/isso.git`, `python setup.py develop` -inside a virtualenv. Then start `isso` with: +Requirements: + +- Python 2.6 or 2.7 +- [NPM](https://npmjs.org/) + +For now (as long as there is no stable version), you need to manually +build everything: + + ~> git clone https://github.com/posativ/isso.git + ~> cd isso/ + ~> python setup.py develop + +You can now either use the JS client as-is (using [require.js][r.js], see +below) or compile all JS into a single file: + + ~> cd isso/js + ~> npm install -g requirejs uglifyjs + ~> r.js -o build.embed.js + ~> r.js -o build.count.js + +Before you start, you may want to import comments from +[Disqus.com](https://disqus.com/): + + ~> isso import ~/Downloads/user-2013-09-02T11_39_22.971478-all.xml + [100%] 53 threads, 192 comments + +You start the server via (try to visit [http://localhost:8080/static/post.html]()). ~> isso run -You can now leave a comment at hopefully. -The admin interface password is `p@$$w0rd`, you may change this with a custom cfg -file that I'll document later. You find the admin interface at . -**[Screenshot](http://posativ.org/~tmp/isso-preview.png)** +Webserver Configuration +----------------------- + +This part is not fun, I know. I have prepared two possible setups for nginx, +using Isso on the same domain as the blog, and on a different domain. Each +setup has its own benefits. + +### Isso on a Sub URI + +Let's assume you want Isso on `/isso`, use the following nginx snippet + +```nginx +server { + + listen [::]:80; + listen [::]:443 ssl; + server_name example.tld; + root /var/www/example.tld; + + location /isso { + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Script-Name /isso; + proxy_pass http://localhost:8080; + } +} +``` + +The Isso API endpoint is now `example.tld/isso`, check by `curl`ing the client +JS located at `http://example.tld/isso/js/embed.js`. + +### Isso on a Dedicated Domain + +... -Migration from Disqus ---------------------- +Website Integration +------------------- -Go to [Disqus.com](https://disqus.com/) and export your "forum" as XML. +Add the following two lines into your HTML header: - ~> isso import /path/to/ur/dump.xml +```html + + +``` -That's it. Visit your admin page to see all threads. If it doesn't work for -you, please file in a bug report \*including\* your dump. +To enable comments, add a `
` below your post and +let the magic happen :-) + +To add comment count links to your index page, include `count.min.js` at the +very bottom of your document. All links followed by `#isso-thread`, are +updated with the current comment count. + +This functionality is already included when you embed `embed.min.js`, try +to *not* mix `embed.min.js` and `count.min.js` in a single document. + +### Embed with require.js + +This section is primarily for developers: The client-side JS is modularized +and uses an AMD loader for execution. You can easily hack on the JS files, +when using [require.js][r.js]: + +```html + + +``` -API (a draft) -------------- +API +--- -To fetch all comments for `http://example.tld/foo-bar/`, run +See [docs/API.md](https://github.com/posativ/isso/blob/master/docs/API.md). -:: - - $ curl http://example.tld/isso?uri=%2Ffoo-bar%2F - -To write a comment, you have to POST a JSON dictionary with the following -key-value pairs. Text is mandatory otherwise you'll get a 400 Bad Request. -You'll also get a 400 when your JSON is invalid. - -Let's say you want to comment on /foo-bar/ - - $ curl http://example.tld/isso/new?uri=%2Ffoo-bar%2F -X POST -d \ - '{ - "text": "Lorem ipsum ...", - "name": "Hans", "email": "foo@bla.org", "website": "http://blog/log/" - }' - -This will set a cookie, that expires in a few minutes (15 minutes per default). -This cookie allows you do modify or delete your comment. Don't try to modify -that cookie, it is cryptographically signed. If your cookie is outdated or -modified, you'll get a 403 Forbidden. - -For each comment you'll post, you get an unique cookie. Let's try to remove -your comment:: - - $ curl -X DELETE 'http://example.tld/isso?uri=%2Ffoo-bar%2F&id=1' - -If your comment has been referenced by another comment, your comment will be -cleared but not deleted to retain depending comments. Alternatives ------------ -- `talkatv `_ – Python -- `Juvia `_ – Ruby on Rails -- `Tildehash.com `_ – PHP -- `SO: Unobtrusive, self-hosted comments `_ +- [talkatv](https://github.com/talkatv/talkatv) – Python +- [Juvia](https://github.com/phusion/juvia – Ruby on Rails +- [Tildehash.com](http://www.tildehash.com/?article=why-im-reinventing-disqus) – PHP +- [SO: Unobtrusive, self-hosted comments](http://stackoverflow.com/q/2053217) + + +[r.js]: http://require.js/ diff --git a/docs/API.md b/docs/API.md new file mode 100644 index 0000000..29d3972 --- /dev/null +++ b/docs/API.md @@ -0,0 +1,104 @@ +Isso API +======== + +The Isso API uses HTTP and JSON as primary communication protocol. + + +## JSON format + +When querying the API you either get an error, an object or list of objects +representing the comment. Here's a example JSON returned from Isso: + +```json +{ + "text": "Hello, World!", + "author": "Bernd", + "website": null, + "votes": 0, + "mode": 1, + "id": 1, + "parent": null, + "hash": "68b329da9893e34099c7d8ad5cb9c940", + "created": 1379001637.50, + "modified": null +} +``` + +text +: required, comment as HTML + +author +: author's name, may be `null` + +website +: author's website, may be `null` + +votes +: sum of up- and downvotes, defaults to zero. + +mode +: * 1, accepted comment + * 2, comment in moderation queue + * 4, comment deleted, but is referenced + +id +: unique comment number per thread + +parent +: answer to a parent id, may be `null` + +hash +: user identification, used to generate identicons + +created +: time in seconds sinde epoch + +modified +: last modification time in seconds, may be `null` + + +## List comments + +List all visible comments for a thread. Does not include deleted and +comments currently in moderation queue. + + GET /?uri=path + +You must encode `path`, e.g. to retrieve comments for `/hello-world/`: + + GET /?uri=%2Fhello-world%2F + +You can also pass an `id` to fetch a specific comment: + + GET /?uri=%2Fhello-world%2F&id=1 + +To disable automatic Markdown-to-HTML conversion, pass `plain=1` to the +query URL: + + GET /?uri=...&plain=1 + +As response, you either get 200, 400, or 404, which are pretty self-explanatory. + + GET / + 400 BAD REQUEST + + GET /?uri=%2Fhello-world%2F + 404 NOT FOUND + + GET /?uri=%2Fcomment-me%2F + [{comment 1}, {comment 2}, ...] + + +## Create comments + +... + + +## Delete comments + +... + + +## Up- and downvote comments + +... diff --git a/isso/js/app/api.js b/isso/js/app/api.js index 514780f..2cf7f2e 100644 --- a/isso/js/app/api.js +++ b/isso/js/app/api.js @@ -18,8 +18,8 @@ define(["lib/q"], function(Q) { if (js[i].src.match("/js/require\\.js$")) { endpoint = js[i].src.substring(0, js[i].src.length - 14); break; - } else if (js[i].src.match("/js/embed\\.js$")) { - endpoint = js[i].src.substring(0, js[i].src.length - 12); + } else if (js[i].src.match("/js/embed\\.min\\.js$")) { + endpoint = js[i].src.substring(0, js[i].src.length - 16); break; } } diff --git a/isso/js/build.count.js b/isso/js/build.count.js index bf1d9b1..57be274 100644 --- a/isso/js/build.count.js +++ b/isso/js/build.count.js @@ -1,5 +1,5 @@ ({ - bseUrl: ".", + baseUrl: ".", name: "lib/almond", include: ['count'], out: "count.min.js", diff --git a/isso/js/build.embed.js b/isso/js/build.embed.js index 7ee13b7..1d16e1f 100644 --- a/isso/js/build.embed.js +++ b/isso/js/build.embed.js @@ -1,7 +1,7 @@ ({ - bseUrl: ".", + baseUrl: ".", name: "lib/almond", - include: ['main'], - out: "embed.js", + include: ['embed'], + out: "embed.min.js", wrap: true }) diff --git a/isso/js/main.js b/isso/js/embed.js similarity index 100% rename from isso/js/main.js rename to isso/js/embed.js