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: Addressed more comments. Created March 2, 2015, 10:37 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « sitescripts/filterhits/bin/process_logs.py ('k') | sitescripts/filterhits/db.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 show_error(message, start_response, status="400 Processing Error"):
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
« no previous file with comments | « sitescripts/filterhits/bin/process_logs.py ('k') | sitescripts/filterhits/db.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld