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: Improvements regarding comments Created Feb. 17, 2015, 10:50 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
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 19 import json, tempfile, time, os
20 20
21 def showError(message, start_response, status="400 Processing Error"): 21 def showError(message, start_response, status="400 Processing Error"):
22 start_response(status, [("Content-Type", "text/plain; charset=utf-8")]) 22 start_response(status, [("Content-Type", "text/plain; charset=utf-8")])
23 return [message.encode("utf-8")] 23 return [message.encode("utf-8")]
24 24
25 def valid_filter_hit(filter_hit):
26 return (
27 isinstance(filter_hit, dict) and
28 "thirdParty" in filter_hit and
29 isinstance(filter_hit["thirdParty"], dict) and
30 "firstParty" in filter_hit and
31 isinstance(filter_hit["firstParty"], dict) and
32 "subscriptions" in filter_hit and
33 isinstance(filter_hit["subscriptions"], (list, tuple))
34 )
35
36 def valid_log_data(data):
37 """
38 This returns True if the filterhits data passed is structured
39 roughly OK. Used as a quick check, it's not comprehensive.
40 """
41 return (
42 isinstance(data, dict) and
43 "version" in data and
44 "timeSincePush" in data and
45 "addonName" in data and
46 "addonVersion" in data and
47 "application" in data and
48 "applicationVersion" in data and
49 "platform" in data and
50 "platformVersion" in data and
51 "filters" in data and
52 isinstance(data["filters"], dict) and
53 (not len(data["filters"]) or
54 valid_filter_hit(data["filters"].itervalues().next()))
55 )
56
57 def datetime_to_timestamp(dt):
58 return int((dt - datetime(1970, 1, 1)).total_seconds())
59
60 def log_filterhits(data, basepath, query_string): 25 def log_filterhits(data, basepath, query_string):
61 """ 26 """
62 This logs the provided filterhits data as JSON to a file named after 27 This logs the provided filterhits data as JSON to a file named after
63 the current timestamp in a directory named after the current date. 28 the current timestamp in a directory named after the current date.
64 """ 29 """
65 now = datetime.now() 30 now = time.gmtime()
Sebastian Noack 2015/02/17 14:59:17 For reference, this will be UTC. I don't have a st
Wladimir Palant 2015/02/17 15:12:21 Local timezone is always a bad idea - already beca
Sebastian Noack 2015/02/17 15:19:44 I generally agree. Though I wasn't entirely sure i
66 31
67 dir_name = now.strftime("%Y-%m-%d") 32 dir_name = time.strftime("%Y-%m-%d", now)
68 path = os.path.join(basepath, dir_name) 33 path = os.path.join(basepath, dir_name)
69 if not os.path.exists(path): 34 try:
70 os.makedirs(path) 35 os.makedirs(path)
36 except OSError as e:
37 if e.errno != EEXIST:
38 raise
71 39
72 with tempfile.NamedTemporaryFile( 40 with tempfile.NamedTemporaryFile(
73 prefix = str(datetime_to_timestamp(now)) + "-", 41 prefix = str(int(time.mktime(now))) + "-",
74 suffix = ".log", 42 suffix = ".log",
75 dir = path, 43 dir = path,
76 delete = False 44 delete = False
77 ) as f: 45 ) as f:
78 f.write("[%s] \"%s\" %s\n" % (now.strftime('%d/%b/%Y:%H:%M:%S %z'), 46 f.write("[%s] \"%s\" %s\n" % (time.strftime('%d/%b/%Y:%H:%M:%S', now),
79 query_string, json.dumps(data))) 47 query_string, json.dumps(data)))
80 return f.name 48 return f.name
OLDNEW

Powered by Google App Engine
This is Rietveld