@@ -3,3 +3,10 @@ This is a from-scratch rewrite of | |||||
[EarwigBot rewrite](https://github.com/earwig/earwigbot). | [EarwigBot rewrite](https://github.com/earwig/earwigbot). | ||||
Not much else to say at this stage. Move along, now. | Not much else to say at this stage. Move along, now. | ||||
Dependencies | |||||
============ | |||||
* [earwigbot](https://github.com/earwig/earwigbot) | |||||
* [mako](http://www.makotemplates.org/) | |||||
* [oursql](http://packages.python.org/oursql/) |
@@ -71,12 +71,12 @@ | |||||
</form> | </form> | ||||
% if query.project and query.lang and query.title and not page: | % if query.project and query.lang and query.title and not page: | ||||
<div class="divider"></div> | <div class="divider"></div> | ||||
<div id="cv-result-yes"> | |||||
<div class="red-box"> | |||||
<p>The given site (project=<b><tt>${query.project}</tt></b>, language=<b><tt>${query.lang}</tt></b>) doesn't seem to exist. It may also be closed or private. <a href="//${query.lang}.${query.project}.org/">Confirm its URL.</a></p> | <p>The given site (project=<b><tt>${query.project}</tt></b>, language=<b><tt>${query.lang}</tt></b>) doesn't seem to exist. It may also be closed or private. <a href="//${query.lang}.${query.project}.org/">Confirm its URL.</a></p> | ||||
</div> | </div> | ||||
% elif query.project and query.lang and query.title and page and not result: | % elif query.project and query.lang and query.title and page and not result: | ||||
<div class="divider"></div> | <div class="divider"></div> | ||||
<div id="cv-result-yes"> | |||||
<div class="red-box"> | |||||
<p>The given page doesn't seem to exist: <a href="${page.url}">${page.title | h}</a>.</p> | <p>The given page doesn't seem to exist: <a href="${page.url}">${page.title | h}</a>.</p> | ||||
</div> | </div> | ||||
% elif page: | % elif page: | ||||
@@ -1,6 +1,9 @@ | |||||
<%include file="/support/header.mako" args="environ=environ, title='Settings'"/>\ | <%include file="/support/header.mako" args="environ=environ, title='Settings'"/>\ | ||||
<%namespace module="toolserver.settings" import="main"/>\ | <%namespace module="toolserver.settings" import="main"/>\ | ||||
<% bot, cookies, langs, projects = main(environ, headers) %> | |||||
<% bot, cookies, status, langs, projects = main(environ, headers) %> | |||||
% if status: | |||||
<div class="green-box">${status}</div> | |||||
% endif | |||||
<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> | ||||
<form action="${environ['PATH_INFO']}" method="post"> | <form action="${environ['PATH_INFO']}" method="post"> | ||||
@@ -22,6 +22,7 @@ | |||||
% for filename in add_css: | % for filename in add_css: | ||||
<link rel="stylesheet" href="${root}/static/css/${filename}" type="text/css" /> | <link rel="stylesheet" href="${root}/static/css/${filename}" type="text/css" /> | ||||
% endfor | % endfor | ||||
<script src="${root}/static/js/cookies.js" type="text/javascript"></script> | |||||
<script src="${root}/static/js/potd.js" type="text/javascript"></script> | <script src="${root}/static/js/potd.js" type="text/javascript"></script> | ||||
% for filename in add_js: | % for filename in add_js: | ||||
<script src="${root}/static/js/${filename}" type="text/javascript"></script> | <script src="${root}/static/js/${filename}" type="text/javascript"></script> | ||||
@@ -42,4 +43,4 @@ | |||||
% endfor | % endfor | ||||
</p> | </p> | ||||
</div> | </div> | ||||
<div id="container"> | |||||
<div id="container"> |
@@ -77,6 +77,20 @@ div.divider { | |||||
margin-bottom: 15px; | margin-bottom: 15px; | ||||
} | } | ||||
div.green-box { | |||||
padding: 0 10px 0 10px; | |||||
margin: 0 5px 10px 5px; | |||||
background-color: #FEE; | |||||
border: 1px solid #F77; | |||||
} | |||||
div.red-box { | |||||
padding: 0 10px 0 10px; | |||||
margin: 0 5px 10px 5px; | |||||
background-color: #EFE; | |||||
border: 1px solid #7F7; | |||||
} | |||||
p.toolname { | p.toolname { | ||||
font-size: 18px; | font-size: 18px; | ||||
margin: 6px 0 6px 0; | margin: 6px 0 6px 0; | ||||
@@ -0,0 +1,37 @@ | |||||
// Partially based on http://www.quirksmode.org/js/cookies.html | |||||
function get_cookie(name) { | |||||
var nameEQ = name + "="; | |||||
var ca = document.cookie.split(";"); | |||||
for (var i = 0; i < ca.length; i++) { | |||||
var c = ca[i]; | |||||
while (c.charAt(0) == " ") { | |||||
c = c.substring(1, c.length); | |||||
} | |||||
if (c.indexOf(nameEQ) == 0) { | |||||
var value = window.atob(c.substring(nameEQ.length, c.length)); | |||||
if (value.indexOf("--ets1") == 0) { | |||||
return value.substring("--ets1".length, value.length); | |||||
} | |||||
} | |||||
} | |||||
return null; | |||||
} | |||||
function set_cookie(name, value, days) { | |||||
value = window.btoa("--ets1" + value); | |||||
var path = window.location.pathname.split("/", 2)[1]; | |||||
if (days) { | |||||
var date = new Date(); | |||||
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); | |||||
var expires = "; expires=" + date.toGMTString(); | |||||
} | |||||
else { | |||||
var expires = ""; | |||||
} | |||||
document.cookie = name + "=" + value + expires + "; path=/" + path; | |||||
} | |||||
function delete_cookie(name) { | |||||
set_cookie(name, "", -1); | |||||
} |
@@ -1,38 +1,3 @@ | |||||
// Thanks to http://www.quirksmode.org/js/cookies.html for the cookie code. | |||||
function get_cookie(name) { | |||||
var nameEQ = name + "="; | |||||
var ca = document.cookie.split(";"); | |||||
for (var i = 0; i < ca.length; i++) { | |||||
var c = ca[i]; | |||||
while (c.charAt(0) == " ") { | |||||
c = c.substring(1, c.length); | |||||
} | |||||
if (c.indexOf(nameEQ) == 0) { | |||||
return c.substring(nameEQ.length, c.length); | |||||
} | |||||
} | |||||
return null; | |||||
} | |||||
function set_cookie(name, value, days) { | |||||
value = window.btoa("--ets1" + value); | |||||
var path = window.location.pathname.split("/", 2)[1]; | |||||
if (days) { | |||||
var date = new Date(); | |||||
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); | |||||
var expires = "; expires=" + date.toGMTString(); | |||||
} | |||||
else { | |||||
var expires = ""; | |||||
} | |||||
document.cookie = name + "=" + value + expires + "; path=/" + path; | |||||
} | |||||
function delete_cookie(name) { | |||||
set_cookie(name, "", -1); | |||||
} | |||||
function copyvio_toggle_details(details) { | function copyvio_toggle_details(details) { | ||||
link = document.getElementById("cv-result-detail-link"); | link = document.getElementById("cv-result-detail-link"); | ||||
details = document.getElementById("cv-result-detail"); | details = document.getElementById("cv-result-detail"); | ||||
@@ -1,6 +1,6 @@ | |||||
function potd_set_background() { | function potd_set_background() { | ||||
var d = new Date(); | var d = new Date(); | ||||
var callback = "like_a_boss"; | |||||
var callback = "earwigpotd1"; | |||||
var date = (d.getUTCFullYear()) + "-" + zero_pad(d.getUTCMonth() + 1, 2) + "-" + zero_pad(d.getUTCDate(), 2); | var date = (d.getUTCFullYear()) + "-" + zero_pad(d.getUTCMonth() + 1, 2) + "-" + zero_pad(d.getUTCDate(), 2); | ||||
var base = "//commons.wikimedia.org/w/api.php?action=query&prop=revisions&rvprop=content&format=json&titles=Template:Potd/"; | var base = "//commons.wikimedia.org/w/api.php?action=query&prop=revisions&rvprop=content&format=json&titles=Template:Potd/"; | ||||
var url = base + date + "&callback=" + callback; | var url = base + date + "&callback=" + callback; | ||||
@@ -25,7 +25,7 @@ function parse_file_name(data) { | |||||
} | } | ||||
var filename = /\{\{Potd filename\|(1=)?(.*?)\|.*?\}\}/.exec(content)[2]; | var filename = /\{\{Potd filename\|(1=)?(.*?)\|.*?\}\}/.exec(content)[2]; | ||||
var callback = "like_a_faust"; | |||||
var callback = "earwigpotd2"; | |||||
var base = "//commons.wikimedia.org/w/api.php?action=query&prop=imageinfo&iiprop=url|size&format=json&titles=File:"; | var base = "//commons.wikimedia.org/w/api.php?action=query&prop=imageinfo&iiprop=url|size&format=json&titles=File:"; | ||||
var url = base + escape(filename) + "&callback=" + callback; | var url = base + escape(filename) + "&callback=" + callback; | ||||
@@ -55,7 +55,10 @@ function parse_file_url(data, filename) { | |||||
imgwidth = r["width"]; | imgwidth = r["width"]; | ||||
imgheight = r["height"]; | imgheight = r["height"]; | ||||
} | } | ||||
set_background(url, descurl, imgwidth, imgheight); | |||||
} | |||||
function set_background(url, descurl, imgwidth, imgheight) { | |||||
var s = get_window_size(); | var s = get_window_size(); | ||||
var winwidth = s[0]; | var winwidth = s[0]; | ||||
var winheight = s[1]; | var winheight = s[1]; | ||||
@@ -1,29 +1,51 @@ | |||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
from markupsafe import escape | |||||
from .cookies import parse_cookies, set_cookie, delete_cookie | from .cookies import parse_cookies, set_cookie, delete_cookie | ||||
from .misc import get_bot, Query | from .misc import get_bot, Query | ||||
from .sites import get_sites | from .sites import get_sites | ||||
def main(context, environ, headers): | def main(context, environ, headers): | ||||
cookies = parse_cookies(context, environ) | |||||
query = Query(environ, method="POST") | query = Query(environ, method="POST") | ||||
cookies = parse_cookies(context, environ) | |||||
if query.action == "set": | 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) | |||||
status = _do_set(query, cookies) | |||||
elif query.action == "delete": | elif query.action == "delete": | ||||
if query.cookie in cookies: | |||||
delete_cookie(headers, cookies, query.cookie.encode("utf8")) | |||||
elif query.all: | |||||
for cookie in cookies.values(): | |||||
delete_cookie(headers, cookies, cookie.key) | |||||
status = _do_delete(query, cookies) | |||||
else: | |||||
status = None | |||||
bot = get_bot() | bot = get_bot() | ||||
langs, projects = get_sites(bot) | langs, projects = get_sites(bot) | ||||
return bot, cookies, langs, projects | |||||
return bot, cookies, status, langs, projects | |||||
def _do_set(query, cookies): | |||||
changes = 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) | |||||
changes.add("site") | |||||
if query.project: | |||||
key = "EarwigDefaultProject" | |||||
if key not in cookies or cookies[key].value != query.project: | |||||
set_cookie(headers, cookies, key, query.project, 365) | |||||
changes.add("site") | |||||
if changes: | |||||
changes = ", ".format(changes) | |||||
return "Updated {0}.".format(changes) | |||||
return None | |||||
def _do_delete(query, cookies): | |||||
if query.cookie in cookies: | |||||
delete_cookie(headers, cookies, query.cookie.encode("utf8")) | |||||
template = "Deleted cookie <b><tt>{0}</tt></b>." | |||||
return template.format(escape(query.cookie)) | |||||
elif query.all: | |||||
number = len(cookies) | |||||
for cookie in cookies.values(): | |||||
delete_cookie(headers, cookies, cookie.key) | |||||
return "Deleted <b>{0}</b> cookies.".format(number) | |||||
return None |