Bump babel from 2.9.1 to 2.10.3
[mygpo.git] / mygpo / administration / clients.py
blobcaeb30e033e171cf94459b66a2a19680427c4951
1 import re
2 from collections import namedtuple, Counter
4 from mygpo.users.models import Client
7 Client = namedtuple("Client", "client client_version lib lib_version os os_version")
10 class UserAgentStats(object):
11 """Provides User-Agent statistics"""
13 def __init__(self):
14 self._useragents = None
16 def get_entries(self):
17 if self._useragents is None:
18 result = Client.objects.values("user_agent").annotate(Count("user_agent"))
19 result = {x["user_agent"]: x["user_agent__count"] for x in result}
20 self._useragents = Counter(result)
22 return self._useragents
24 @property
25 def max_users(self):
26 uas = self.get_entries()
27 if uas:
28 return uas.most_common(1)[0][1]
29 else:
30 return 0
32 @property
33 def total_users(self):
34 uas = self.get_entries()
35 if uas:
36 return sum(uas.values())
37 else:
38 return 0
41 # regular expressions for detecting a client application from a User-Agent
42 RE_GPODROID = re.compile(
43 r"GpodRoid ([0-9.]+) Mozilla/5.0 \(Linux; U; Android ([0-9a-z.-]+);"
45 RE_GPODDER = re.compile(r"mygpoclient/([0-9.]+) \([^)]+\) gPodder/([0-9.]+)")
46 RE_MYGPOCLIENT = re.compile(r"mygpoclient/([0-9.]+) \([^)]+\)")
47 RE_CLEMENTINE = re.compile(r"Clementine ([0-9a-z.-]+)")
48 RE_AMAROK = re.compile(r"amarok/([0-9.]+)")
49 RE_GPNACCOUNT = re.compile(r"GPodder.net Account for Android")
52 class ClientStats(UserAgentStats):
53 """Provides statistics about client applications"""
55 def __init__(self):
56 self._clients = None
57 super(ClientStats, self).__init__()
59 def get_entries(self):
61 if self._clients is None:
62 self._clients = Counter()
64 uas = super(ClientStats, self).get_entries()
65 for ua_string, count in uas.items():
66 client = self.parse_ua_string(ua_string) or ua_string
67 self._clients[client] += count
69 return self._clients
71 def parse_ua_string(self, ua_string):
73 m = RE_GPODROID.search(ua_string)
74 if m:
75 return Client("gpodroid", m.group(1), None, None, "android", m.group(2))
77 m = RE_GPODDER.search(ua_string)
78 if m:
79 return Client("gpodder", m.group(2), "mygpoclient", m.group(1), None, None)
81 m = RE_MYGPOCLIENT.search(ua_string)
82 if m:
83 return Client(None, None, "mygpoclient", m.group(1), None, None)
85 m = RE_CLEMENTINE.search(ua_string)
86 if m:
87 return Client("clementine", m.group(1), None, None, None, None)
89 m = RE_AMAROK.search(ua_string)
90 if m:
91 return Client("amarok", m.group(1), None, None, None, None)
93 m = RE_GPNACCOUNT.search(ua_string)
94 if m:
95 return Client(
96 None, None, "gpodder.net-account-android", None, "android", None
99 return None