diff --git a/Procfile b/Procfile index ac9d762..91f7f3b 100644 --- a/Procfile +++ b/Procfile @@ -1 +1 @@ -web: python server.py +web: gunicorn -w 4 -b 0.0.0.0:$PORT -k gevent app:app diff --git a/server.py b/app.py similarity index 88% rename from server.py rename to app.py index 2a035d3..789a04b 100644 --- a/server.py +++ b/app.py @@ -4,7 +4,6 @@ from flask import Flask, Response, send_from_directory, request app = Flask(__name__) -app.debug = True cpl = Completer() @@ -32,6 +31,9 @@ def complete(): return Response(json.dumps(completions), mimetype='application/json') +@app.route('/debug') +def debug(): + return str(app.debug) + if __name__ == '__main__': - port = int(os.environ.get('PORT', 5000)) - app.run(host='0.0.0.0', port=port) + app.run(debug=True) diff --git a/completer.py b/completer.py index b6a40a8..5923618 100644 --- a/completer.py +++ b/completer.py @@ -91,12 +91,15 @@ def __init__(self): 'stranger': StrangerCompleter(), } self.stranger_completer = self.completers['stranger'] + self.default_completer = self.completers['stranger'] def complete(self, sources, context): completions = [] for source in sources: if source in self.completers: completions += self.completers[source].complete(context) + if len(completions) == 0: + completions += self.default_completer.complete(context) self.stranger_completer.update(context) random.shuffle(completions) return completions diff --git a/requirements.txt b/requirements.txt index c8d39f4..121449e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,6 +5,9 @@ Werkzeug==0.8.3 certifi==0.0.8 chardet==1.0.1 distribute==0.6.24 +gevent==0.13.6 +greenlet==0.3.4 +gunicorn==0.14.2 nltk==2.0.1rc4 requests==0.10.8 wsgiref==0.1.2 diff --git a/static/css/style.css b/static/css/style.css index 6a12ab9..ad5a18f 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -40,10 +40,18 @@ body { #sources { cursor: pointer; } +#sources li .plus { + color: transparent; +} #sources li.selected { font-weight: bold; color: #ccc; + text-shadow: 0 0 3px rgba(200,200,200,0.5); +} + +#sources li.selected .plus { + color: #ccc; } input[type=checkbox] { diff --git a/static/index.html b/static/index.html index 7f46333..6dd56b0 100644 --- a/static/index.html +++ b/static/index.html @@ -15,9 +15,9 @@
diff --git a/static/js/autocomplete.js b/static/js/autocomplete.js index 0962aa1..b49e386 100644 --- a/static/js/autocomplete.js +++ b/static/js/autocomplete.js @@ -1,6 +1,7 @@ /* globals */ var selected_sources = [] var currentReq; +var currentTimeout; var completions; var completionIndex; @@ -67,29 +68,36 @@ function setupEvents() { currentReq.abort(); currentReq = null; completions = null; + $('#spinner').hide(); + } + if (currentTimeout) { + clearTimeout(currentTimeout); + currentTimeout = null; } if (evt.which === 32) { if (evt.ctrlKey && completions) { showNextCompletion(); return; } - var ct = getCurrentTrigram(); - if (ct === '') { - return; - } - $('#spinner').show() - currentReq = $.get('/complete', - {'sources': getSourcesList(), 'context': ct}, - function(data) { - currentReq = null; - $('#spinner').hide() - if (data.length === 0) { + setTimeout(function() { + var ct = getCurrentTrigram(); + if (ct === '') { return; } - completions = data; - completionIndex = 0; - showNextCompletion(); - }); + $('#spinner').show() + currentReq = $.get('/complete', + {'sources': getSourcesList(), 'context': ct}, + function(data) { + currentReq = null; + $('#spinner').hide() + if (data.length === 0) { + return; + } + completions = data; + completionIndex = 0; + showNextCompletion(); + }); + }, 500); } }); $('#sources li').each(function() {