From 01159008fb206678848479b4cb3e2409f8e0c49d Mon Sep 17 00:00:00 2001 From: Aleksey Lim Date: Sun, 10 Nov 2013 14:52:29 +0000 Subject: Leave HTTP visits related stats conting to web server; reveal Context.dowloads and Artifact.downloads stats --- diff --git a/misc/aslo-sync b/misc/aslo-sync index 828d5a9..4641d97 100755 --- a/misc/aslo-sync +++ b/misc/aslo-sync @@ -135,10 +135,6 @@ LICENSES_MAP = { } -class AbsDict(dict): - pass - - class Application(application.Application): _my_connection = None diff --git a/sugar_network/model/artifact.py b/sugar_network/model/artifact.py index 5dba159..e461c4d 100644 --- a/sugar_network/model/artifact.py +++ b/sugar_network/model/artifact.py @@ -40,6 +40,10 @@ class Artifact(db.Resource): def description(self, value): return value + @db.indexed_property(slot=2, default=0, acl=ACL.READ | ACL.CALC) + def downloads(self, value): + return value + @db.indexed_property(slot=3, typecast=model.RATINGS, default=0, acl=ACL.READ | ACL.CALC) def rating(self, value): diff --git a/sugar_network/model/context.py b/sugar_network/model/context.py index e885b53..869ad6c 100644 --- a/sugar_network/model/context.py +++ b/sugar_network/model/context.py @@ -89,7 +89,11 @@ class Context(db.Resource): 'mime_type': 'image/png', }) - @db.indexed_property(slot=3, typecast=model.RATINGS, default=0, + @db.indexed_property(slot=3, default=0, acl=ACL.READ | ACL.CALC) + def downloads(self, value): + return value + + @db.indexed_property(slot=4, typecast=model.RATINGS, default=0, acl=ACL.READ | ACL.CALC) def rating(self, value): return value diff --git a/sugar_network/node/stats_node.py b/sugar_network/node/stats_node.py index 6c24278..e21a8bd 100644 --- a/sugar_network/node/stats_node.py +++ b/sugar_network/node/stats_node.py @@ -76,6 +76,7 @@ class Sniffer(object): class _ObjectStats(object): + downloads = 0 reviews = 0 rating = 0 @@ -92,6 +93,12 @@ class _Stats(object): self._volume = volume self._directory = volume[self.RESOURCE] + def __getitem__(self, guid): + result = self.active.get(guid) + if result is None: + result = self.active[guid] = _ObjectStats() + return result + def log(self, request): context = None @@ -122,20 +129,8 @@ class _Stats(object): elif request.method == 'POST': context = parse_context(request.content) - if request.principal: - stats = self._stats['user'] - if request.method in ('POST', 'PUT', 'DELETE'): - stats.effective.add(request.principal) - stats.active.add(request.principal) - if context: - return self._stats['context'].active_object(context) - - def active_object(self, guid): - result = self.active.get(guid) - if result is None: - result = self.active[guid] = _ObjectStats() - return result + return self._stats['context'][context] def commit(self): pass @@ -144,10 +139,6 @@ class _Stats(object): class _ResourceStats(_Stats): total = 0 - created = 0 - updated = 0 - deleted = 0 - viewed = 0 def __init__(self, stats, volume): _Stats.__init__(self, stats, volume) @@ -156,32 +147,29 @@ class _ResourceStats(_Stats): def log(self, request): result = _Stats.log(self, request) - if request.method == 'GET': - if request.guid and not request.prop: - self.viewed += 1 - elif request.method == 'PUT': - self.updated += 1 - elif request.method == 'POST': + if request.method == 'POST': self.total += 1 - self.created += 1 elif request.method == 'DELETE': self.total -= 1 - self.deleted += 1 return result def commit(self): if type(self.active) is dict: for guid, stats in self.active.items(): - if not stats.reviews: + if not stats.reviews and not stats.downloads: continue - reviews, rating = self._directory.get(guid)['reviews'] - reviews += stats.reviews - rating += stats.rating - self._directory.update(guid, { - 'reviews': [reviews, rating], - 'rating': int(round(float(rating) / reviews)), - }) + doc = self._directory.get(guid) + updates = {} + if stats.downloads: + updates['downloads'] = stats.downloads + doc['downloads'] + if stats.reviews: + reviews, rating = doc['reviews'] + reviews += stats.reviews + rating += stats.rating + updates['reviews'] = [reviews, rating] + updates['rating'] = int(round(float(rating) / reviews)) + self._directory.update(guid, updates) result = {} for attr in dir(self): @@ -193,11 +181,6 @@ class _ResourceStats(_Stats): if type(value) in (int, long): result[attr] = value - self.created = 0 - self.updated = 0 - self.deleted = 0 - self.viewed = 0 - return result @@ -205,17 +188,6 @@ class _UserStats(_ResourceStats): RESOURCE = 'user' - def __init__(self, stats, volume): - _ResourceStats.__init__(self, stats, volume) - self.active = set() - self.effective = set() - - def commit(self): - result = _ResourceStats.commit(self) - self.active.clear() - self.effective.clear() - return result - class _ContextStats(_ResourceStats): @@ -250,6 +222,8 @@ class _ImplementationStats(_Stats): if request.method == 'GET': if request.prop == 'data': + context = self._volume['implementation'].get(request.guid) + self._stats['context'][context.context].downloads += 1 self._stats['context'].downloaded += 1 elif request.method == 'POST': self._stats['context'].released += 1 @@ -280,7 +254,7 @@ class _ReviewStats(_ResourceStats): if request.method == 'POST': if request.content.get('artifact'): artifact = self._stats['artifact'] - stats = artifact.active_object(request.content['artifact']) + stats = artifact[request.content['artifact']] artifact.reviewed += 1 else: stats = context @@ -300,9 +274,6 @@ class _FeedbackStats(_ResourceStats): OWNERS = ['context'] solutions = 0 - solved = 0 - rejected = 0 - commented = 0 def __init__(self, stats, volume): @@ -317,16 +288,12 @@ class _FeedbackStats(_ResourceStats): if request.method in ('POST', 'PUT'): if 'solution' in request.content: if request.content['solution'] is None: - self.rejected += 1 self.solutions -= 1 else: - self.solved += 1 self.solutions += 1 def commit(self): result = _ResourceStats.commit(self) - self.solved = 0 - self.rejected = 0 self.commented = 0 return result @@ -361,6 +328,7 @@ class _ArtifactStats(_ResourceStats): if request.method == 'GET': if request.prop == 'data': + self[request.guid].downloads += 1 self.downloaded += 1 def commit(self): diff --git a/tests/units/node/stats_node.py b/tests/units/node/stats_node.py index 2fa9446..aaf953f 100755 --- a/tests/units/node/stats_node.py +++ b/tests/units/node/stats_node.py @@ -13,31 +13,6 @@ from sugar_network.toolkit.router import Request class StatsTest(tests.Test): - def ___test_DoNotLogAnonymouses(self): - volume = db.Volume('local', model.RESOURCES) - stats = Sniffer(volume) - - request = Request(method='GET', path=['context', 'guid']) - stats.log(request) - self.assertEqual(0, stats._stats['context'].viewed) - - request.principal = 'user' - stats.log(request) - self.assertEqual(1, stats._stats['context'].viewed) - - def test_DoNotLogCmds(self): - volume = db.Volume('local', model.RESOURCES) - stats = Sniffer(volume) - - request = Request(method='GET', path=['context', 'guid'], cmd='probe') - request.principal = 'user' - stats.log(request) - self.assertEqual(0, stats._stats['context'].viewed) - - request.cmd = None - stats.log(request) - self.assertEqual(1, stats._stats['context'].viewed) - def test_InitializeTotals(self): volume = db.Volume('local', model.RESOURCES) @@ -77,23 +52,6 @@ class StatsTest(tests.Test): stats.log(request) stats.log(request) self.assertEqual(3, stats._stats['context'].total) - self.assertEqual(3, stats._stats['context'].created) - self.assertEqual(0, stats._stats['context'].updated) - self.assertEqual(0, stats._stats['context'].deleted) - - def test_PUTs(self): - volume = db.Volume('local', model.RESOURCES) - stats = Sniffer(volume) - - request = Request(method='PUT', path=['context', 'guid']) - request.principal = 'user' - stats.log(request) - stats.log(request) - stats.log(request) - self.assertEqual(0, stats._stats['context'].total) - self.assertEqual(0, stats._stats['context'].created) - self.assertEqual(3, stats._stats['context'].updated) - self.assertEqual(0, stats._stats['context'].deleted) def test_DELETEs(self): volume = db.Volume('local', model.RESOURCES) @@ -105,27 +63,6 @@ class StatsTest(tests.Test): stats.log(request) stats.log(request) self.assertEqual(-3, stats._stats['context'].total) - self.assertEqual(0, stats._stats['context'].created) - self.assertEqual(0, stats._stats['context'].updated) - self.assertEqual(3, stats._stats['context'].deleted) - - def test_GETs(self): - volume = db.Volume('local', model.RESOURCES) - stats = Sniffer(volume) - - request = Request(method='GET', path=['user']) - request.principal = 'user' - stats.log(request) - self.assertEqual(0, stats._stats['user'].viewed) - - def test_GETsDocument(self): - volume = db.Volume('local', model.RESOURCES) - stats = Sniffer(volume) - - request = Request(method='GET', path=['user', 'user']) - request.principal = 'user' - stats.log(request) - self.assertEqual(1, stats._stats['user'].viewed) def test_FeedbackSolutions(self): volume = db.Volume('local', model.RESOURCES) @@ -136,23 +73,14 @@ class StatsTest(tests.Test): request.principal = 'user' request.content = {} stats.log(request) - self.assertEqual(1, stats._stats['feedback'].updated) - self.assertEqual(0, stats._stats['feedback'].rejected) - self.assertEqual(0, stats._stats['feedback'].solved) self.assertEqual(0, stats._stats['feedback'].solutions) request.content = {'solution': 'solution'} stats.log(request) - self.assertEqual(2, stats._stats['feedback'].updated) - self.assertEqual(0, stats._stats['feedback'].rejected) - self.assertEqual(1, stats._stats['feedback'].solved) self.assertEqual(1, stats._stats['feedback'].solutions) request.content = {'solution': None} stats.log(request) - self.assertEqual(3, stats._stats['feedback'].updated) - self.assertEqual(1, stats._stats['feedback'].rejected) - self.assertEqual(1, stats._stats['feedback'].solved) self.assertEqual(0, stats._stats['feedback'].solutions) def test_Comments(self): @@ -303,30 +231,6 @@ class StatsTest(tests.Test): ['1', '2', '3', '4', '5', '6', '7'], sorted(stats._stats['context'].active.keys())) - def test_UserActive(self): - volume = db.Volume('local', model.RESOURCES) - stats = Sniffer(volume) - - request = Request(method='GET', path=['user']) - request.principal = '1' - stats.log(request) - self.assertEqual( - set(['1']), - stats._stats['user'].active) - self.assertEqual( - set([]), - stats._stats['user'].effective) - - request = Request(method='POST', path=['user']) - request.principal = '2' - stats.log(request) - self.assertEqual( - set(['1', '2']), - stats._stats['user'].active) - self.assertEqual( - set(['2']), - stats._stats['user'].effective) - def test_ArtifactDownloaded(self): volume = db.Volume('local', model.RESOURCES) stats = Sniffer(volume) @@ -335,13 +239,11 @@ class StatsTest(tests.Test): request = Request(method='GET', path=['artifact', 'artifact', 'fake']) request.principal = 'user' stats.log(request) - self.assertEqual(0, stats._stats['artifact'].viewed) self.assertEqual(0, stats._stats['artifact'].downloaded) request = Request(method='GET', path=['artifact', 'artifact', 'data']) request.principal = 'user' stats.log(request) - self.assertEqual(0, stats._stats['artifact'].viewed) self.assertEqual(1, stats._stats['artifact'].downloaded) def test_Commit(self): @@ -375,94 +277,51 @@ class StatsTest(tests.Test): stats.log(request) self.assertEqual(1, stats._stats['user'].total) - self.assertEqual(1, stats._stats['user'].viewed) - self.assertEqual(1, stats._stats['user'].viewed) - self.assertEqual(set(['user']), stats._stats['user'].active) self.assertEqual(1, stats._stats['context'].total) - self.assertEqual(1, stats._stats['context'].viewed) self.assertEqual(['context'], stats._stats['context'].active.keys()) self.assertEqual(1, stats._stats['review'].total) - self.assertEqual(1, stats._stats['review'].viewed) self.assertEqual(1, stats._stats['feedback'].total) - self.assertEqual(1, stats._stats['feedback'].viewed) self.assertEqual(1, stats._stats['solution'].total) - self.assertEqual(1, stats._stats['solution'].viewed) self.assertEqual(1, stats._stats['artifact'].total) - self.assertEqual(1, stats._stats['artifact'].viewed) ts = int(time.time()) stats.commit(ts) self.assertEqual(1, stats._stats['user'].total) - self.assertEqual(0, stats._stats['user'].viewed) - self.assertEqual(set(), stats._stats['user'].active) self.assertEqual(1, stats._stats['context'].total) - self.assertEqual(0, stats._stats['context'].viewed) self.assertEqual([], stats._stats['context'].active.keys()) self.assertEqual(1, stats._stats['review'].total) - self.assertEqual(0, stats._stats['review'].viewed) self.assertEqual(1, stats._stats['feedback'].total) - self.assertEqual(0, stats._stats['feedback'].viewed) self.assertEqual(1, stats._stats['solution'].total) - self.assertEqual(0, stats._stats['solution'].viewed) self.assertEqual(1, stats._stats['artifact'].total) - self.assertEqual(0, stats._stats['artifact'].viewed) self.assertEqual([ [('feedback', ts, { - 'updated': 0.0, - 'created': 0.0, - 'deleted': 0.0, - 'rejected': 0.0, - 'solved': 0.0, 'solutions': 0.0, 'total': 1.0, 'commented': 0.0, - 'viewed': 1.0, })], [('review', ts, { - 'updated': 0.0, - 'created': 0.0, - 'deleted': 0.0, 'total': 1.0, 'commented': 0.0, - 'viewed': 1.0, })], [('solution', ts, { - 'updated': 0.0, - 'created': 0.0, - 'deleted': 0.0, 'total': 1.0, 'commented': 0.0, - 'viewed': 1.0, })], [('artifact', ts, { - 'updated': 0.0, - 'created': 0.0, - 'deleted': 0.0, 'reviewed': 0.0, 'downloaded': 0.0, 'total': 1.0, - 'viewed': 1.0, 'active': 0.0, })], [('user', ts, { - 'updated': 0.0, - 'effective': 0.0, - 'created': 0.0, - 'deleted': 0.0, - 'active': 1.0, 'total': 1.0, - 'viewed': 1.0, })], [('context', ts, { - 'updated': 0.0, 'failed': 0.0, - 'deleted': 0.0, - 'created': 0.0, 'reviewed': 0.0, 'downloaded': 0.0, - 'viewed': 1.0, 'active': 1.0, 'total': 1.0, 'released': 0.0, @@ -478,6 +337,7 @@ class StatsTest(tests.Test): volume['implementation'].create({'guid': 'implementation', 'context': 'context', 'license': 'GPLv3', 'version': '1', 'date': 0, 'stability': 'stable', 'notes': ''}) volume['artifact'].create({'guid': 'artifact', 'type': 'instance', 'context': 'context', 'title': '', 'description': ''}) + self.assertEqual(0, volume['context'].get('context')['downloads']) self.assertEqual([0, 0], volume['context'].get('context')['reviews']) self.assertEqual(0, volume['context'].get('context')['rating']) @@ -495,11 +355,13 @@ class StatsTest(tests.Test): stats.log(request) stats.commit() + self.assertEqual(1, volume['context'].get('context')['downloads']) self.assertEqual([1, 5], volume['context'].get('context')['reviews']) self.assertEqual(5, volume['context'].get('context')['rating']) stats.commit() + self.assertEqual(1, volume['context'].get('context')['downloads']) self.assertEqual([1, 5], volume['context'].get('context')['reviews']) self.assertEqual(5, volume['context'].get('context')['rating']) @@ -513,6 +375,7 @@ class StatsTest(tests.Test): stats.log(request) stats.commit() + self.assertEqual(2, volume['context'].get('context')['downloads']) self.assertEqual([2, 6], volume['context'].get('context')['reviews']) self.assertEqual(3, volume['context'].get('context')['rating']) @@ -523,6 +386,7 @@ class StatsTest(tests.Test): volume['context'].create({'guid': 'context', 'type': 'activity', 'title': '', 'summary': '', 'description': ''}) volume['artifact'].create({'guid': 'artifact', 'type': 'instance', 'context': 'context', 'title': '', 'description': ''}) + self.assertEqual(0, volume['artifact'].get('artifact')['downloads']) self.assertEqual([0, 0], volume['artifact'].get('artifact')['reviews']) self.assertEqual(0, volume['artifact'].get('artifact')['rating']) @@ -536,11 +400,13 @@ class StatsTest(tests.Test): stats.log(request) stats.commit() + self.assertEqual(1, volume['artifact'].get('artifact')['downloads']) self.assertEqual([1, 5], volume['artifact'].get('artifact')['reviews']) self.assertEqual(5, volume['artifact'].get('artifact')['rating']) stats.commit() + self.assertEqual(1, volume['artifact'].get('artifact')['downloads']) self.assertEqual([1, 5], volume['artifact'].get('artifact')['reviews']) self.assertEqual(5, volume['artifact'].get('artifact')['rating']) @@ -553,6 +419,7 @@ class StatsTest(tests.Test): stats.log(request) stats.commit() + self.assertEqual(2, volume['artifact'].get('artifact')['downloads']) self.assertEqual([2, 6], volume['artifact'].get('artifact')['reviews']) self.assertEqual(3, volume['artifact'].get('artifact')['rating']) -- cgit v0.9.1