fix one-off error in merge-episode-states
[mygpo.git] / mygpo / admin / clients.py
blob455b9a306b6bae4565423e58b27db0298b6a9576
1 import re
2 from collections import namedtuple
4 from mygpo.users.models import User
5 from mygpo.counter import Counter
6 from mygpo.db.couchdb.user import user_agent_stats
9 Client = namedtuple('Client', 'client client_version lib lib_version os os_version')
12 class UserAgentStats(object):
13 """ Provides User-Agent statistics """
15 def __init__(self):
16 self._useragents = None
19 def get_entries(self):
20 if self._useragents is None:
21 self._useragents = user_agent_stats()
23 return self._useragents
26 @property
27 def max_users(self):
28 uas = self.get_entries()
29 if uas:
30 return uas.most_common(1)[0][1]
31 else:
32 return 0
34 @property
35 def total_users(self):
36 uas = self.get_entries()
37 if uas:
38 return sum(uas.values())
39 else:
40 return 0
43 # regular expressions for detecting a client application from a User-Agent
44 RE_GPODROID = re.compile('GpodRoid ([0-9.]+) Mozilla/5.0 \(Linux; U; Android ([0-9a-z.-]+);')
45 RE_GPODDER = re.compile('mygpoclient/([0-9.]+) \([^)]+\) gPodder/([0-9.]+)')
46 RE_MYGPOCLIENT = re.compile('mygpoclient/([0-9.]+) \([^)]+\)')
47 RE_CLEMENTINE = re.compile('Clementine ([0-9a-z.-]+)')
48 RE_AMAROK = re.compile('amarok/([0-9.]+)')
49 RE_GPNACCOUNT = re.compile('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__()
60 def get_entries(self):
62 if self._clients is None:
63 self._clients = Counter()
65 uas = super(ClientStats, self).get_entries()
66 for ua_string, count in uas.items():
67 client = self.parse_ua_string(ua_string) or ua_string
68 self._clients[client] += count
70 return self._clients
73 def parse_ua_string(self, ua_string):
75 m = RE_GPODROID.search(ua_string)
76 if m:
77 return Client('gpodroid', m.group(1), None, None, 'android', m.group(2))
79 m = RE_GPODDER.search(ua_string)
80 if m:
81 return Client('gpodder', m.group(2), 'mygpoclient', m.group(1), None, None)
83 m = RE_MYGPOCLIENT.search(ua_string)
84 if m:
85 return Client(None, None, 'mygpoclient', m.group(1), None, None)
87 m = RE_CLEMENTINE.search(ua_string)
88 if m:
89 return Client('clementine', m.group(1), None, None, None, None)
91 m = RE_AMAROK.search(ua_string)
92 if m:
93 return Client('amarok', m.group(1), None, None, None, None)
95 m = RE_GPNACCOUNT.search(ua_string)
96 if m:
97 return Client(None, None, 'gpodder.net-account-android', None, 'android', None)
99 return None