@@ -0,0 +1,11 @@ | |||||
*.pyc | |||||
*.egg | |||||
*.egg-info | |||||
.DS_Store | |||||
__pycache__ | |||||
.earwigbot | |||||
*.min.js | |||||
*.min.css | |||||
logs/* | |||||
!logs/.gitinclude |
@@ -1,28 +1,22 @@ | |||||
#! /usr/bin/env python | #! /usr/bin/env python | ||||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
from flask import Flask, g | |||||
from flask import Flask | |||||
from flask.ext.mako import MakoTemplates, render_template | from flask.ext.mako import MakoTemplates, render_template | ||||
from tif.calc import calculate_tif | |||||
from tif.util import catch_errors, set_up_hash_caching | from tif.util import catch_errors, set_up_hash_caching | ||||
app = Flask(__name__) | app = Flask(__name__) | ||||
MakoTemplates(app) | MakoTemplates(app) | ||||
set_up_hash_caching(app) | set_up_hash_caching(app) | ||||
@app.before_request | |||||
def prepare_request(): | |||||
g._db = None | |||||
@app.teardown_appcontext | |||||
def close_databases(error): | |||||
if g._db: | |||||
g._db.close() | |||||
@app.route("/") | @app.route("/") | ||||
@catch_errors(app) | @catch_errors(app) | ||||
def index(): | def index(): | ||||
return render_template("index.mako") | |||||
title = request.args.get("title") | |||||
result = calculate_tif(title) if title else None | |||||
return render_template("index.mako", result=result) | |||||
if __name__ == '__main__': | if __name__ == '__main__': | ||||
app.run() | app.run() |
@@ -0,0 +1,13 @@ | |||||
header {} | |||||
footer {} | |||||
#container {} | |||||
#error {} | |||||
#result {} | |||||
#result-page {} | |||||
#result-cache {} |
@@ -0,0 +1,7 @@ | |||||
<%include file="/support/header.mako" args="title='Error - TIF Calculator'"/> | |||||
<h2>Error!</h2> | |||||
<p>An error occurred. If it hasn't been reported (<a href="https://github.com/earwig/template-influence-factor/issues">try to check</a>), please <a href="https://github.com/earwig/template-influence-factor/issues/new">file an issue</a> or <a href="mailto:wikipedia.earwig@gmail.com">email me</a>. Include the following information:</p> | |||||
<div id="error"> | |||||
<pre>${traceback | trim,h}</pre> | |||||
</div> | |||||
<%include file="/support/footer.mako"/> |
@@ -0,0 +1,43 @@ | |||||
<%include file="/support/header.mako" args="title='TIF Calculator'"/> | |||||
<form action="${request.script_root}" method="get"> | |||||
% if result["title"]: | |||||
<input type="text" name="title" value="${query['page'].title if 'page' in query else query['title'] | h}" /> | |||||
% else: | |||||
<input type="text" name="title" /> | |||||
% endif | |||||
<button type="submit">Submit</button> | |||||
</form> | |||||
% if "error" in result: | |||||
<div id="error"> | |||||
% if result["error"] == "no page": | |||||
<p>Can't find the given page: <a href="${result['page'].url}">${result["page"].title | h}</a>.</p> | |||||
% else | |||||
An unknown error occurred. | |||||
% endif | |||||
</div> | |||||
% endif | |||||
% if "tif" in result: | |||||
<div id="result"> | |||||
<div id="result-page"><a href="${result['page'].url}">${result["page"].title | h}</a></div> | |||||
<table> | |||||
<tr> | |||||
<td>TIF</td> | |||||
<td>${result["tif"]}</td> | |||||
</tr> | |||||
<tr> | |||||
<td>Transclusions</td> | |||||
<td>${result["transclusions"]}</td> | |||||
</tr> | |||||
<tr> | |||||
<td>Protection</td> | |||||
<td>${result["protection"]}</td> | |||||
</tr> | |||||
</table> | |||||
% if "cache" in result and result["cache"]: | |||||
<div id="result-cache">Pageview data is cached from up to <abbr title="${result['cache_time']}">${result["cache_age"]} ago</abbr>.</div> | |||||
% endif | |||||
</div> | |||||
% endif | |||||
<%include file="/support/footer.mako"/> |
@@ -0,0 +1,10 @@ | |||||
<%! from datetime import datetime %>\ | |||||
<% this_year = datetime.now().year %>\ | |||||
</div> | |||||
<footer> | |||||
Copyright © 2016${"–" + str(this_year) if this_year > 2016 else ""} <a href="//en.wikipedia.org/wiki/User:The_Earwig">Ben Kurtovic</a> • \ | |||||
<a href="https://github.com/earwig/template-influence-factor">Source Code</a> • \ | |||||
<a href="http://validator.w3.org/check?uri=referer">Valid HTML5</a> | |||||
</footer> | |||||
</body> | |||||
</html> |
@@ -0,0 +1,15 @@ | |||||
<%page args="title"/>\ | |||||
<%! from flask import request, url_for %>\ | |||||
<!DOCTYPE html> | |||||
<html lang="en"> | |||||
<head> | |||||
<meta charset="utf-8"> | |||||
<title>${title}</title> | |||||
<link rel="stylesheet" href="${request.script_root}${url_for('static', file='style.css')}" type="text/css" /> | |||||
</head> | |||||
<body> | |||||
<header> | |||||
<h1><a href="${request.script_root}">TIF Calculator</a></h1> | |||||
<p>Calculate the <a href="https://en.wikipedia.org/wiki/User:The_Earwig/Sandbox/TIF">template influence factor</a> of any page on the English Wikipedia</p> | |||||
</header> | |||||
<div id="container"> |
@@ -0,0 +1,62 @@ | |||||
# -*- coding: utf-8 -*- | |||||
from datetime import datetime | |||||
from os.path import expanduser | |||||
from earwigbot.bot import Bot | |||||
from oursql import connect | |||||
__all__ = ["calculate_tif"] | |||||
def _get_db(bot): | |||||
args = bot.config.wiki["_tifSQL"] | |||||
args["read_default_file"] = expanduser("~/.my.cnf") | |||||
args["autoping"] = True | |||||
args["autoreconnect"] = True | |||||
return connect(**args) | |||||
def _get_transclusions(page): | |||||
# TODO | |||||
yield page | |||||
def _get_view_average(page, db, cache_info): | |||||
# TODO | |||||
return 0.0 | |||||
def _format_time(cache_time): | |||||
formatter = lambda n, w: "{0} {1}{2}".format(n, w, "" if n == 1 else "s") | |||||
diff = datetime.utcnow() - cache_time | |||||
if diff.seconds > 3600: | |||||
return formatter(diff.seconds / 3600, "hour") | |||||
if diff.seconds > 60: | |||||
return formatter(diff.seconds / 60, "minute") | |||||
return formatter(diff.seconds, "second") | |||||
def calculate_tif(title): | |||||
bot = Bot(".earwigbot") | |||||
db = _get_db(bot) | |||||
site = bot.wiki.get_site() | |||||
template = site.get_page(title) | |||||
result = {"title": title, "page": template} | |||||
if template.exists != template.PAGE_EXISTS: | |||||
result["error"] = "no page" | |||||
return result | |||||
tif = 0.0 | |||||
transclusions = 0 | |||||
cache_info = {"cache": False, "cache_time_raw": None} | |||||
for page in _get_transclusions(template): | |||||
tif += _get_view_average(page, db, cache_info) | |||||
transclusions += 1 | |||||
if cache_info["cache"]: | |||||
ctime = cache_info["cache_time"] | |||||
cache_info["cache_time"] = ctime.strftime("%b %d, %Y %H:%M:%S UTC") | |||||
cache_info["cache_ago"] = _format_time(ctime) | |||||
result["tif"] = tif | |||||
result["transclusions"] = transclusions | |||||
result["protection"] = template.protection | |||||
result.update(cache_info) | |||||
return result |