 Issue 4883267715072000:
  Issue 2276 - Handle groups in notification.json requests  (Closed)
    
  
    Issue 4883267715072000:
  Issue 2276 - Handle groups in notification.json requests  (Closed) 
  | Index: sitescripts/notifications/web/notification.py | 
| =================================================================== | 
| new file mode 100644 | 
| --- /dev/null | 
| +++ b/sitescripts/notifications/web/notification.py | 
| @@ -0,0 +1,86 @@ | 
| +# coding: utf-8 | 
| + | 
| +# This file is part of the Adblock Plus web scripts, | 
| +# Copyright (C) 2006-2015 Eyeo GmbH | 
| +# | 
| +# Adblock Plus is free software: you can redistribute it and/or modify | 
| +# it under the terms of the GNU General Public License version 3 as | 
| +# published by the Free Software Foundation. | 
| +# | 
| +# Adblock Plus is distributed in the hope that it will be useful, | 
| +# but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
| +# GNU General Public License for more details. | 
| +# | 
| +# You should have received a copy of the GNU General Public License | 
| +# along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. | 
| + | 
| +import copy | 
| +import json | 
| +import random | 
| +import time | 
| +from urlparse import parse_qs | 
| + | 
| +from sitescripts.notifications.parser import load_notifications | 
| +from sitescripts.web import url_handler | 
| + | 
| +def _assign_groups(notifications): | 
| + groups = [] | 
| + selection = random.random() | 
| 
kzar
2015/06/03 11:09:50
Nit: `from random import random` and then we can j
 
Sebastian Noack
2015/06/03 12:17:15
I slightly prefer to import just the module, looki
 
Felix Dahlke
2015/06/12 11:02:40
Same here, not incredibly consistent about it howe
 
kzar
2015/06/15 15:17:38
Acknowledged.
 | 
| + start = 0 | 
| + for notification in notifications: | 
| + if "variants" not in notification: | 
| + continue | 
| + group = {"id": notification["id"], "variant": 0} | 
| + groups.append(group) | 
| + for i, variant in enumerate(notification["variants"]): | 
| + sample_size = variant["sample"] | 
| + end = start + sample_size | 
| + selected = sample_size > 0 and start <= selection <= end | 
| + start = end | 
| + if selected: | 
| + group["variant"] = i + 1 | 
| + break | 
| + return groups | 
| + | 
| +def _create_response(notifications, groups): | 
| + response = { | 
| + "version": time.strftime("%Y%m%d%H%M", time.gmtime()) | 
| + } | 
| + for group in groups: | 
| + group_id = group["id"] | 
| + variant = group["variant"] | 
| + response["version"] += "-%s/%s" % (group_id, variant) | 
| + if variant > 0: | 
| + notification = next(x for x in notifications if x["id"] == group_id) | 
| + notification = copy.deepcopy(notification) | 
| + notification.update(notification["variants"][variant - 1]) | 
| + for key_to_remove in ("sample", "variants"): | 
| + notification.pop(key_to_remove, None) | 
| + response["notifications"] = [notification] | 
| 
kzar
2015/06/03 11:09:50
Won't you overwrite a previous notification in the
 
Felix Dahlke
2015/06/12 11:02:40
That's intentional - if the user is in a test, the
 
kzar
2015/06/15 15:17:37
Acknowledged.
 | 
| + if "notifications" not in response: | 
| + response["notifications"] = [x for x in notifications | 
| + if "variants" not in x] | 
| + return json.dumps(response, ensure_ascii=False, indent=2, | 
| + separators=(",", ": "), sort_keys=True) | 
| + | 
| +@url_handler("/notification.json") | 
| +def notification(environ, start_response): | 
| + params = parse_qs(environ.get("QUERY_STRING", "")) | 
| 
kzar
2015/06/03 11:09:50
Nit: IMHO it's easier to do `params = dict(parse_q
 
Sebastian Noack
2015/06/03 12:17:15
Given that only one param is retrieved here, I thi
 
Felix Dahlke
2015/06/12 11:02:40
No particularly strong opinion, but I also think t
 
kzar
2015/06/15 15:17:37
Acknowledged.
 | 
| + version = params.get("lastVersion", [""])[0] | 
| + current_groups = dict(x.split("/") for x in version.split("-")[1:] | 
| + if x.count("/") == 1) | 
| + notifications = load_notifications() | 
| + groups = [] | 
| 
kzar
2015/06/03 11:09:50
Wouldn't it be better to merge current_groups with
 
Felix Dahlke
2015/06/12 11:02:40
I can see why you don't like this, but I'm not sur
 
Sebastian Noack
2015/06/12 11:15:09
I'd vote for this one.
 
Felix Dahlke
2015/06/12 12:12:52
I prefer that one too, went for it. Let me know wh
 
kzar
2015/06/15 15:17:37
Sounds good to me
 | 
| + for notification in notifications: | 
| + if "variants" not in notification: | 
| + continue | 
| + group_id = notification["id"] | 
| + if group_id in current_groups: | 
| + groups.append({"id": group_id, "variant": int(current_groups[group_id])}) | 
| + if not groups: | 
| + groups = _assign_groups(notifications) | 
| + response = _create_response(notifications, groups) | 
| + start_response("200 OK", | 
| + [("Content-Type", "application/json; charset=utf-8")]) | 
| + return response.encode("utf-8") |