@@ -16,17 +16,19 @@ sys.path.insert(0, ".") | |||||
from mako.template import Template | from mako.template import Template | ||||
from mako.lookup import TemplateLookup | from mako.lookup import TemplateLookup | ||||
def myapp(environ, start_response): | |||||
start_response("200 OK", [("Content-Type", "text/html")]) | |||||
def main(environ, start_response): | |||||
lookup = TemplateLookup(directories=["{{pages_dir}}"], | lookup = TemplateLookup(directories=["{{pages_dir}}"], | ||||
input_encoding="utf8") | input_encoding="utf8") | ||||
template = Template(filename="{{src}}", module_directory="{{temp_dir}}", | template = Template(filename="{{src}}", module_directory="{{temp_dir}}", | ||||
lookup=lookup, format_exceptions=True) | lookup=lookup, format_exceptions=True) | ||||
return [template.render(environ=environ).encode("utf8")] | |||||
headers = [("Content-Type", "text/html")] | |||||
page = template.render(environ=environ, headers=headers).encode("utf8") | |||||
start_response("200 OK", headers) | |||||
return [page] | |||||
if __name__ == "__main__": | if __name__ == "__main__": | ||||
from flup.server.fcgi import WSGIServer | from flup.server.fcgi import WSGIServer | ||||
WSGIServer(myapp).run() | |||||
WSGIServer(main).run() | |||||
""" | """ | ||||
rewrite_script_src = """match URL into $ with ^/~earwig/{0}(\?.*?)?$ | rewrite_script_src = """match URL into $ with ^/~earwig/{0}(\?.*?)?$ | ||||
@@ -1,6 +1,7 @@ | |||||
<%include file="/support/header.mako" args="environ=environ, title='Copyvio Detector', add_css=('copyvios.css',), add_js=('copyvios.js',)"/>\ | <%include file="/support/header.mako" args="environ=environ, title='Copyvio Detector', add_css=('copyvios.css',), add_js=('copyvios.js',)"/>\ | ||||
<%namespace module="toolserver.copyvios" import="main, highlight_delta"/>\ | <%namespace module="toolserver.copyvios" import="main, highlight_delta"/>\ | ||||
<%namespace module="toolserver.misc" import="parse_cookies, urlstrip"/>\ | |||||
<%namespace module="toolserver.cookies" import="parse_cookies"/>\ | |||||
<%namespace module="toolserver.misc" import="urlstrip"/>\ | |||||
<% query, bot, all_langs, all_projects, page, result = main(environ) %> | <% query, bot, all_langs, all_projects, page, result = main(environ) %> | ||||
<% cookies = parse_cookies(environ) %> | <% cookies = parse_cookies(environ) %> | ||||
<h1>Copyvio Detector</h1> | <h1>Copyvio Detector</h1> | ||||
@@ -1,21 +1,20 @@ | |||||
<%include file="/support/header.mako" args="environ=environ, title='Settings'"/>\ | <%include file="/support/header.mako" args="environ=environ, title='Settings'"/>\ | ||||
<%namespace module="toolserver.misc" import="get_bot, parse_cookies"/>\ | |||||
<%namespace module="toolserver.sites" import="get_sites"/>\ | |||||
<% cookies = parse_cookies(environ) %> | |||||
<% langs, projects = get_sites(get_bot()) %> | |||||
<%namespace module="toolserver.settings" import="main"/>\ | |||||
<% bot, cookies, langs, projects = main(environ, headers) %> | |||||
<h1>Settings</h1> | <h1>Settings</h1> | ||||
<p>This page contains some configurable options for this Toolserver site. Settings are saved as cookies. You can view and delete all cookies generated by this site at the bottom of this page.</p> | <p>This page contains some configurable options for this Toolserver site. Settings are saved as cookies. You can view and delete all cookies generated by this site at the bottom of this page.</p> | ||||
<h2>Options</h2> | <h2>Options</h2> | ||||
<table> | |||||
<tr> | |||||
<form action="${environ['PATH_INFO']}" method="post"> | |||||
<input type="hidden" name="action" value="setDefaultSite"> | |||||
<form action="${environ['PATH_INFO']}" method="post"> | |||||
<input type="hidden" name="action" value="set"> | |||||
<table> | |||||
<tr> | |||||
<td>Default site:</td> | <td>Default site:</td> | ||||
<td> | <td> | ||||
<tt>http://</tt> | <tt>http://</tt> | ||||
<select name="lang"> | <select name="lang"> | ||||
<% selected_lang = cookies["EarwigDefaultLang"].value if "EarwigDefaultLang" in cookies else bot.wiki.get_site().lang %> | |||||
% for code, name in langs: | % for code, name in langs: | ||||
% if "EarwigDefaultLang" in cookies and code == cookies["EarwigDefaultLang"].value: | |||||
% if code == selected_lang: | |||||
<option value="${code}" selected="selected">${name}</option> | <option value="${code}" selected="selected">${name}</option> | ||||
% else: | % else: | ||||
<option value="${code}">${name}</option> | <option value="${code}">${name}</option> | ||||
@@ -24,8 +23,9 @@ | |||||
</select> | </select> | ||||
<tt>.</tt> | <tt>.</tt> | ||||
<select name="project"> | <select name="project"> | ||||
<% selected_project = cookies["EarwigDefaultProject"].value if "EarwigDefaultProject" in cookies else bot.wiki.get_site().lang %> | |||||
% for code, name in projects: | % for code, name in projects: | ||||
% if "EarwigDefaultProject" in cookies and code == cookies["EarwigDefaultProject"].value: | |||||
% if code == selected_project: | |||||
<option value="${code}" selected="selected">${name}</option> | <option value="${code}" selected="selected">${name}</option> | ||||
% else: | % else: | ||||
<option value="${code}">${name}</option> | <option value="${code}">${name}</option> | ||||
@@ -34,21 +34,23 @@ | |||||
</select> | </select> | ||||
<tt>.org</tt> | <tt>.org</tt> | ||||
</td> | </td> | ||||
</tr> | |||||
<tr> | |||||
<td>Background:</td> | |||||
</tr> | |||||
<tr> | |||||
<td><button type="submit">Save</button></td> | <td><button type="submit">Save</button></td> | ||||
</form> | |||||
</tr> | |||||
<tr> | |||||
<td>Background:</td> | |||||
</tr> | |||||
</table> | |||||
</tr> | |||||
</table> | |||||
</form> | |||||
<h2>Cookies</h2> | <h2>Cookies</h2> | ||||
% if cookies: | % if cookies: | ||||
<ul> | <ul> | ||||
% for cookie in cookies.itervalues(): | % for cookie in cookies.itervalues(): | ||||
<li> | <li> | ||||
<tt>${cookie.key | h}</tt>: <tt>${cookie.value | h}</tt> | |||||
<tt>${cookie.key | h}</tt>: <tt>${cookie.value | h}</tt> (<tt>${cookie.path | h}</tt>) | |||||
<form action="${environ['PATH_INFO']}" method="post"> | <form action="${environ['PATH_INFO']}" method="post"> | ||||
<input type="hidden" name="action" value="deleteCookie"> | |||||
<input type="hidden" name="action" value="delete"> | |||||
<input type="hidden" name="cookie" value="${cookie.key | h}"> | <input type="hidden" name="cookie" value="${cookie.key | h}"> | ||||
<button type="submit">Delete</button> | <button type="submit">Delete</button> | ||||
</form> | </form> | ||||
@@ -56,7 +58,7 @@ | |||||
% endfor | % endfor | ||||
</ul> | </ul> | ||||
<form action="${environ['PATH_INFO']}" method="post"> | <form action="${environ['PATH_INFO']}" method="post"> | ||||
<input type="hidden" name="action" value="deleteCookie"> | |||||
<input type="hidden" name="action" value="delete"> | |||||
<input type="hidden" name="all" value="1"> | <input type="hidden" name="all" value="1"> | ||||
<button type="submit">Delete all</button> | <button type="submit">Delete all</button> | ||||
</form> | </form> | ||||
@@ -16,6 +16,7 @@ function get_cookie(name) { | |||||
} | } | ||||
function set_cookie(name, value, days) { | function set_cookie(name, value, days) { | ||||
value = window.btoa(value); | |||||
var path = window.location.pathname.split("/", 2)[1]; | var path = window.location.pathname.split("/", 2)[1]; | ||||
if (days) { | if (days) { | ||||
var date = new Date(); | var date = new Date(); | ||||
@@ -39,7 +40,7 @@ function copyvio_toggle_details(details) { | |||||
if (link.innerHTML == "Show details:") { | if (link.innerHTML == "Show details:") { | ||||
details.style.display = "block"; | details.style.display = "block"; | ||||
link.innerHTML = "Hide details:"; | link.innerHTML = "Hide details:"; | ||||
set_cookie("EarwigCVShowDetails", "True", 180); | |||||
set_cookie("EarwigCVShowDetails", "True", 365); | |||||
} else { | } else { | ||||
details.style.display = "none"; | details.style.display = "none"; | ||||
link.innerHTML = "Show details:"; | link.innerHTML = "Show details:"; | ||||
@@ -0,0 +1,42 @@ | |||||
# -*- coding: utf-8 -*- | |||||
import base64 | |||||
from Cookie import BaseCookie | |||||
from datetime import datetime, timedelta | |||||
from os import path | |||||
class _CookieManager(BaseCookie): | |||||
def __init__(self, environ): | |||||
self._path = path.split(environ["PATH_INFO"])[0] | |||||
try: | |||||
self.load(environ["HTTP_COOKIE"]) | |||||
except AttributeError: | |||||
pass | |||||
def value_decode(self, value): | |||||
try: | |||||
return base64.b64decode(value).decode("utf8") | |||||
except (TypeError, UnicodeDecodeError): | |||||
return u"False" | |||||
def value_encode(self, value): | |||||
return base64.b64encode(value.encode("utf8")) | |||||
@property | |||||
def path(self): | |||||
return self._path | |||||
def parse_cookies(context, environ): | |||||
return _CookieManager(environ) | |||||
def set_cookie(headers, cookies, key, value, days=0): | |||||
cookies[key] = value | |||||
if days: | |||||
expires = datetime.utcnow() + timedelta(days=days) | |||||
cookies[key]["expires"] = expires.strftime("%a, %d %b %Y %H:%M:%S GMT") | |||||
cookies[key]["path"] = cookies.path | |||||
headers.append(("Set-Cookie", cookies[key].OutputString())) | |||||
def delete_cookie(headers, cookies, key): | |||||
set_cookie(headers, cookies, key, "", days=-1) |
@@ -14,8 +14,8 @@ def main(context, environ): | |||||
if query.project: | if query.project: | ||||
query.project = query.project.lower() | query.project = query.project.lower() | ||||
bot = get_bot(context) | |||||
all_langs, all_projects = get_sites(context, bot) | |||||
bot = get_bot() | |||||
all_langs, all_projects = get_sites(bot) | |||||
page = result = None | page = result = None | ||||
if query.lang and query.project and query.title: | if query.lang and query.project and query.title: | ||||
site = get_site(bot, query, all_projects) | site = get_site(bot, query, all_projects) | ||||
@@ -1,6 +1,5 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
from Cookie import CookieError, SimpleCookie | |||||
from os.path import expanduser | from os.path import expanduser | ||||
from urlparse import parse_qs | from urlparse import parse_qs | ||||
@@ -48,11 +47,5 @@ def urlstrip(context, url): | |||||
url = url[:-1] | url = url[:-1] | ||||
return url | return url | ||||
def get_bot(context): | |||||
return Bot(".earwigbot") | |||||
def parse_cookies(context, environ): | |||||
try: | |||||
return SimpleCookie(environ["HTTP_COOKIE"]) | |||||
except CookieError: | |||||
return SimpleCookie() | |||||
def get_bot(): | |||||
return Bot(".earwigbot", 100) # Don't print any logs to the console |
@@ -0,0 +1,30 @@ | |||||
# -*- coding: utf-8 -*- | |||||
from ..cookies import parse_cookies, set_cookie | |||||
from ..misc import get_bot, Query | |||||
from ..sites import get_sites | |||||
def main(context, environ, headers): | |||||
cookies = parse_cookies(context, environ) | |||||
query = Query(environ) | |||||
if query.action == "set": | |||||
if query.lang: | |||||
key = "EarwigDefaultLang" | |||||
if key not in cookies or cookies[key].value != query.lang: | |||||
set_cookie(headers, cookies, key, query.lang, 365) | |||||
if query.project: | |||||
key = "EarwigDefaultProject" | |||||
if key not in cookies or cookies[key].value != query.project: | |||||
set_cookie(headers, cookies, key, query.project, 365) | |||||
elif query.action == "delete": | |||||
if query.cookie in cookies: | |||||
delete_cookie(headers, cookies, query.cookie) | |||||
elif query.all: | |||||
for cookie in cookies.values: | |||||
if cookie.path.startswith(cookies.path): | |||||
delete_cookie(headers, cookies, cookie.key) | |||||
bot = get_bot() | |||||
langs, projects = get_sites(bot) | |||||
return bot, cookies, langs, projects |
@@ -27,7 +27,7 @@ def get_site(bot, query, all_projects): | |||||
except (exceptions.APIError, exceptions.LoginError): | except (exceptions.APIError, exceptions.LoginError): | ||||
return None | return None | ||||
def get_sites(context, bot): | |||||
def get_sites(bot): | |||||
max_staleness = 60 * 60 * 24 * 7 | max_staleness = 60 * 60 * 24 * 7 | ||||
conn = open_sql_connection(bot, "globals") | conn = open_sql_connection(bot, "globals") | ||||
query1 = "SELECT update_time FROM updates WHERE update_service = ?" | query1 = "SELECT update_time FROM updates WHERE update_service = ?" | ||||