Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: sitescripts/filterhits/common.py

Issue 4615801646612480: Issue 395 - Filter hits statistics backend (Closed)
Patch Set: Added API tests, addressed comments and some other improvements. Created Feb. 28, 2015, 7:36 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
1 # coding: utf-8 1 # coding: utf-8
2 2
3 # This file is part of the Adblock Plus web scripts, 3 # This file is part of the Adblock Plus web scripts,
4 # Copyright (C) 2006-2014 Eyeo GmbH 4 # Copyright (C) 2006-2015 Eyeo GmbH
5 # 5 #
6 # Adblock Plus is free software: you can redistribute it and/or modify 6 # Adblock Plus is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License version 3 as 7 # it under the terms of the GNU General Public License version 3 as
8 # published by the Free Software Foundation. 8 # published by the Free Software Foundation.
9 # 9 #
10 # Adblock Plus is distributed in the hope that it will be useful, 10 # Adblock Plus is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details. 13 # GNU General Public License for more details.
14 # 14 #
15 # You should have received a copy of the GNU General Public License 15 # You should have received a copy of the GNU General Public License
16 # along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. 16 # along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
17 17
18 from datetime import datetime 18 from errno import EEXIST
19 import json, tempfile, os, MySQLdb 19 import json, tempfile, time, os
20 20
21 def _get_db(config): 21 def showError(message, start_response, status="400 Processing Error"):
Sebastian Noack 2015/03/02 10:04:01 Nit: PEP-8 please, i.e. showError -> show_error
kzar 2015/03/02 10:39:03 (I was following the example from sitescripts.repo
22 return MySQLdb.connect( 22 start_response(status, [("Content-Type", "text/plain; charset=utf-8")])
23 user=config.get("filterhitstats", "dbuser"), 23 return [message.encode("utf-8")]
24 passwd=config.get("filterhitstats", "dbpassword"),
25 db=config.get("filterhitstats", "database"),
26 use_unicode=True, charset="utf8"
27 )
28 24
29 def datetime_to_timestamp(dt): 25 def log_filterhits(data, basepath, query_string):
30 return int((dt - datetime(1970, 1, 1)).total_seconds()) 26 """
27 This logs the provided filterhits data as JSON to a file named after
28 the current timestamp in a directory named after the current date.
29 """
30 now = time.gmtime()
31 31
32 def valid_filter_hit(filter_hit): 32 dir_name = time.strftime("%Y-%m-%d", now)
33 return (
34 isinstance(filter_hit, dict) and
35 "thirdParty" in filter_hit and
36 isinstance(filter_hit["thirdParty"], dict) and
37 "firstParty" in filter_hit and
38 isinstance(filter_hit["firstParty"], dict) and
39 "subscriptions" in filter_hit and
40 isinstance(filter_hit["subscriptions"], (list, tuple))
41 )
42
43 def valid_log_data(data):
44 """
45 This returns True if the filterhits data passed is structured
46 roughly OK. Used as a quick check, it's not comprehensive.
47 """
48 return (
49 isinstance(data, dict) and
50 "version" in data and
51 "timeSincePush" in data and
52 "addonName" in data and
53 "version" in data and
54 "timeSincePush" in data and
55 "addonName" in data and
56 "addonVersion" in data and
57 "application" in data and
58 "applicationVersion" in data and
59 "platform" in data and
60 "platformVersion" in data and
61 "filters" in data and
62 isinstance(data["filters"], dict) and
63 (not len(data["filters"]) or
64 valid_filter_hit(data["filters"].itervalues().next()))
65 )
66
67 def log_filterhits(data, basepath):
68 """
69 This logs the provided filterhits data as JSON to a file named after
70 the current timestamp in a directory named after the current date.
71 """
72 now = datetime.now()
73
74 dir_name = now.strftime("%Y-%m-%d")
75 path = os.path.join(basepath, dir_name) 33 path = os.path.join(basepath, dir_name)
76 if not os.path.exists(path): 34 try:
77 os.makedirs(path) 35 os.makedirs(path)
36 except OSError as e:
37 if e.errno != EEXIST:
38 raise
78 39
79 with tempfile.NamedTemporaryFile( 40 with tempfile.NamedTemporaryFile(
80 prefix = str(datetime_to_timestamp(now)) + "-", 41 prefix = str(int(time.mktime(now))) + "-",
81 suffix = ".log", 42 suffix = ".log",
82 dir = path, 43 dir = path,
83 delete = False 44 delete = False
84 ) as f: 45 ) as f:
85 f.write(json.dumps(data) + "\n") 46 f.write("[%s] \"%s\" %s\n" % (time.strftime('%d/%b/%Y:%H:%M:%S', now),
47 query_string, json.dumps(data)))
48 return f.name
OLDNEW

Powered by Google App Engine
This is Rietveld