summary |
shortlog | log |
commit |
commitdiff |
tree
first ⋅ prev ⋅ next
W. Trevor King [Sun, 21 Sep 2014 20:52:27 +0000 (13:52 -0700)]
nmhive.py: Use per-request database connections.
On #notmuch, Austin Clements just said:
Opening the database always gives you a consistent snapshot, so you
won't see changes unless you close and reopen it. However, opening
in read-only mode is quite cheap.
so I'm going to drop my global connection in favor of per-request
connections. This also allows me to cleanup after aborted atomic
transactions (when I implement the POST backend), because notmuch does
not currently expose Xapian::WritableDatabase::cancel_transaction. It
also allows other readers to see the new data, since notmuch only
commits changes when the database connection is closed. Finally,
David Bremner pointed out that holding the read/write lock for an
extended period of time is just bad form.
W. Trevor King [Sun, 21 Sep 2014 18:38:33 +0000 (11:38 -0700)]
nmhive.py: Use notmuch behind GET /tags
I stick with the NMBPREFIX environment variable for consistency with
nmbug itself. I also drop 'app.debug = True', to avoid trouble like:
$ ./nmhive.py
* Running on http://0.0.0.0:5000/
* Restarting with reloader
A Xapian exception occurred opening database: Unable to get write
lock on /.../xapian: already locked
Traceback (most recent call last):
File "./nmhive.py", line 83, in <module>
mode=notmuch.Database.MODE.READ_WRITE)
File "/.../notmuch/database.py", line 154, in __init__
self.open(path, mode)
File "/.../notmuch/database.py", line 214, in open
raise NotmuchError(status)
notmuch.errors.XapianError
because with 'debug = True', Flask tries to run two instances of this
process simultaneously, but only one can hold the write lock at a
time. If we want to scale this up to multiple writing
threads/processes, we'll probably want to make the persistant Database
instance read-only, and either acquire a write lock as necessary, or
just instantiate a read/write database for each PUT. For now, it's
easy enough to just have a single thread.
W. Trevor King [Sun, 21 Sep 2014 17:15:03 +0000 (10:15 -0700)]
COPYING: Add the 2-clause BSD license
From http://opensource.org/licenses/BSD-2-Clause
W. Trevor King [Sun, 21 Sep 2014 17:04:56 +0000 (10:04 -0700)]
bower.json: Mention bookmarklet and server in the description
Nmbug is already distributed. This project is just about providing an
interface for collaborators that don't have notmuch/nmbug locally.
W. Trevor King [Sun, 21 Sep 2014 13:41:39 +0000 (06:41 -0700)]
nmbug.js: Fill in the POST /mid/<message_id> handling
This is currently only (un)setting one tag per request. If we want, a
later optimization could queue changes and push them all at once (e.g.
after a user pushes a submit button). It would also be nice to update
the UI based on the list of returned tags, so we hear about changes
made by parallel parties.
W. Trevor King [Sun, 21 Sep 2014 13:30:45 +0000 (06:30 -0700)]
nmhive.py: Accept Content-Type headers via CORS
Using the suggested syntax [1] so I can POST from the bookmarklet.
[1]: https://pypi.python.org/pypi/Flask-Cors/1.9.0/#using-json-with-cors
W. Trevor King [Sun, 21 Sep 2014 13:06:18 +0000 (06:06 -0700)]
nmbug.js: Add tag-toggling with a stub _toggle_tag
This takes care of binding the new method and adjusting the CSS.
W. Trevor King [Sun, 21 Sep 2014 12:48:25 +0000 (05:48 -0700)]
nmbug.js: Add available-tags fetcher and highlight selected tags
Instead of just listing selected tags, list all available tags (using
nmhive.py's new GET /tags). Mark the selected tags with a background
color.
W. Trevor King [Sun, 21 Sep 2014 12:35:05 +0000 (05:35 -0700)]
nmbug.js: Use bind to avoid forwarding message_id through _get_tags
Instead of telling _get_tags that the callback will always want the
message_id (in addition to the list of that message's tags), use bind
[1] to add that information when we set the _edit_tags callback.
[1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
W. Trevor King [Sun, 21 Sep 2014 12:22:56 +0000 (05:22 -0700)]
nmhive.py: Add GET /tags
We don't want bookmarklet users adding random tags. Instead, restrict
them to tags that are already in the database, which allows us to keep
a consistent tag-set and present a simpler UI. The hard-coded
_AVAILABLE_TAGS will be replaced by a notmuch query once I finish with
the UI.
W. Trevor King [Sun, 21 Sep 2014 12:09:55 +0000 (05:09 -0700)]
nmbug.js: Style the dialog with some round corners and a shadow
The CSS is from Eiji Kitamura's demo [1]. I'm inlining the CSS here
to avoid more dynamic-loading shenanigans like we needed for the
dialog polyfill. I don't expect this CSS will grow much larger
anyway.
[1]: http://demo.agektmr.com/dialog/#styling
W. Trevor King [Sat, 20 Sep 2014 23:52:38 +0000 (16:52 -0700)]
nmbug.js: Add dialog-polyfill dependency for Firefox
It looks like Firefox doesn't support the <dialog> element yet [1,2],
so this commit dynamically loads the polyfill replacement [3]. Since
the polyfill files load asynchronously, I need to use onload to decide
when they've all made it down (setting the async property to false
didn't seem to work).
[1]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog
[2]: https://bugzilla.mozilla.org/show_bug.cgi?id=840640
[3]: https://github.com/GoogleChrome/dialog-polyfill
W. Trevor King [Sat, 20 Sep 2014 23:07:12 +0000 (16:07 -0700)]
bower.json: Add boilerplate so I can serve static dependencies
It looks like Firefox doesn't support the <dialog> element yet [1,2],
so I'll need the polyfill replacement. This commit puts the generic
boilerplate in place, so we can revert just the dialog polyfill later,
while leaving this boilerplate in place for other dependencies.
[1]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog
[2]: https://bugzilla.mozilla.org/show_bug.cgi?id=840640
W. Trevor King [Sat, 20 Sep 2014 22:32:38 +0000 (15:32 -0700)]
nmbug.js: Stub out a dialog for editing tags
It lists the associated Message-ID and tags, but I haven't added
JavaScript to support editing the tag list yet. I'm using the
<dialog> element [1] to float this dialog over the launching page
(e.g. Gmane), so we don't have to worry about mucking with whatever's
going on there ;).
[1]: https://html.spec.whatwg.org/multipage/forms.html#the-dialog-element
W. Trevor King [Sat, 20 Sep 2014 21:17:55 +0000 (14:17 -0700)]
nmbug.js: Fill in the tag-fetching portion of nmbug.show
Ask nmhive for the tags associated with the given Message-ID.
I've also used bind [1] so that the nmbug.show callback get's called
with this pointing to the nmbug object.
[1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
W. Trevor King [Sat, 20 Sep 2014 20:17:50 +0000 (13:17 -0700)]
nmhive.py: Add GET/POST /mid/<message_id>
So the bookmarklet can get and set tags on a given message. This
currently just uses an in-memory store, but eventually we'll drop
notmuch in on the backend.
W. Trevor King [Sat, 20 Sep 2014 19:35:23 +0000 (12:35 -0700)]
index.html: Avoid interpreting nmbug.js as text/xml
When loaded from file:///.../index.html, Firefox seems to assume
nmbug.js is text/xml. If you're serving nmbug.js from an actual
server, this shouldn't be a problem, but the explicit override makes
local testing easier.
W. Trevor King [Sat, 20 Sep 2014 18:46:55 +0000 (11:46 -0700)]
index.html: Supply nmbug.js as a bookmarklet
Distribute the bookmarklet as a link, so folks can just drag it up
onto their bookmark toolbar.
We're trying to avoid external dependencies, so I don't want to force
folks to load nmbug.js whenever they run the bookmarklet. Instead,
load_bookmarklet fetches nmbug.js, adds a bit of wrapping code to
create the bookmarklet, and injects that as the nmbug link's href.
W. Trevor King [Sat, 20 Sep 2014 20:00:23 +0000 (13:00 -0700)]
nmbug.js: Extract the Gmane article id and convert to a Message-ID
Using some JavaScript gymnastics to look through the available frames
for an article.gmane.org/ URL. For example, we might be on a page
like:
http://thread.gmane.org/gmane.mail.notmuch.general/19055/focus=19056
which is composed of the following frames [1]:
http://news.gmane.org/group/gmane.mail.notmuch.general/thread=19055/force_load=t/focus=19056
http://article.gmane.org/gmane.mail.notmuch.general/19056
http://news.gmane.org/navbar.php?group=gmane.mail.notmuch.general&article=19056&next=19057&prev=19054&newsrc=,19056
Or we might be on the article page directly. There are also permalink
pages (with 'permalink' instead of 'article' available from the
blog-link view), but I'm not worrying about them yet.
[1]: for (var i = 0; i < window.frames.length; i++) {
console.log(window.frames[i].document.URL);
}
W. Trevor King [Sat, 20 Sep 2014 19:51:37 +0000 (12:51 -0700)]
nmhive.py: Add GET /gmane/<group>/<int:article>
Gmane's download endpoint [1] doesn't allow cross-origin requests, and
article.gmane.org -> download.gmane.org is a cross-origin request [2].
Work around that with this proxy endpoint, which uses Flask-Cors [3]
to accept all origins. The bookmarklet can figure out the current
message's group and article id, and hit this endpoint. Then nmhive
will use Gmane's download endpoint to fetch the message as an mbox,
after which we can use Python's stdlib to extract the Message-ID from
the mbox, and return the extracted Message-ID to the bookmarklet.
Later on we can also add local caching and rate-limiting here, so we
don't bother Gmane more than necessary (the downloads are somewhat
expensive [1]).
[1]: http://gmane.org/export.php
[2]: https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy#Definition_of_an_origin
[3]: https://pypi.python.org/pypi/Flask-Cors/
W. Trevor King [Sat, 20 Sep 2014 18:46:37 +0000 (11:46 -0700)]
nmbug.js: Sketch out the bookmarklet framework
We'll have a generic nmbug.show() to handle the UI for tagging a given
message (using its Message-ID). To get that Message-ID, we'll have a
list of potential handlers. When the bookmarklet fires (run()), we'll
iterate through the handlers unril handler.regexp matches
document.URL. For the first match, we'll run handler.handle, which
will do whatever it needs to figure out the Message-ID, and then
launch nmbug.show (passed in via 'callback') with the extracted id.
W. Trevor King [Sat, 20 Sep 2014 18:42:49 +0000 (11:42 -0700)]
README.rst: Start outlining the project