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 """
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
28 uas
= self
.get_entries()
30 return uas
.most_common(1)[0][1]
35 def total_users(self
):
36 uas
= self
.get_entries()
38 return sum(uas
.values())
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 """
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
73 def parse_ua_string(self
, ua_string
):
75 m
= RE_GPODROID
.search(ua_string
)
77 return Client('gpodroid', m
.group(1), None, None, 'android', m
.group(2))
79 m
= RE_GPODDER
.search(ua_string
)
81 return Client('gpodder', m
.group(2), 'mygpoclient', m
.group(1), None, None)
83 m
= RE_MYGPOCLIENT
.search(ua_string
)
85 return Client(None, None, 'mygpoclient', m
.group(1), None, None)
87 m
= RE_CLEMENTINE
.search(ua_string
)
89 return Client('clementine', m
.group(1), None, None, None, None)
91 m
= RE_AMAROK
.search(ua_string
)
93 return Client('amarok', m
.group(1), None, None, None, None)
95 m
= RE_GPNACCOUNT
.search(ua_string
)
97 return Client(None, None, 'gpodder.net-account-android', None, 'android', None)