diff options
author | Jelmer Vernooij <jelmer@jelmer.uk> | 2016-10-01 02:22:24 +0000 |
---|---|---|
committer | Jelmer Vernooij <jelmer@jelmer.uk> | 2016-10-01 02:22:24 +0000 |
commit | c914b1d44430ff2ea7e0e8ee35688414ebb76979 (patch) | |
tree | 7d34f27bd107f6d359bc528039a91101a1fb86a9 | |
parent | 6bcd17a8f76c6d4ae0fe71f4db7e22092bc4bdc0 (diff) | |
parent | b825e27335b2872784b1ecb49d6f390640af092a (diff) |
Merge tag 'upstream/0.10.6' into unstable
Upstream version 0.10.6
-rw-r--r-- | .gitignore | 92 | ||||
-rw-r--r-- | CHANGES.rst | 35 | ||||
-rw-r--r-- | CONTRIBUTORS.txt | 7 | ||||
-rw-r--r-- | docs/docs/configuration/client.rst | 30 | ||||
-rw-r--r-- | docs/docs/configuration/server.rst | 7 | ||||
-rw-r--r-- | isso/__init__.py | 2 | ||||
-rw-r--r-- | isso/css/isso.css | 3 | ||||
-rw-r--r-- | isso/db/spam.py | 4 | ||||
-rw-r--r-- | isso/js/app/config.js | 4 | ||||
-rw-r--r-- | isso/js/app/dom.js | 7 | ||||
-rw-r--r-- | isso/js/app/globals.js | 4 | ||||
-rw-r--r-- | isso/js/app/i18n.js | 14 | ||||
-rw-r--r-- | isso/js/app/i18n/fi.js | 30 | ||||
-rw-r--r-- | isso/js/app/i18n/zh_CN.js | 8 | ||||
-rw-r--r-- | isso/js/app/i18n/zh_TW.js | 6 | ||||
-rw-r--r-- | isso/js/app/isso.js | 49 | ||||
-rw-r--r-- | isso/js/app/text/comment.jade | 2 | ||||
-rw-r--r-- | isso/tests/test_comments.py | 8 | ||||
-rw-r--r-- | isso/tests/test_guard.py | 23 | ||||
-rw-r--r-- | isso/views/comments.py | 26 | ||||
-rw-r--r-- | setup.py | 2 | ||||
-rw-r--r-- | share/isso.conf | 5 |
22 files changed, 322 insertions, 46 deletions
@@ -27,3 +27,95 @@ /docs/_static/css/site.css /pip-selfcheck.json + +# github/gitignore +Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover +.hypothesis/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# IPython Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# dotenv +.env + +# virtualenv +.venv/ +venv/ +ENV/ + +# Spyder project settings +.spyderproject + +# Rope project settings +.ropeproject diff --git a/CHANGES.rst b/CHANGES.rst index 732cc63..2bf9c81 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,11 +1,44 @@ Changelog for Isso ================== +0.10.6 (2016-09-22) +------------------- + +- fix missing configuration field + + +0.10.5 (2016-09-20) +------------------- + +- add support for different vote levels, #260 + + List of vote levels used to customize comment appearance based on score. + Provide a comma-separated values (eg. `"0,5,10,25,100"`) or a JSON array (eg. + `"[-5,5,15]"`). + + For example, the value `"-5,5"` will cause each `isso-comment` to be given + one of these 3 classes: + + - `isso-vote-level-0` for scores lower than `-5` + - `isso-vote-level-1` for scores between `-5` and `4` + - `isso-vote-level-2` for scores of `5` and greater + + These classes can then be used to customize the appearance of comments (eg. + put a star on popular comments). + +- add new post preview API endpoint, #254 + +- add an option for mandatory author, #257 + +- clients can now use `data-title` to get the HTML title for a new page, #252 + +- add finish translation and other minor bugfixes + + 0.10.4 (2016-04-12) ------------------- - fix wrapper attribute when using data-isso-require-mail="true", #238 - - fix reponse for OPTIONS response on Python 3, #242 diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index cffbfc2..0b5e649 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -51,5 +51,12 @@ In chronological order: * Added configuration to require email addresses (no validation) * Fix Vagrantfile +* Benoît Latinier <benoit@latinier.fr> + * Fix thread discovery + * Added mandatory author + +* Ivan Pantic <ivanpantic82@gmail.com> + * Added vote levels + * [Your name or handle] <[email or website]> * [Brief summary of your changes] diff --git a/docs/docs/configuration/client.rst b/docs/docs/configuration/client.rst index 3eece63..ea7487a 100644 --- a/docs/docs/configuration/client.rst +++ b/docs/docs/configuration/client.rst @@ -10,6 +10,7 @@ preferably in the script tag which embeds the JS: data-isso-css="true" data-isso-lang="ru" data-isso-reply-to-self="false" + data-isso-require-author="false" data-isso-require-email="false" data-isso-max-comments-top="10" data-isso-max-comments-nested="5" @@ -18,6 +19,7 @@ preferably in the script tag which embeds the JS: data-isso-avatar-bg="#f0f0f0" data-isso-avatar-fg="#9abf88 #5698c4 #e279a3 #9163b6 ..." data-isso-vote="true" + data-vote-levels="" src="/prefix/js/embed.js"></script> Furthermore you can override the automatic title detection inside @@ -63,6 +65,11 @@ data-isso-reply-to-self Set to `true` when spam guard is configured with `reply-to-self = true`. +data-isso-require-author +------------------------ + +Set to `true` when spam guard is configured with `require-author = true`. + data-isso-require-email ----------------------- @@ -104,14 +111,27 @@ data-isso-vote Enable or disable voting feature on the client side. +data-isso-vote-levels +--------------------- + +List of vote levels used to customize comment appearance based on score. +Provide a comma-separated values (eg. `"0,5,10,25,100"`) or a JSON array (eg. `"[-5,5,15]"`). + +For example, the value `"-5,5"` will cause each `isso-comment` to be given one of these 3 classes: + +- `isso-vote-level-0` for scores lower than `-5` +- `isso-vote-level-1` for scores between `-5` and `4` +- `isso-vote-level-2` for scores of `5` and greater + +These classes can then be used to customize the appearance of comments (eg. put a star on popular comments) + data-isso-id ------------ -Broken – do not use. https://github.com/posativ/isso/issues/27 - -Set a custom thread id, defaults to current URI. If you use a comment counter, -add this attribute to the link tag, too. +Set a custom thread id, defaults to current URI. This attribute needs +to be used with the data-title attribute in order to work. +If you use a comment counter, add this attribute to the link tag, too. .. code-block:: html - <section data-isso-id="test.abc" id="isso-thread"></section> + <section data-title="Yay!" data-isso-id="test.abc" id="isso-thread"></section> diff --git a/docs/docs/configuration/server.rst b/docs/docs/configuration/server.rst index 86d1b7f..cb39ccd 100644 --- a/docs/docs/configuration/server.rst +++ b/docs/docs/configuration/server.rst @@ -217,6 +217,7 @@ for IPv4, ``/48`` for IPv6). ratelimit = 2 direct-reply = 3 reply-to-self = false + require-author = false require-email = false enabled @@ -237,6 +238,12 @@ reply-to-self Do not forget to configure the client. +require-author + force commenters to enter a value into the author field. No validation is + performed on the provided value. + + Do not forget to configure the client accordingly. + require-email force commenters to enter a value into the email field. No validation is performed on the provided value. diff --git a/isso/__init__.py b/isso/__init__.py index ff8f6b4..7795c4f 100644 --- a/isso/__init__.py +++ b/isso/__init__.py @@ -194,7 +194,7 @@ def make_app(conf=None, threading=True, multiprocessing=False, uwsgi=False): allowed=("Origin", "Referer", "Content-Type"), exposed=("X-Set-Cookie", "Date"))) - wrapper.extend([wsgi.SubURI, ProxyFix, wsgi.LegacyWerkzeugMiddleware]) + wrapper.extend([wsgi.SubURI, ProxyFix]) if werkzeug.version.startswith("0.8"): wrapper.append(wsgi.LegacyWerkzeugMiddleware) diff --git a/isso/css/isso.css b/isso/css/isso.css index b0ed6d1..2d587ff 100644 --- a/isso/css/isso.css +++ b/isso/css/isso.css @@ -145,6 +145,9 @@ .isso-comment .isso-postbox { margin-top: 0.8em; } +.isso-comment.isso-no-votes span.votes { + display: none; +} .isso-postbox { max-width: 68em; diff --git a/isso/db/spam.py b/isso/db/spam.py index 8a1c747..d198f6a 100644 --- a/isso/db/spam.py +++ b/isso/db/spam.py @@ -66,6 +66,10 @@ class Guard: if self.conf.getboolean("require-email") and not comment.get("email"): return False, "email address required but not provided" + # require author if :param:`require-author` is enabled + if self.conf.getboolean("require-author") and not comment.get("author"): + return False, "author address required but not provided" + return True, "" def _spam(self, uri, comment): diff --git a/isso/js/app/config.js b/isso/js/app/config.js index 35bf051..952d588 100644 --- a/isso/js/app/config.js +++ b/isso/js/app/config.js @@ -6,6 +6,7 @@ define(function() { "lang": (navigator.language || navigator.userLanguage).split("-")[0], "reply-to-self": false, "require-email": false, + "require-author": false, "max-comments-top": "inf", "max-comments-nested": 5, "reveal-on-click": 5, @@ -13,7 +14,8 @@ define(function() { "avatar-bg": "#f0f0f0", "avatar-fg": ["#9abf88", "#5698c4", "#e279a3", "#9163b6", "#be5168", "#f19670", "#e4bf80", "#447c69"].join(" "), - "vote": true + "vote": true, + "vote-levels": null }; var js = document.getElementsByTagName("script"); diff --git a/isso/js/app/dom.js b/isso/js/app/dom.js index 9a50609..ec76e13 100644 --- a/isso/js/app/dom.js +++ b/isso/js/app/dom.js @@ -205,10 +205,13 @@ define(function() { el.href = "#"; } + if (!content && content !== 0) { + content = ""; + } if (["TEXTAREA", "INPUT"].indexOf(el.nodeName) > -1) { - el.value = content || ""; + el.value = content; } else { - el.textContent = content || ""; + el.textContent = content; } return el; }; diff --git a/isso/js/app/globals.js b/isso/js/app/globals.js index 6c411f1..680a96c 100644 --- a/isso/js/app/globals.js +++ b/isso/js/app/globals.js @@ -10,7 +10,7 @@ define(function() { }; Offset.prototype.localTime = function() { - return new Date((new Date()).getTime() + this.values.reduce( + return new Date((new Date()).getTime() - this.values.reduce( function(a, b) { return a + b; }) / this.values.length); }; @@ -18,4 +18,4 @@ define(function() { offset: new Offset() }; -});
\ No newline at end of file +}); diff --git a/isso/js/app/i18n.js b/isso/js/app/i18n.js index 2c1c756..2765915 100644 --- a/isso/js/app/i18n.js +++ b/isso/js/app/i18n.js @@ -1,19 +1,22 @@ -define(["app/config", "app/i18n/cs", "app/i18n/de", "app/i18n/en", - "app/i18n/fr", "app/i18n/hr", "app/i18n/ru", "app/i18n/it", - "app/i18n/eo", "app/i18n/sv", "app/i18n/nl", "app/i18n/el_GR", - "app/i18n/es", "app/i18n/vi", "app/i18n/zh_CN"], - function(config, cs, de, en, fr, hr, ru, it, eo, sv, nl, el, es, vi, zh) { +define(["app/config", "app/i18n/bg", "app/i18n/cs", "app/i18n/de", + "app/i18n/en", "app/i18n/fi", "app/i18n/fr", "app/i18n/hr", + "app/i18n/ru", "app/i18n/it", "app/i18n/eo", "app/i18n/sv", + "app/i18n/nl", "app/i18n/el_GR", "app/i18n/es", "app/i18n/vi", + "app/i18n/zh_CN"], + function(config, bg, cs, de, en, fi, fr, hr, ru, it, eo, sv, nl, el, es, vi, zh) { "use strict"; var pluralforms = function(lang) { switch (lang) { + case "bg": case "cs": case "de": case "el": case "en": case "es": case "eo": + case "fi": case "hr": case "it": case "sv": @@ -57,6 +60,7 @@ define(["app/config", "app/i18n/cs", "app/i18n/de", "app/i18n/en", en: en, eo: eo, es: es, + fi: fi, fr: fr, it: it, hr: hr, diff --git a/isso/js/app/i18n/fi.js b/isso/js/app/i18n/fi.js new file mode 100644 index 0000000..80b6316 --- /dev/null +++ b/isso/js/app/i18n/fi.js @@ -0,0 +1,30 @@ +define({ + "postbox-text": "Kirjoita kommentti tähän (vähintään 3 merkkiä)", + "postbox-author": "Nimi (valinnainen)", + "postbox-email": "Sähköposti (valinnainen)", + "postbox-website": "Web-sivu (valinnainen)", + "postbox-submit": "Lähetä", + + "num-comments": "Yksi kommentti\n{{ n }} kommenttia", + "no-comments": "Ei vielä kommentteja", + + "comment-reply": "Vastaa", + "comment-edit": "Muokkaa", + "comment-save": "Tallenna", + "comment-delete": "Poista", + "comment-confirm": "Vahvista", + "comment-close": "Sulje", + "comment-cancel": "Peru", + "comment-deleted": "Kommentti on poistettu.", + "comment-queued": "Kommentti on laitettu jonoon odottamaan moderointia.", + "comment-anonymous": "Nimetön", + "comment-hidden": "{{ n }} piilotettua", + + "date-now": "hetki sitten", + "date-minute": "minuutti sitten\n{{ n }} minuuttia sitten", + "date-hour": "tunti sitten\n{{ n }} tuntia sitten", + "date-day": "eilen\n{{ n }} päivää sitten", + "date-week": "viime viikolla\n{{ n }} viikkoa sitten", + "date-month": "viime kuussa\n{{ n }} kuukautta sitten", + "date-year": "viime vuonna\n{{ n }} vuotta sitten" +}); diff --git a/isso/js/app/i18n/zh_CN.js b/isso/js/app/i18n/zh_CN.js index 70ae081..b9d4582 100644 --- a/isso/js/app/i18n/zh_CN.js +++ b/isso/js/app/i18n/zh_CN.js @@ -1,8 +1,8 @@ define({ - "postbox-text": "在此输入评论(最少3个字符)", - "postbox-author": "名字(可选)", - "postbox-email": "E-mail(可选)", - "postbox-website": "网站(可选)", + "postbox-text": "在此输入评论 (最少3个字符)", + "postbox-author": "名字 (可选)", + "postbox-email": "E-mail (可选)", + "postbox-website": "网站 (可选)", "postbox-submit": "提交", "num-comments": "1条评论\n{{ n }}条评论", diff --git a/isso/js/app/i18n/zh_TW.js b/isso/js/app/i18n/zh_TW.js index 20191da..9bb59fa 100644 --- a/isso/js/app/i18n/zh_TW.js +++ b/isso/js/app/i18n/zh_TW.js @@ -1,8 +1,8 @@ define({
"postbox-text": "在此輸入留言(至少3個字元)",
- "postbox-author": "名稱(非必填)",
- "postbox-email": "電子信箱(非必填)",
- "postbox-website": "個人網站(非必填)",
+ "postbox-author": "名稱 (非必填)",
+ "postbox-email": "電子信箱 (非必填)",
+ "postbox-website": "個人網站 (非必填)",
"postbox-submit": "送出",
"num-comments": "1則留言\n{{ n }}則留言",
diff --git a/isso/js/app/isso.js b/isso/js/app/isso.js index a46f43a..0523e9b 100644 --- a/isso/js/app/isso.js +++ b/isso/js/app/isso.js @@ -30,6 +30,12 @@ define(["app/dom", "app/utils", "app/config", "app/api", "app/jade", "app/i18n", $("[name='email']", this).focus(); return false; } + if (config["require-author"] && + $("[name='author']", this).value.length <= 0) + { + $("[name='author']", this).focus(); + return false; + } return true; }; @@ -39,6 +45,12 @@ define(["app/dom", "app/utils", "app/config", "app/api", "app/jade", "app/i18n", $("[name='email']", el).placeholder.replace(/ \(.*\)/, ""); } + // author is not optional if this config parameter is set + if (config["require-author"]) { + $("[name='author']", el).placeholder = + $("[name='author']", el).placeholder.replace(/ \(.*\)/, ""); + } + // submit form, initialize optional fields with `null` and reset form. // If replied to a comment, remove form completely. $("[type=submit]", el).on("click", function() { @@ -57,7 +69,8 @@ define(["app/dom", "app/utils", "app/config", "app/api", "app/jade", "app/i18n", api.create($("#isso-thread").getAttribute("data-isso-id"), { author: author, email: email, website: website, text: utils.text($(".textarea", el).innerHTML), - parent: parent || null + parent: parent || null, + title: $("#isso-thread").getAttribute("data-title") || null }).then(function(comment) { $(".textarea", el).innerHTML = ""; $(".textarea", el).blur(); @@ -165,18 +178,34 @@ define(["app/dom", "app/utils", "app/config", "app/api", "app/jade", "app/i18n", ); if (config.vote) { - // update vote counter, but hide if votes sum to 0 + var voteLevels = config['vote-levels']; + if (typeof voteLevels === 'string') { + // Eg. -5,5,15 + voteLevels = voteLevels.split(','); + } + + // update vote counter var votes = function (value) { var span = $("span.votes", footer); if (span === null) { - if (value !== 0) { - footer.prepend($.new("span.votes", value)); - } + footer.prepend($.new("span.votes", value)); } else { - if (value === 0) { - span.remove(); - } else { - span.textContent = value; + span.textContent = value; + } + if (value) { + el.classList.remove('isso-no-votes'); + } else { + el.classList.add('isso-no-votes'); + } + if (voteLevels) { + var before = true; + for (var index = 0; index <= voteLevels.length; index++) { + if (before && (index >= voteLevels.length || value < voteLevels[index])) { + el.classList.add('isso-vote-level-' + index); + before = false; + } else { + el.classList.remove('isso-vote-level-' + index); + } } } }; @@ -192,6 +221,8 @@ define(["app/dom", "app/utils", "app/config", "app/api", "app/jade", "app/i18n", votes(rv.likes - rv.dislikes); }); }); + + votes(comment.likes - comment.dislikes); } $("a.edit", footer).toggle("click", diff --git a/isso/js/app/text/comment.jade b/isso/js/app/text/comment.jade index 95dc7b1..4884bf7 100644 --- a/isso/js/app/text/comment.jade +++ b/isso/js/app/text/comment.jade @@ -24,8 +24,6 @@ div(class='isso-comment' id='isso-#{comment.id}') div(class='isso-comment-footer') if conf.vote - if comment.likes - comment.dislikes != 0 - span(class='votes') #{comment.likes - comment.dislikes} a(class='upvote' href='#') != svg['arrow-up'] span(class='spacer') | diff --git a/isso/tests/test_comments.py b/isso/tests/test_comments.py index 70bd3a3..1e2bdf1 100644 --- a/isso/tests/test_comments.py +++ b/isso/tests/test_comments.py @@ -375,6 +375,14 @@ class TestComments(unittest.TestCase): # just for the record self.assertEqual(self.post('/id/1/dislike', content_type=js).status_code, 200) + def testPreview(self): + response = self.post('/preview', data=json.dumps({'text': 'This is **mark***down*'})) + self.assertEqual(response.status_code, 200) + + rv = loads(response.data) + self.assertEqual(rv["text"], '<p>This is <strong>mark</strong><em>down</em></p>') + + class TestModeratedComments(unittest.TestCase): diff --git a/isso/tests/test_guard.py b/isso/tests/test_guard.py index 8a050d9..fca932c 100644 --- a/isso/tests/test_guard.py +++ b/isso/tests/test_guard.py @@ -35,7 +35,8 @@ class TestGuard(unittest.TestCase): def setUp(self): self.path = tempfile.NamedTemporaryFile().name - def makeClient(self, ip, ratelimit=2, direct_reply=3, self_reply=False, require_email=False): + def makeClient(self, ip, ratelimit=2, direct_reply=3, self_reply=False, + require_email=False, require_author=False): conf = config.load(os.path.join(dist.location, "share", "isso.conf")) conf.set("general", "dbpath", self.path) @@ -45,6 +46,7 @@ class TestGuard(unittest.TestCase): conf.set("guard", "direct-reply", str(direct_reply)) conf.set("guard", "reply-to-self", "1" if self_reply else "0") conf.set("guard", "require-email", "1" if require_email else "0") + conf.set("guard", "require-author", "1" if require_author else "0") class App(Isso, core.Mixin): pass @@ -120,8 +122,8 @@ class TestGuard(unittest.TestCase): payload = lambda email: json.dumps({"text": "...", "email": email}) - client = self.makeClient("127.0.0.1", ratelimit=4, require_email=False) - client_strict = self.makeClient("127.0.0.2", ratelimit=4, require_email=True) + client = self.makeClient("127.0.0.1", ratelimit=4, require_email=False) + client_strict = self.makeClient("127.0.0.2", ratelimit=4, require_email=True) # if we don't require email self.assertEqual(client.post("/new?uri=test", data=payload("")).status_code, 201) @@ -130,3 +132,18 @@ class TestGuard(unittest.TestCase): # if we do require email self.assertEqual(client_strict.post("/new?uri=test", data=payload("")).status_code, 403) self.assertEqual(client_strict.post("/new?uri=test", data=payload("test@me.more")).status_code, 201) + + def testRequireAuthor(self): + + payload = lambda author: json.dumps({"text": "...", "author": author}) + + client = self.makeClient("127.0.0.1", ratelimit=4, require_author=False) + client_strict = self.makeClient("127.0.0.2", ratelimit=4, require_author=True) + + # if we don't require author + self.assertEqual(client.post("/new?uri=test", data=payload("")).status_code, 201) + self.assertEqual(client.post("/new?uri=test", data=payload("pipo author")).status_code, 201) + + # if we do require author + self.assertEqual(client_strict.post("/new?uri=test", data=payload("")).status_code, 403) + self.assertEqual(client_strict.post("/new?uri=test", data=payload("pipo author")).status_code, 201) diff --git a/isso/views/comments.py b/isso/views/comments.py index 0272fa3..d328305 100644 --- a/isso/views/comments.py +++ b/isso/views/comments.py @@ -75,7 +75,7 @@ class API(object): 'mode', 'created', 'modified', 'likes', 'dislikes', 'hash']) # comment fields, that can be submitted - ACCEPT = set(['text', 'author', 'website', 'email', 'parent']) + ACCEPT = set(['text', 'author', 'website', 'email', 'parent', 'title']) VIEWS = [ ('fetch', ('GET', '/')), @@ -89,7 +89,8 @@ class API(object): ('moderate',('POST', '/id/<int:id>/<any(activate,delete):action>/<string:key>')), ('like', ('POST', '/id/<int:id>/like')), ('dislike', ('POST', '/id/<int:id>/dislike')), - ('demo', ('GET', '/demo')) + ('demo', ('GET', '/demo')), + ('preview', ('POST', '/preview')) ] def __init__(self, isso, hasher): @@ -168,11 +169,14 @@ class API(object): with self.isso.lock: if uri not in self.threads: - with http.curl('GET', local("origin"), uri) as resp: - if resp and resp.status == 200: - uri, title = parse.thread(resp.read(), id=uri) - else: - return NotFound('URI does not exist') + if 'title' not in data: + with http.curl('GET', local("origin"), uri) as resp: + if resp and resp.status == 200: + uri, title = parse.thread(resp.read(), id=uri) + else: + return NotFound('URI does not exist %s') + else: + title = data['title'] thread = self.threads.new(uri, title) self.signal("comments.new:new-thread", thread) @@ -476,5 +480,13 @@ class API(object): return JSON(self.comments.count(*data), 200) + def preview(self, environment, request): + data = request.get_json() + + if "text" not in data or data["text"] is None: + raise BadRequest("no text given") + + return JSON({'text': self.isso.render(data["text"])}, 200) + def demo(self, env, req): return redirect(get_current_url(env) + '/index.html') @@ -12,7 +12,7 @@ if (3, 0) <= sys.version_info < (3, 3): setup( name='isso', - version='0.10.4', + version='0.10.6', author='Martin Zimmermann', author_email='info@posativ.org', packages=find_packages(), diff --git a/share/isso.conf b/share/isso.conf index be17a50..e17de4f 100644 --- a/share/isso.conf +++ b/share/isso.conf @@ -130,6 +130,11 @@ direct-reply = 3 # their own comments anyways. Do not forget to configure the client. reply-to-self = false +# force commenters to enter a value into the author field. No validation is +# performed on the provided value. Do not forget to configure the client +# accordingly. +require-author = false + # require the commenter to enter an email address (note: no validation is # done on the provided address). Do not forget to configure the client. require-email = false |