From de24419942178dbf17acd9311d0c0edf8d49be17 Mon Sep 17 00:00:00 2001 From: Aleksey Lim Date: Sat, 01 Feb 2014 19:01:16 +0000 Subject: Simplify objects model by introducing Post resource --- diff --git a/doc/objects.dia b/doc/objects.dia index 50439c4..11710bc 100644 --- a/doc/objects.dia +++ b/doc/objects.dia @@ -85,21 +85,181 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + ## + + + + + + + + + + + + ## + + + ## + + + + + + + + + ## + + + #*# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ## + + + + + + + + + + + + ## + + + ## + + + + + + + + + ## + + + #*# + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + #Context# @@ -410,7 +570,7 @@ ## - #Number of Implementation downloads# + #Number of Release downloads# @@ -427,36 +587,13 @@ #rating# - #int [R S]# - - - ## - - - #Avarage rating given by reviewers; value from 0 to 5# - - - - - - - - - - - - - - #reviews# - - - #int [R]# + #[int, int] [R S]# ## - #Number of reviews# + #A list of two integers, number of voting Posts and a sum of all votes# @@ -475,7 +612,7 @@ - + @@ -681,7 +818,7 @@ - + @@ -933,339 +1070,21 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - ## - - - - - - - - - - - - ## - - - ## - - - - - - - - - ## - - - #*# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ## - - - - - - - - - - - - ## - - - ## - - - - - - - - - ## - - - #*# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ## - - - - - - - - - - - - ## - - - ## - - - - - - - - - ## - - - #*# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ## - - - - - - - - - - - - ## - - - ## - - - - - - - - - ## - - - #*# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - + + + + @@ -1327,263 +1146,34 @@ - - + + - - - - - - - - - - - - - - - - - - #Feedback# - - - #Resource# - - - #Feedback related resources# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #context# - - - #Context [R WN]# - - - ## - - - #The Context this Feedback belongs to# - - - - - - - - - - - - - - #type# - - - #enum [R WA]# - - - ## - - - #Feedback type; see Wiki for details# - - - - - - - - - - - - - - #title# - - - #str [R WA F I]# - - - ## - - - #One line summary# - - - - - - - - - - - - - - #content# - - - #markdown [R WA F I]# - - - ## - - - #The content of the Feedback# - - - - - - - - - - - - - - #solution# - - - #Solution [R WA]# - - - #""# - - - #Solution to the Feedback# - - - - - - - - - - - - - - - - - - - + - + - + - + - + - + - #Solution# + #Post# #Resource# - #Solution for Question|Idea|Problem# + #Users' posts, text messages or files# @@ -1672,320 +1262,13 @@ #context# - #Context [R]# - - - ## - - - #Context,Solutoin created within# - - - - - - - - - - - - - - #feedback# - - - #Feedback [R WN]# - - - ## - - - #Feedback's GUID this Solution is for# - - - - - - - - - - - - - - #content# - - - #markdown [R WA F I]# - - - ## - - - #The content of the Solution# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ## - - - - - - - - - - - - ## - - - ## - - - - - - - - - ## - - - #*# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Common objects # - - - ## - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Comment# - - - #Resource# - - - #Comment all other objects except User|Context|Event|Comment# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #context# - - - #Context [R]# + #Context [R WN]# ## - #Context the Comment was created within# + #The Context this Post belongs to# @@ -1999,39 +1282,16 @@ - #review# + #topic# - #Review [R WN]# + #Post [R WN]# - #""# - - - #Review the Comment was created for# - - - - - - - - - - - - - - #feedback# - - - #Feedback [R WN]# - - - #""# + #null# - #Feedback the Comment was created for# + #Set if current Post is a dependent messsage, e.g., an answer to a question# @@ -2045,166 +1305,6 @@ - #solution# - - - #Solution [R WN]# - - - #""# - - - #Solution the Comment was created for# - - - - - - - - - - - - - - #message# - - - #str [R WN F I]# - - - ## - - - #Comment message# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Notification# - - - #Resource# - - - #Events generated by the Network as a reaction on Users behaviour; beides, it might be direct events betwen Users# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #type# @@ -2214,7 +1314,7 @@ ## - #Event type; see the Wiki for details# + #Post type; see Wiki for details# @@ -2228,76 +1328,7 @@ - #resource# - - - #enum [R WN]# - - - #""# - - - #The +object type# - - - - - - - - - - - - - - #object# - - - #str [R WN]# - - - #""# - - - #GUID of an Object that is associated with the Event# - - - - - - - - - - - - - - #to# - - - #User [R WN]# - - - #""# - - - #If this Event is intended to the particular User# - - - - - - - - - - - - - - #message# + #title# #str [R WN F I]# @@ -2306,7 +1337,7 @@ ## - #Event explanation# + #One line summary# @@ -2318,132 +1349,18 @@ - - - - - - - - - - - - - - - - - - - - - - - - - #Artifact# - - - #Resource# - - - #Artefacts created within the Context# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #context# + #message# - #Context [R WN]# + #markdown [R WN F I]# ## - #The Context this Artifact belongs to# + #Multilined text message# @@ -2457,16 +1374,16 @@ - #type# + #solution# - #enum [R WN]# + #Post [R W]# - ## + #null# - #Artifact type; see Wiki for details# + #If current Post has a "solution" Post, e.g., an answer to a question or issue resolution# @@ -2480,16 +1397,16 @@ - #title# + #vote# - #str [R WN S F I]# + #int [R WN S]# - #""# + #0# - #One line summary# + #The value from 0 to 5; If more than 0, the Post is ranking the Context or the topic# @@ -2503,16 +1420,16 @@ - #description# + #comments# - #markdown [R WN F I]# + #[object] [R W S]# - #""# + #[]# - #Long description# + #List of JSON objects with users' comments; see Wiki for details# @@ -2532,10 +1449,10 @@ #blob [R WN]# - ## + #null# - #PNG image to represent the Artifact with fixed size# + #PNG image to represent the Post# @@ -2555,10 +1472,10 @@ #blob [R WN]# - ## + #null# - #Artifact's vague data# + #Attachments to the Post# @@ -2581,7 +1498,7 @@ ## - #Number of downloads# + #Number of attachemtns downloads# @@ -2598,311 +1515,13 @@ #rating# - #int [R S]# - - - ## - - - #Avarage rating given by reviewers; value from 0 to 5# - - - - - - - - - - - - - - #reviews# - - - #int [R]# - - - ## - - - #Number of reviews# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Implementation# - - - #Resource# - - - #Implementation of the Context, e.g., Sugar activity bundle or .xol content# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #context# - - - #Context [R WN]# - - - ## - - - #The Context this Version belongs to# - - - - - - - - - - - - - - #license# - - - #[enum] [R WN F]# - - - ## - - - #List of licenses that the Implementation is covered by; see the Wiki for details# - - - - - - - - - - - - - - #version# - - - #str [R WN S]# - - - ## - - - #Version number# - - - - - - - - - - - - - - #stability# - - - #enum [R WN F]# + #[int, int] [R S]# ## - #Version stability level in Zero Install notation; see the Wiki for details# - - - - - - - - - - - - - - #notes# - - - #markdown [R WN F I]# - - - ## - - - #Release notes# - - - - - - - - - - - - - - #requires# - - - #[str] [R]# - - - #List of dependencies; see Wiki for details# - - - ## - - - - - - - - - - - - - - #data# - - - #blob [R WN]# - - - ## - - - #Contain implementation data# + #A list of two integers, number of voting Posts and a sum of all votes# @@ -2921,21 +1540,21 @@ - + - + - + - + - + - + #Report# @@ -2944,7 +1563,7 @@ #Resource# - #Reports about issues with Implementations# + #Reports about issues with Releases# @@ -3053,10 +1672,10 @@ - #implementation# + #release# - #Implementation [R WN]# + #Release [R WN]# #""# @@ -3127,556 +1746,9 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - ## - - - - - - - - - - - - ## - - - ## - - - - - - - - - ## - - - #*# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ## - - - - - - - - - - - - ## - - - ## - - - - - - - - - ## - - - #*# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #Review# - - - #Resource# - - - #Users' reviews# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #context# - - - #Context [R WN]# - - - ## - - - #The Context this Feedback belongs to# - - - - - - - - - - - - - - #artifact# - - - #Artifact [R WN]# - - - #""# - - - #If specified, the Review was created for an Artifact# - - - - - - - - - - - - - - #title# - - - #str [R WN F I]# - - - ## - - - #One line summary# - - - - - - - - - - - - - - #content# - - - #markdown [R WN F I]# - - - ## - - - #The content of the Review# - - - - - - - - - - - - - - #rating# - - - #int [R WN S]# - - - ## - - - #Reviewer' rating, value from 1 to 5.# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ## - - - - - - - - - - - - ## - - - ## - - - - - - - - - ## - - - #*# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ## - - - - - - - - - - - - ## - - - ## - - - - - - - - - ## - - - #*# - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -3705,7 +1777,7 @@ - + @@ -3738,7 +1810,7 @@ - + @@ -3771,7 +1843,7 @@ - + @@ -3804,7 +1876,7 @@ - + @@ -3837,7 +1909,7 @@ - + @@ -3870,7 +1942,7 @@ - + @@ -3903,7 +1975,7 @@ - + @@ -3936,7 +2008,7 @@ - + @@ -3969,7 +2041,7 @@ - + @@ -4002,7 +2074,7 @@ - + @@ -4035,7 +2107,7 @@ - + @@ -4069,5 +2141,280 @@ + + + + + + + + + + + + + + + + + + #Release# + + + #Resource# + + + #Implementation of the Context, e.g., Sugar activity bundle or .xol content# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #context# + + + #Context [R WN]# + + + ## + + + #The Context this Version belongs to# + + + + + + + + + + + + + + #license# + + + #[enum] [R WN F]# + + + ## + + + #List of licenses that the Implementation is covered by; see the Wiki for details# + + + + + + + + + + + + + + #version# + + + #str [R WN S]# + + + ## + + + #Version number# + + + + + + + + + + + + + + #stability# + + + #enum [R WN F]# + + + ## + + + #Version stability level in Zero Install notation; see the Wiki for details# + + + + + + + + + + + + + + #notes# + + + #markdown [R WN F I]# + + + ## + + + #Release notes# + + + + + + + + + + + + + + #requires# + + + #[str] [R]# + + + #List of dependencies; see Wiki for details# + + + ## + + + + + + + + + + + + + + #data# + + + #blob [R WN]# + + + ## + + + #Contain implementation data# + + + + + + + + + + + + + + + + + + diff --git a/sugar_network/model/__init__.py b/sugar_network/model/__init__.py index 117649b..167eb30 100644 --- a/sugar_network/model/__init__.py +++ b/sugar_network/model/__init__.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 Aleksey Lim +# Copyright (C) 2012-2014 Aleksey Lim # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -16,13 +16,19 @@ from sugar_network.model.routes import VolumeRoutes, FrontRoutes -CONTEXT_TYPES = ['activity', 'group', 'package', 'book'] -NOTIFICATION_TYPES = ['create', 'update', 'delete', 'vote'] -FEEDBACK_TYPES = ['question', 'idea', 'problem'] -ARTIFACT_TYPES = ['instance', 'preview'] - -NOTIFICATION_OBJECT_TYPES = [ - '', 'content', 'feedback', 'solution', 'artifact', 'version', 'report', +CONTEXT_TYPES = [ + 'activity', 'group', 'package', 'book', + ] +POST_TYPES = [ + 'review', # Review the Context + 'object', # Object generated by Context application + 'question', # Q&A request + 'answer', # Q&A response + 'issue', # Propblem with the Context + 'announce', # General announcement + 'update', # Auto-generated Post for updates within the Context + 'feedback', # Review parent Post + 'comment', # Dependent Post ] STABILITIES = [ @@ -32,14 +38,9 @@ STABILITIES = [ RATINGS = [0, 1, 2, 3, 4, 5] RESOURCES = ( - 'sugar_network.model.artifact', - 'sugar_network.model.comment', 'sugar_network.model.context', + 'sugar_network.model.post', 'sugar_network.model.release', - 'sugar_network.model.notification', - 'sugar_network.model.feedback', 'sugar_network.model.report', - 'sugar_network.model.review', - 'sugar_network.model.solution', 'sugar_network.model.user', ) diff --git a/sugar_network/model/comment.py b/sugar_network/model/comment.py deleted file mode 100644 index 88917ed..0000000 --- a/sugar_network/model/comment.py +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright (C) 2012-2013 Aleksey Lim -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program 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 this program. If not, see . - -from sugar_network import db -from sugar_network.toolkit.router import ACL - - -class Comment(db.Resource): - - @db.indexed_property(prefix='C', - acl=ACL.READ) - def context(self, value): - return value - - @db.indexed_property(prefix='R', default='', - acl=ACL.CREATE | ACL.READ) - def review(self, value): - return value - - @review.setter - def review(self, value): - if value: - review = self.volume['review'].get(value) - self['context'] = review['context'] - return value - - @db.indexed_property(prefix='F', default='', - acl=ACL.CREATE | ACL.READ) - def feedback(self, value): - return value - - @feedback.setter - def feedback(self, value): - if value: - feedback = self.volume['feedback'].get(value) - self['context'] = feedback['context'] - return value - - @db.indexed_property(prefix='S', default='', - acl=ACL.CREATE | ACL.READ) - def solution(self, value): - return value - - @solution.setter - def solution(self, value): - if value: - solution = self.volume['solution'].get(value) - self['context'] = solution['context'] - return value - - @db.indexed_property(prefix='M', full_text=True, localized=True, - acl=ACL.CREATE | ACL.READ) - def message(self, value): - return value diff --git a/sugar_network/model/context.py b/sugar_network/model/context.py index 461960b..872d74d 100644 --- a/sugar_network/model/context.py +++ b/sugar_network/model/context.py @@ -111,11 +111,11 @@ class Context(db.Resource): 'mime_type': 'image/png', }) - @db.indexed_property(slot=3, default=0, acl=ACL.READ | ACL.CALC) + @db.indexed_property(slot=2, default=0, acl=ACL.READ | ACL.CALC) def downloads(self, value): return value - @db.indexed_property(slot=4, typecast=model.RATINGS, default=0, + @db.indexed_property(slot=3, typecast=model.RATINGS, default=0, acl=ACL.READ | ACL.CALC) def rating(self, value): return value diff --git a/sugar_network/model/feedback.py b/sugar_network/model/feedback.py deleted file mode 100644 index 45bacfe..0000000 --- a/sugar_network/model/feedback.py +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright (C) 2012-2013 Aleksey Lim -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program 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 this program. If not, see . - -from sugar_network import db, model -from sugar_network.toolkit.router import ACL - - -class Feedback(db.Resource): - - @db.indexed_property(prefix='C', acl=ACL.CREATE | ACL.READ) - def context(self, value): - return value - - @db.indexed_property(prefix='T', typecast=[model.FEEDBACK_TYPES]) - def type(self, value): - return value - - @db.indexed_property(prefix='S', full_text=True, localized=True) - def title(self, value): - return value - - @db.indexed_property(prefix='N', full_text=True, localized=True) - def content(self, value): - return value - - @db.indexed_property(prefix='A', default='') - def solution(self, value): - return value diff --git a/sugar_network/model/notification.py b/sugar_network/model/notification.py deleted file mode 100644 index e567b65..0000000 --- a/sugar_network/model/notification.py +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright (C) 2012-2013 Aleksey Lim -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program 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 this program. If not, see . - -from sugar_network import db, model -from sugar_network.toolkit.router import ACL - - -class Notification(db.Resource): - - @db.indexed_property(prefix='T', - acl=ACL.CREATE | ACL.READ, - typecast=model.NOTIFICATION_TYPES) - def type(self, value): - return value - - @db.indexed_property(prefix='K', - acl=ACL.CREATE | ACL.READ, - default='', typecast=model.NOTIFICATION_OBJECT_TYPES) - def resource(self, value): - return value - - @db.indexed_property(prefix='O', - acl=ACL.CREATE | ACL.READ, default='') - def object(self, value): - return value - - @db.indexed_property(prefix='D', - acl=ACL.CREATE | ACL.READ, default='') - def to(self, value): - return value - - @db.indexed_property(prefix='M', full_text=True, localized=True, - acl=ACL.CREATE | ACL.READ) - def message(self, value): - return value diff --git a/sugar_network/model/artifact.py b/sugar_network/model/post.py index 0a0239d..d7a742c 100644 --- a/sugar_network/model/artifact.py +++ b/sugar_network/model/post.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 Aleksey Lim +# Copyright (C) 2012-2014 Aleksey Lim # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -17,44 +17,48 @@ from sugar_network import db, model, static from sugar_network.toolkit.router import Blob, ACL -class Artifact(db.Resource): +class Post(db.Resource): @db.indexed_property(prefix='C', acl=ACL.CREATE | ACL.READ) def context(self, value): return value - @db.indexed_property(prefix='T', typecast=[model.ARTIFACT_TYPES]) + @db.indexed_property(prefix='A', default='', + acl=ACL.CREATE | ACL.READ) + def topic(self, value): + return value + + @topic.setter + def topic(self, value): + if value and not self['context']: + post = self.volume['post'].get(value) + self['context'] = post['context'] + return value + + @db.indexed_property(prefix='T', typecast=model.POST_TYPES) def type(self, value): return value - @db.indexed_property(slot=1, prefix='S', full_text=True, localized=True, + @db.indexed_property(slot=1, prefix='N', full_text=True, localized=True, acl=ACL.CREATE | ACL.READ) def title(self, value): return value @db.indexed_property(prefix='D', full_text=True, localized=True, acl=ACL.CREATE | ACL.READ) - def description(self, value): + def message(self, value): return value - @db.indexed_property(slot=2, default=0, acl=ACL.READ | ACL.CALC) - def downloads(self, value): + @db.indexed_property(prefix='R', default='') + def solution(self, value): return value - @db.indexed_property(slot=3, typecast=model.RATINGS, default=0, - acl=ACL.READ | ACL.CALC) - def rating(self, value): + @db.indexed_property(prefix='V', typecast=model.RATINGS, default=0, + acl=ACL.CREATE | ACL.READ) + def vote(self, value): return value - @db.stored_property(typecast=[], default=[0, 0], - acl=ACL.READ | ACL.CALC) - def reviews(self, value): - if value is None: - return 0 - else: - return value[0] - @db.blob_property(mime_type='image/png') def preview(self, value): if value: @@ -70,3 +74,20 @@ class Artifact(db.Resource): if value: value['name'] = self['title'] 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): + return value + + @db.stored_property(typecast=[], default=[0, 0], + acl=ACL.READ | ACL.CALC) + def reviews(self, value): + if value is None: + return 0 + else: + return value[0] diff --git a/sugar_network/model/review.py b/sugar_network/model/review.py deleted file mode 100644 index 621ac87..0000000 --- a/sugar_network/model/review.py +++ /dev/null @@ -1,52 +0,0 @@ -# Copyright (C) 2012-2013 Aleksey Lim -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program 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 this program. If not, see . - -from sugar_network import db, model -from sugar_network.toolkit.router import ACL - - -class Review(db.Resource): - - @db.indexed_property(prefix='C', - acl=ACL.CREATE | ACL.READ) - def context(self, value): - return value - - @db.indexed_property(prefix='A', default='', - acl=ACL.CREATE | ACL.READ) - def artifact(self, value): - return value - - @artifact.setter - def artifact(self, value): - if value and not self['context']: - artifact = self.volume['artifact'].get(value) - self['context'] = artifact['context'] - return value - - @db.indexed_property(prefix='S', full_text=True, localized=True, - acl=ACL.CREATE | ACL.READ) - def title(self, value): - return value - - @db.indexed_property(prefix='N', full_text=True, localized=True, - acl=ACL.CREATE | ACL.READ) - def content(self, value): - return value - - @db.indexed_property(slot=1, typecast=model.RATINGS, - acl=ACL.CREATE | ACL.READ) - def rating(self, value): - return value diff --git a/sugar_network/model/solution.py b/sugar_network/model/solution.py deleted file mode 100644 index 549e0f2..0000000 --- a/sugar_network/model/solution.py +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright (C) 2012-2013 Aleksey Lim -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program 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 this program. If not, see . - -from sugar_network import db -from sugar_network.toolkit.router import ACL - - -class Solution(db.Resource): - - @db.indexed_property(prefix='C', acl=ACL.READ) - def context(self, value): - return value - - @db.indexed_property(prefix='P', acl=ACL.CREATE | ACL.READ) - def feedback(self, value): - return value - - @feedback.setter - def feedback(self, value): - if value: - feedback = self.volume['feedback'].get(value) - self['context'] = feedback['context'] - return value - - @db.indexed_property(prefix='N', full_text=True, localized=True) - def content(self, value): - return value diff --git a/sugar_network/node/routes.py b/sugar_network/node/routes.py index 5f066a9..4bc97e4 100644 --- a/sugar_network/node/routes.py +++ b/sugar_network/node/routes.py @@ -438,12 +438,8 @@ def generate_node_stats(volume, path): ('user', []), ('context', []), ('release', ['context']), - ('artifact', ['context', 'type']), - ('feedback', ['context']), - ('solution', ['context', 'feedback']), - ('review', ['context', 'artifact', 'rating']), ('report', ['context', 'release']), - ('comment', ['context', 'review', 'feedback', 'solution']), + ('post', ['context', 'topic', 'type', 'vote']), ]: objs, __ = volume[resource].find( query='ctime:%s..%s' % (left, right)) @@ -455,12 +451,8 @@ def generate_node_stats(volume, path): ('user', ['layer']), ('context', ['layer']), ('release', ['layer']), - ('artifact', ['layer']), - ('feedback', ['layer', 'solution']), - ('solution', ['layer']), - ('review', ['layer']), ('report', ['layer']), - ('comment', ['layer']), + ('post', ['layer']), ]: objs, __ = volume[resource].find( query='mtime:%s..%s' % (left, right)) @@ -473,7 +465,7 @@ def generate_node_stats(volume, path): content=obj.properties(props)) new_stats.log(request) downloaded = {} - for resource in ('context', 'artifact'): + for resource in ('context', 'post'): stats = old_stats.report( {resource: ['downloaded']}, left - step, right, 1) if not stats.get(resource): diff --git a/sugar_network/node/stats_node.py b/sugar_network/node/stats_node.py index cc77424..ed2c0bd 100644 --- a/sugar_network/node/stats_node.py +++ b/sugar_network/node/stats_node.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 Aleksey Lim +# Copyright (C) 2012-2014 Aleksey Lim # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -170,7 +170,7 @@ class Sniffer(object): class _Stats(dict): RESOURCE = None - OWNERS = [] + PARENTS = [] def __init__(self, stats, volume): self.objects = {} @@ -205,14 +205,14 @@ class _ResourceStats(_Stats): directory = self._volume[self.RESOURCE] def parse_context(props): - for owner in self.OWNERS: - guid = props.get(owner) + for prop, resource in self.PARENTS: + guid = props.get(prop) if not guid: continue - if owner == 'context': + if resource == 'context': return guid else: - return self._volume[owner].get(guid)['context'] + return self._volume[resource].get(guid)['context'] if request.method == 'GET': if not request.guid: @@ -253,7 +253,7 @@ class _ContextStats(_ResourceStats): class _ReleaseStats(_Stats): RESOURCE = 'release' - OWNERS = ['context'] + PARENTS = [('context', 'context')] def log(self, request): if request.method == 'GET': @@ -268,81 +268,45 @@ class _ReleaseStats(_Stats): class _ReportStats(_Stats): RESOURCE = 'report' - OWNERS = ['context', 'release'] + PARENTS = [('context', 'context'), ('release', 'release')] def log(self, request): if request.method == 'POST': self._stats['context']['failed'] += 1 -class _ReviewStats(_ResourceStats): +class _PostStats(_ResourceStats): - RESOURCE = 'review' - OWNERS = ['artifact', 'context'] - - def log(self, request): - _ResourceStats.log(self, request) - - if request.method == 'POST': - if request.content.get('artifact'): - stats = self._stats['artifact'] - guid = request.content['artifact'] - else: - stats = self._stats['context'] - guid = self.parse_context(request) - stats.inc(guid, 'reviews') - stats.inc(guid, 'rating', request.content.get('rating') or 0) - - -class _FeedbackStats(_ResourceStats): - - RESOURCE = 'feedback' - OWNERS = ['context'] - - -class _SolutionStats(_ResourceStats): - - RESOURCE = 'solution' - OWNERS = ['feedback'] - - -class _ArtifactStats(_ResourceStats): - - RESOURCE = 'artifact' - OWNERS = ['context'] + RESOURCE = 'post' + PARENTS = [('context', 'context'), ('topic', 'post')] def __init__(self, stats, volume): _ResourceStats.__init__(self, stats, volume) self['downloaded'] = 0 def log(self, request): - if request.method == 'POST': - if request.content.get('type') != 'preview': - self['total'] += 1 - elif request.method == 'DELETE': - existing = self._volume[self.RESOURCE].get(request.guid) - if existing['type'] != 'preview': - self['total'] -= 1 - elif request.method == 'GET' and request.prop == 'data': - existing = self._volume[self.RESOURCE].get(request.guid) - if existing['type'] != 'preview': - self.inc(request.guid, 'downloads') - self['downloaded'] += 1 - + _ResourceStats.log(self, request) -class _CommentStats(_ResourceStats): + if request.method == 'POST': + stats = None + if request.content['type'] == 'review': + stats = self._stats['context'] + guid = request.content['context'] + elif request.content['type'] == 'feedback': + stats = self._stats['post'] + guid = request.content['topic'] + if stats: + stats.inc(guid, 'reviews') + stats.inc(guid, 'rating', request.content.get('vote') or 0) - RESOURCE = 'comment' - OWNERS = ['solution', 'feedback', 'review'] + elif request.method == 'GET' and request.prop == 'data': + self.inc(request.guid, 'downloads') + self['downloaded'] += 1 _STATS = {_UserStats.RESOURCE: _UserStats, _ContextStats.RESOURCE: _ContextStats, _ReleaseStats.RESOURCE: _ReleaseStats, _ReportStats.RESOURCE: _ReportStats, - _ReviewStats.RESOURCE: _ReviewStats, - _FeedbackStats.RESOURCE: _FeedbackStats, - _SolutionStats.RESOURCE: _SolutionStats, - _ArtifactStats.RESOURCE: _ArtifactStats, - _CommentStats.RESOURCE: _CommentStats, + _PostStats.RESOURCE: _PostStats, } diff --git a/tests/integration/node_client.py b/tests/integration/node_client.py index 601e969..64fe97c 100755 --- a/tests/integration/node_client.py +++ b/tests/integration/node_client.py @@ -130,7 +130,7 @@ class NodeClientTest(tests.Test): def test_UsecaseOOB(self): self.cli(['--quiet', 'PUT', '/context/context', 'cmd=clone', '-jd', 'true']) - assert exists('client/db/release/im/release/data.blob/activity/activity.info') + assert exists('client/db/release/re/release/data.blob/activity/activity.info') self.assertEqual(['clone'], json.load(file('client/db/context/co/context/layer'))['value']) def cli(self, cmd, stdin=None): diff --git a/tests/units/client/online_routes.py b/tests/units/client/online_routes.py index 0431934..1d1b780 100755 --- a/tests/units/client/online_routes.py +++ b/tests/units/client/online_routes.py @@ -25,7 +25,7 @@ from sugar_network.model.user import User from sugar_network.model.report import Report from sugar_network.model.context import Context from sugar_network.model.release import Release -from sugar_network.model.artifact import Artifact +from sugar_network.model.post import Post from sugar_network.toolkit.router import route from sugar_network.toolkit import Option @@ -1223,7 +1223,7 @@ Can't find all required implementations: ipc.get(['context', guid], reply=['title'])) def test_RestrictLayers(self): - self.start_online_client([User, Context, Release, Artifact]) + self.start_online_client([User, Context, Release]) ipc = IPCConnection() context = ipc.post(['context'], { @@ -1404,18 +1404,18 @@ Can't find all required implementations: assert trigger.wait(.1) is not None def test_ContentDisposition(self): - self.start_online_client([User, Context, Release, Artifact]) + self.start_online_client([User, Context, Release, Post]) ipc = IPCConnection() - artifact = ipc.post(['artifact'], { - 'type': 'instance', + post = ipc.post(['post'], { + 'type': 'object', 'context': 'context', 'title': 'title', - 'description': 'description', + 'message': '', }) - ipc.request('PUT', ['artifact', artifact, 'data'], 'blob', headers={'Content-Type': 'image/png'}) + ipc.request('PUT', ['post', post, 'data'], 'blob', headers={'Content-Type': 'image/png'}) - response = ipc.request('GET', ['artifact', artifact, 'data']) + response = ipc.request('GET', ['post', post, 'data']) self.assertEqual( 'attachment; filename="Title.png"', response.headers.get('Content-Disposition')) diff --git a/tests/units/db/index.py b/tests/units/db/index.py index ef6df53..9d996b0 100755 --- a/tests/units/db/index.py +++ b/tests/units/db/index.py @@ -30,6 +30,10 @@ class IndexTest(tests.Test): def test_Create(self): db = Index({'key': IndexedProperty('key', 1, 'K')}) + self.assertEqual( + ([], 0), + db._find()) + db.store('1', {'key': 'value_1'}) self.assertEqual( ([{'guid': '1', 'key': 'value_1'}], 1), diff --git a/tests/units/model/__main__.py b/tests/units/model/__main__.py index 6cc5c7f..2766988 100644 --- a/tests/units/model/__main__.py +++ b/tests/units/model/__main__.py @@ -2,11 +2,9 @@ from __init__ import tests -from comment import * +from post import * from context import * from release import * -from review import * -from solution import * from routes import * if __name__ == '__main__': diff --git a/tests/units/model/comment.py b/tests/units/model/comment.py deleted file mode 100755 index 495e6cb..0000000 --- a/tests/units/model/comment.py +++ /dev/null @@ -1,75 +0,0 @@ -#!/usr/bin/env python -# sugar-lint: disable - -from __init__ import tests - -from sugar_network.client import Connection, keyfile -from sugar_network.model.user import User -from sugar_network.model.context import Context -from sugar_network.model.review import Review -from sugar_network.model.feedback import Feedback -from sugar_network.model.solution import Solution -from sugar_network.model.comment import Comment -from sugar_network.model.release import Release -from sugar_network.toolkit import http - - -class CommentTest(tests.Test): - - def test_SetContext(self): - volume = self.start_master([User, Context, Review, Feedback, Solution, Comment, Release]) - client = Connection(auth=http.SugarAuth(keyfile.value)) - - self.assertRaises(http.NotFound, client.post, ['comment'], {'message': '', 'review': 'absent'}) - self.assertRaises(http.NotFound, client.post, ['comment'], {'message': '', 'feedback': 'absent'}) - self.assertRaises(http.NotFound, client.post, ['comment'], {'message': '', 'solution': 'absent'}) - - context = client.post(['context'], { - 'type': 'package', - 'title': 'title', - 'summary': 'summary', - 'description': 'description', - }) - review = client.post(['review'], { - 'context': context, - 'title': 'title', - 'content': 'content', - 'rating': 5, - }) - comment = client.post(['comment'], { - 'review': review, - 'message': '', - }) - self.assertEqual( - context, - client.get(['comment', comment, 'context'])) - - feedback = client.post(['feedback'], { - 'context': context, - 'type': 'idea', - 'title': 'title', - 'content': 'content', - }) - comment = client.post(['comment'], { - 'feedback': feedback, - 'message': '', - }) - self.assertEqual( - context, - client.get(['comment', comment, 'context'])) - - solution = client.post(['solution'], { - 'feedback': feedback, - 'content': 'content', - }) - comment = client.post(['comment'], { - 'solution': solution, - 'message': '', - }) - self.assertEqual( - context, - client.get(['comment', comment, 'context'])) - - -if __name__ == '__main__': - tests.main() diff --git a/tests/units/model/solution.py b/tests/units/model/post.py index d4c7444..91a0298 100755 --- a/tests/units/model/solution.py +++ b/tests/units/model/post.py @@ -6,38 +6,40 @@ from __init__ import tests from sugar_network.client import Connection, keyfile from sugar_network.model.user import User from sugar_network.model.context import Context -from sugar_network.model.feedback import Feedback -from sugar_network.model.solution import Solution +from sugar_network.model.post import Post from sugar_network.model.release import Release from sugar_network.toolkit import http -class SolutionTest(tests.Test): +class PostTest(tests.Test): def test_SetContext(self): - volume = self.start_master([User, Context, Feedback, Solution, Release]) + volume = self.start_master([User, Context, Release, Post]) client = Connection(auth=http.SugarAuth(keyfile.value)) + self.assertRaises(http.NotFound, client.post, ['post'], {'type': 'comment', 'title': '', 'message': '', 'topic': 'absent'}) + context = client.post(['context'], { 'type': 'package', 'title': 'title', 'summary': 'summary', 'description': 'description', }) - feedback = client.post(['feedback'], { + topic = client.post(['post'], { 'context': context, - 'type': 'idea', 'title': 'title', - 'content': 'content', + 'message': 'message', + 'type': 'update', }) - solution = client.post(['solution'], { - 'feedback': feedback, - 'content': '', + comment = client.post(['post'], { + 'topic': topic, + 'title': 'title', + 'message': 'message', + 'type': 'comment', }) - self.assertEqual( context, - client.get(['solution', solution, 'context'])) + client.get(['post', comment, 'context'])) if __name__ == '__main__': diff --git a/tests/units/model/review.py b/tests/units/model/review.py deleted file mode 100755 index 10277ac..0000000 --- a/tests/units/model/review.py +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env python -# sugar-lint: disable - -from __init__ import tests - -from sugar_network.client import Connection, keyfile -from sugar_network.model.user import User -from sugar_network.model.context import Context -from sugar_network.model.review import Review -from sugar_network.model.artifact import Artifact -from sugar_network.model.release import Release -from sugar_network.toolkit import http - - -class ReviewTest(tests.Test): - - def test_SetContext(self): - volume = self.start_master([User, Context, Review, Artifact, Release]) - client = Connection(auth=http.SugarAuth(keyfile.value)) - - context = client.post(['context'], { - 'type': 'package', - 'title': 'title', - 'summary': 'summary', - 'description': 'description', - }) - artifact = client.post(['artifact'], { - 'type': 'instance', - 'context': context, - 'title': 'title', - 'description': 'description', - }) - - review = client.post(['review'], { - 'context': context, - 'title': 'title', - 'content': 'content', - 'rating': 5, - }) - self.assertEqual( - context, - client.get(['review', review, 'context'])) - self.assertEqual( - '', - client.get(['review', review, 'artifact'])) - - review = client.post(['review'], { - 'artifact': artifact, - 'title': 'title', - 'content': 'content', - 'rating': 5, - }) - self.assertEqual( - context, - client.get(['review', review, 'context'])) - self.assertEqual( - artifact, - client.get(['review', review, 'artifact'])) - - -if __name__ == '__main__': - tests.main() diff --git a/tests/units/node/node.py b/tests/units/node/node.py index 1e8b093..22c0bd3 100755 --- a/tests/units/node/node.py +++ b/tests/units/node/node.py @@ -25,10 +25,6 @@ from sugar_network.node.master import MasterRoutes from sugar_network.model.user import User from sugar_network.model.context import Context from sugar_network.model.release import Release -from sugar_network.model.review import Review -from sugar_network.model.feedback import Feedback -from sugar_network.model.artifact import Artifact -from sugar_network.model.solution import Solution from sugar_network.model.user import User from sugar_network.toolkit.router import Router, Request, Response, fallbackroute, Blob, ACL, route from sugar_network.toolkit import http @@ -1000,82 +996,49 @@ class NodeTest(tests.Test): 'license': ['GPL-3'], 'version': '1', }) - volume['artifact'].create({ - 'guid': 'artifact_1', + volume['post'].create({ + 'guid': 'topic_1', 'ctime': ts + 3, 'mtime': ts + 3, 'layer': [], 'context': 'context_1', - 'type': 'instance', + 'type': 'object', 'title': '', - 'description': '', - }) - volume['feedback'].create({ - 'guid': 'feedback_1', - 'ctime': ts + 4, - 'mtime': ts + 4, - 'layer': [], - 'context': 'context_1', - 'title': '', - 'content': '', - 'type': 'idea', + 'message': '', }) - volume['solution'].create({ + volume['post'].create({ 'guid': 'solution_1', 'ctime': ts + 5, 'mtime': ts + 5, 'layer': [], 'context': 'context_1', - 'feedback': 'feedback_1', - 'content': '', + 'topic': 'topic_1', + 'title': '', + 'message': '', + 'type': 'answer', }) - volume['review'].create({ + volume['post'].create({ 'guid': 'review_1', 'ctime': ts + 6, 'mtime': ts + 6, 'layer': [], 'context': 'context_1', - 'rating': 1, + 'vote': 1, 'title': '', - 'content': '', + 'message': '', + 'type': 'review', }) - volume['review'].create({ + volume['post'].create({ 'guid': 'review_2', 'ctime': ts + 6, 'mtime': ts + 6, 'layer': [], 'context': 'context_1', - 'artifact': 'artifact_1', - 'rating': 2, + 'topic': 'topic_1', + 'vote': 2, 'title': '', - 'content': '', - }) - volume['comment'].create({ - 'guid': 'comment_1', - 'ctime': ts + 7, - 'mtime': ts + 7, - 'layer': [], - 'context': 'context_1', - 'review': 'review_1', - 'message': '', - }) - volume['comment'].create({ - 'guid': 'comment_2', - 'ctime': ts + 7, - 'mtime': ts + 7, - 'layer': [], - 'context': 'context_1', - 'feedback': 'feedback_1', - 'message': '', - }) - volume['comment'].create({ - 'guid': 'comment_3', - 'ctime': ts + 7, - 'mtime': ts + 7, - 'layer': [], - 'context': 'context_1', - 'solution': 'solution_1', 'message': '', + 'type': 'feedback', }) volume['report'].create({ 'guid': 'report_1', @@ -1086,7 +1049,6 @@ class NodeTest(tests.Test): 'release': 'impl_1', 'error': '', }) - volume['user'].create({ 'guid': 'user_2', 'ctime': ts + 4, @@ -1122,25 +1084,27 @@ class NodeTest(tests.Test): 'license': ['GPL-3'], 'version': '1', }) - volume['review'].create({ + volume['post'].create({ 'guid': 'review_3', 'ctime': ts + 4, 'mtime': ts + 4, 'layer': [], 'context': 'context_2', - 'rating': 3, + 'vote': 3, 'title': '', - 'content': '', + 'message': '', + 'type': 'review', }) - volume['review'].create({ + volume['post'].create({ 'guid': 'review_4', 'ctime': ts + 4, 'mtime': ts + 4, 'layer': [], 'context': 'context_2', - 'rating': 4, + 'vote': 4, 'title': '', - 'content': '', + 'message': '', + 'type': 'review', }) volume['report'].create({ 'guid': 'report_2', @@ -1160,76 +1124,32 @@ class NodeTest(tests.Test): 'release': 'impl_1', 'error': '', }) - volume['artifact'].create({ - 'guid': 'artifact_2', + volume['post'].create({ + 'guid': 'topic_2', 'ctime': ts + 4, 'mtime': ts + 4, 'layer': [], 'context': 'context_2', - 'type': 'instance', + 'type': 'object', 'title': '', - 'description': '', - }) - volume['feedback'].create({ - 'guid': 'feedback_2', - 'ctime': ts + 4, - 'mtime': ts + 4, - 'layer': [], - 'context': 'context_2', - 'title': '', - 'content': '', - 'type': 'idea', - }) - volume['solution'].create({ - 'guid': 'solution_2', - 'ctime': ts + 4, - 'mtime': ts + 4, - 'layer': [], - 'context': 'context_2', - 'feedback': 'feedback_2', - 'content': '', - }) - volume['comment'].create({ - 'guid': 'comment_4', - 'ctime': ts + 4, - 'mtime': ts + 4, - 'layer': [], - 'context': 'context_2', - 'review': 'review_3', - 'message': '', - }) - volume['comment'].create({ - 'guid': 'comment_5', - 'ctime': ts + 4, - 'mtime': ts + 4, - 'layer': [], - 'context': 'context_2', - 'review': 'review_4', - 'message': '', - }) - volume['comment'].create({ - 'guid': 'comment_6', - 'ctime': ts + 4, - 'mtime': ts + 4, - 'layer': [], - 'context': 'context_2', - 'feedback': 'feedback_2', 'message': '', }) - volume['comment'].create({ - 'guid': 'comment_7', + volume['post'].create({ + 'guid': 'solution_2', 'ctime': ts + 4, 'mtime': ts + 4, 'layer': [], 'context': 'context_2', - 'solution': 'solution_2', + 'topic': 'topic_2', + 'title': '', 'message': '', + 'type': 'answer', }) self.override(time, 'time', lambda: ts + 9) old_stats = stats_node.Sniffer(volume, 'stats/node') old_stats.log(Request(method='GET', path=['release', 'impl_1', 'data'])) - old_stats.log(Request(method='GET', path=['artifact', 'artifact_1', 'data'])) + old_stats.log(Request(method='GET', path=['post', 'topic_1', 'data'])) old_stats.commit(ts + 1) old_stats.commit_objects() old_stats.commit(ts + 2) @@ -1240,8 +1160,8 @@ class NodeTest(tests.Test): old_stats.commit_objects() old_stats.commit(ts + 5) old_stats.commit(ts + 6) - old_stats.log(Request(method='GET', path=['artifact', 'artifact_1', 'data'])) - old_stats.log(Request(method='GET', path=['artifact', 'artifact_2', 'data'])) + old_stats.log(Request(method='GET', path=['post', 'topic_1', 'data'])) + old_stats.log(Request(method='GET', path=['post', 'topic_2', 'data'])) old_stats.commit(ts + 7) old_stats.commit_objects() old_stats.commit(ts + 8) @@ -1273,60 +1193,16 @@ class NodeTest(tests.Test): (ts + 8, {'total': 2.0, 'released': 3.0, 'failed': 3.0, 'downloaded': 3.0}), (ts + 9, {'total': 2.0, 'released': 3.0, 'failed': 3.0, 'downloaded': 3.0}), ], - 'review': [ - (ts + 1, {'total': 0.0}), - (ts + 2, {'total': 0.0}), - (ts + 3, {'total': 0.0}), - (ts + 4, {'total': 2.0}), - (ts + 5, {'total': 2.0}), - (ts + 6, {'total': 4.0}), - (ts + 7, {'total': 4.0}), - (ts + 8, {'total': 4.0}), - (ts + 9, {'total': 4.0}), - ], - 'feedback': [ - (ts + 1, {'total': 0.0}), - (ts + 2, {'total': 0.0}), - (ts + 3, {'total': 0.0}), - (ts + 4, {'total': 2.0}), - (ts + 5, {'total': 2.0}), - (ts + 6, {'total': 2.0}), - (ts + 7, {'total': 2.0}), - (ts + 8, {'total': 2.0}), - (ts + 9, {'total': 2.0}), - ], - 'solution': [ - (ts + 1, {'total': 0.0}), - (ts + 2, {'total': 0.0}), - (ts + 3, {'total': 0.0}), - (ts + 4, {'total': 1.0}), - (ts + 5, {'total': 2.0}), - (ts + 6, {'total': 2.0}), - (ts + 7, {'total': 2.0}), - (ts + 8, {'total': 2.0}), - (ts + 9, {'total': 2.0}), - ], - 'artifact': [ + 'post': [ (ts + 1, {'total': 0.0, 'downloaded': 1.0}), (ts + 2, {'total': 0.0, 'downloaded': 1.0}), (ts + 3, {'total': 1.0, 'downloaded': 1.0}), - (ts + 4, {'total': 2.0, 'downloaded': 1.0}), - (ts + 5, {'total': 2.0, 'downloaded': 1.0}), - (ts + 6, {'total': 2.0, 'downloaded': 1.0}), - (ts + 7, {'total': 2.0, 'downloaded': 3.0}), - (ts + 8, {'total': 2.0, 'downloaded': 3.0}), - (ts + 9, {'total': 2.0, 'downloaded': 3.0}), - ], - 'comment': [ - (ts + 1, {'total': 0.0}), - (ts + 2, {'total': 0.0}), - (ts + 3, {'total': 0.0}), - (ts + 4, {'total': 4.0}), - (ts + 5, {'total': 4.0}), - (ts + 6, {'total': 4.0}), - (ts + 7, {'total': 7.0}), - (ts + 8, {'total': 7.0}), - (ts + 9, {'total': 7.0}), + (ts + 4, {'total': 5.0, 'downloaded': 1.0}), + (ts + 5, {'total': 6.0, 'downloaded': 1.0}), + (ts + 6, {'total': 8.0, 'downloaded': 1.0}), + (ts + 7, {'total': 8.0, 'downloaded': 3.0}), + (ts + 8, {'total': 8.0, 'downloaded': 3.0}), + (ts + 9, {'total': 8.0, 'downloaded': 3.0}), ], }, call(cp, method='GET', cmd='stats', source=[ @@ -1335,12 +1211,8 @@ class NodeTest(tests.Test): 'context.released', 'context.failed', 'context.downloaded', - 'review.total', - 'feedback.total', - 'solution.total', - 'artifact.total', - 'artifact.downloaded', - 'comment.total', + 'post.total', + 'post.downloaded', ], start=ts + 1, end=ts + 10)) self.assertEqual({ @@ -1360,13 +1232,13 @@ class NodeTest(tests.Test): 'rating': 2, 'reviews': [1, 2], }, - volume['artifact'].get('artifact_1').properties(['downloads', 'rating', 'reviews'])) + volume['post'].get('topic_1').properties(['downloads', 'rating', 'reviews'])) self.assertEqual({ 'downloads': 1, 'rating': 0, 'reviews': [0, 0], }, - volume['artifact'].get('artifact_2').properties(['downloads', 'rating', 'reviews'])) + volume['post'].get('topic_2').properties(['downloads', 'rating', 'reviews'])) def test_generate_node_stats_Deletes(self): node.stats_root.value = 'stats' @@ -1402,52 +1274,14 @@ class NodeTest(tests.Test): 'license': ['GPL-3'], 'version': '1', }) - volume['artifact'].create({ - 'guid': 'artifact_1', - 'ctime': ts + 1, - 'mtime': ts + 2, - 'layer': ['deleted'], - 'context': 'context_1', - 'type': 'instance', - 'title': '', - 'description': '', - }) - volume['feedback'].create({ - 'guid': 'feedback_1', - 'ctime': ts + 1, - 'mtime': ts + 2, - 'layer': ['deleted'], - 'context': 'context_1', - 'title': '', - 'content': '', - 'type': 'idea', - }) - volume['solution'].create({ - 'guid': 'solution_1', - 'ctime': ts + 1, - 'mtime': ts + 2, - 'layer': ['deleted'], - 'context': 'context_1', - 'feedback': 'feedback_1', - 'content': '', - }) - volume['review'].create({ - 'guid': 'review_1', + volume['post'].create({ + 'guid': 'post_1', 'ctime': ts + 1, 'mtime': ts + 2, 'layer': ['deleted'], 'context': 'context_1', - 'rating': 1, + 'type': 'object', 'title': '', - 'content': '', - }) - volume['comment'].create({ - 'guid': 'comment_1', - 'ctime': ts + 1, - 'mtime': ts + 2, - 'layer': ['deleted'], - 'context': 'context_1', - 'review': 'review_1', 'message': '', }) volume['report'].create({ @@ -1475,27 +1309,7 @@ class NodeTest(tests.Test): (ts + 2, {'total': 0.0}), (ts + 3, {'total': 0.0}), ], - 'review': [ - (ts + 1, {'total': 1.0}), - (ts + 2, {'total': 0.0}), - (ts + 3, {'total': 0.0}), - ], - 'feedback': [ - (ts + 1, {'total': 1.0}), - (ts + 2, {'total': 0.0}), - (ts + 3, {'total': 0.0}), - ], - 'solution': [ - (ts + 1, {'total': 1.0}), - (ts + 2, {'total': 0.0}), - (ts + 3, {'total': 0.0}), - ], - 'artifact': [ - (ts + 1, {'total': 1.0}), - (ts + 2, {'total': 0.0}), - (ts + 3, {'total': 0.0}), - ], - 'comment': [ + 'post': [ (ts + 1, {'total': 1.0}), (ts + 2, {'total': 0.0}), (ts + 3, {'total': 0.0}), @@ -1504,11 +1318,7 @@ class NodeTest(tests.Test): call(cp, method='GET', cmd='stats', source=[ 'user.total', 'context.total', - 'review.total', - 'feedback.total', - 'solution.total', - 'artifact.total', - 'comment.total', + 'post.total', ], start=ts + 1, end=ts + 3)) diff --git a/tests/units/node/stats_node.py b/tests/units/node/stats_node.py index 22f43da..666a183 100755 --- a/tests/units/node/stats_node.py +++ b/tests/units/node/stats_node.py @@ -19,26 +19,16 @@ class StatsTest(tests.Test): stats = Sniffer(volume, 'stats/node') self.assertEqual(0, stats._stats['user']['total']) self.assertEqual(0, stats._stats['context']['total']) - self.assertEqual(0, stats._stats['review']['total']) - self.assertEqual(0, stats._stats['feedback']['total']) - self.assertEqual(0, stats._stats['solution']['total']) - self.assertEqual(0, stats._stats['artifact']['total']) + self.assertEqual(0, stats._stats['post']['total']) volume['user'].create({'guid': 'user', 'name': 'user', 'pubkey': ''}) volume['context'].create({'guid': 'context', 'type': 'activity', 'title': '', 'summary': '', 'description': ''}) - volume['review'].create({'guid': 'review', 'context': 'context', 'title': '', 'content': '', 'rating': 5}) - volume['feedback'].create({'guid': 'feedback', 'context': 'context', 'type': 'idea', 'title': '', 'content': ''}) - volume['feedback'].create({'guid': 'feedback2', 'context': 'context', 'type': 'idea', 'title': '', 'content': '', 'solution': 'solution'}) - volume['solution'].create({'guid': 'solution', 'context': 'context', 'feedback': 'feedback', 'content': ''}) - volume['artifact'].create({'guid': 'artifact', 'type': 'instance', 'context': 'context', 'title': '', 'description': ''}) + volume['post'].create({'guid': 'post', 'context': 'context', 'title': '', 'message': '', 'type': 'update'}) stats = Sniffer(volume, 'stats/node') self.assertEqual(1, stats._stats['user']['total']) self.assertEqual(1, stats._stats['context']['total']) - self.assertEqual(1, stats._stats['review']['total']) - self.assertEqual(2, stats._stats['feedback']['total']) - self.assertEqual(1, stats._stats['solution']['total']) - self.assertEqual(1, stats._stats['artifact']['total']) + self.assertEqual(1, stats._stats['post']['total']) def test_POSTs(self): volume = db.Volume('local', model.RESOURCES) @@ -62,58 +52,35 @@ class StatsTest(tests.Test): stats.log(request) self.assertEqual(-3, stats._stats['context']['total']) - def test_Comments(self): - volume = db.Volume('local', model.RESOURCES) - stats = Sniffer(volume, 'stats/node') - volume['solution'].create({'guid': 'solution', 'context': 'context', 'feedback': 'feedback', 'content': ''}) - volume['feedback'].create({'guid': 'feedback', 'context': 'context', 'type': 'idea', 'title': '', 'content': ''}) - volume['review'].create({'guid': 'review', 'context': 'context', 'title': '', 'content': '', 'rating': 5}) - - request = Request(method='POST', path=['comment']) - request.principal = 'user' - request.content = {'solution': 'solution'} - stats.log(request) - self.assertEqual(1, stats._stats['comment']['total']) - - request = Request(method='POST', path=['comment']) - request.principal = 'user' - request.content = {'feedback': 'feedback'} - stats.log(request) - self.assertEqual(2, stats._stats['comment']['total']) - - request = Request(method='POST', path=['comment']) - request.principal = 'user' - request.content = {'review': 'review'} - stats.log(request) - self.assertEqual(3, stats._stats['comment']['total']) - - def test_Reviewes(self): + def test_Posts(self): volume = db.Volume('local', model.RESOURCES) stats = Sniffer(volume, 'stats/node') volume['context'].create({'guid': 'context', 'type': 'activity', 'title': '', 'summary': '', 'description': ''}) - volume['artifact'].create({'guid': 'artifact', 'type': 'instance', 'context': 'context', 'title': '', 'description': ''}) + volume['post'].create({'guid': 'topic', 'type': 'update', 'context': 'context', 'title': '', 'message': ''}) - request = Request(method='POST', path=['review']) + request = Request(method='POST', path=['post']) request.principal = 'user' - request.content = {'context': 'context', 'rating': 1} + request.content = {'context': 'context', 'vote': 1, 'type': 'review', 'title': '', 'message': ''} stats.log(request) - self.assertEqual(1, stats._stats['review']['total']) + self.assertEqual(1, stats._stats['post']['total']) - request = Request(method='POST', path=['review']) + request = Request(method='POST', path=['post']) request.principal = 'user' - request.content = {'context': 'context', 'artifact': '', 'rating': 2} + request.content = {'context': 'context', 'vote': 2, 'type': 'review', 'title': '', 'message': ''} stats.log(request) - self.assertEqual(2, stats._stats['review']['total']) + self.assertEqual(2, stats._stats['post']['total']) - request = Request(method='POST', path=['review']) + request = Request(method='POST', path=['post']) request.principal = 'user' - request.content = {'artifact': 'artifact', 'rating': 3} + request.content = {'topic': 'topic', 'vote': 3, 'type': 'feedback', 'title': '', 'message': ''} stats.log(request) - self.assertEqual(3, stats._stats['review']['total']) + self.assertEqual(3, stats._stats['post']['total']) stats.commit_objects() self.assertEqual([2, 3], volume['context'].get('context')['reviews']) - self.assertEqual([1, 3], volume['artifact'].get('artifact')['reviews']) + self.assertEqual(2, volume['context'].get('context')['rating']) + self.assertEqual([1, 3], volume['post'].get('topic')['reviews']) + self.assertEqual(3, volume['post'].get('topic')['rating']) def test_ContextDownloaded(self): volume = db.Volume('local', model.RESOURCES) @@ -153,30 +120,26 @@ class StatsTest(tests.Test): stats.log(request) self.assertEqual(1, stats._stats['context']['failed']) - def test_ArtifactDownloaded(self): + def test_PostDownloaded(self): volume = db.Volume('local', model.RESOURCES) stats = Sniffer(volume, 'stats/node') - volume['artifact'].create({'guid': 'artifact', 'type': 'instance', 'context': 'context', 'title': '', 'description': ''}) + volume['post'].create({'guid': 'topic', 'type': 'object', 'context': 'context', 'title': '', 'message': ''}) - request = Request(method='GET', path=['artifact', 'artifact', 'fake']) + request = Request(method='GET', path=['post', 'topic', 'fake']) request.principal = 'user' stats.log(request) - self.assertEqual(0, stats._stats['artifact']['downloaded']) + self.assertEqual(0, stats._stats['post']['downloaded']) - request = Request(method='GET', path=['artifact', 'artifact', 'data']) + request = Request(method='GET', path=['post', 'topic', 'data']) request.principal = 'user' stats.log(request) - self.assertEqual(1, stats._stats['artifact']['downloaded']) + self.assertEqual(1, stats._stats['post']['downloaded']) def test_Commit(self): volume = db.Volume('local', model.RESOURCES) volume['user'].create({'guid': 'user', 'name': 'user', 'pubkey': ''}) volume['context'].create({'guid': 'context', 'type': 'activity', 'title': '', 'summary': '', 'description': ''}) - volume['review'].create({'guid': 'review', 'context': 'context', 'title': '', 'content': '', 'rating': 5}) - volume['feedback'].create({'guid': 'feedback', 'context': 'context', 'type': 'idea', 'title': '', 'content': ''}) - volume['solution'].create({'guid': 'solution', 'context': 'context', 'feedback': 'feedback', 'content': ''}) - volume['artifact'].create({'guid': 'artifact', 'type': 'instance', 'context': 'context', 'title': '', 'description': ''}) - volume['comment'].create({'guid': 'comment', 'context': 'context', 'message': ''}) + volume['post'].create({'guid': 'review', 'context': 'context', 'type': 'review', 'title': '', 'message': '', 'vote': 5}) stats = Sniffer(volume, 'stats/node') request = Request(method='GET', path=['user', 'user']) @@ -185,25 +148,13 @@ class StatsTest(tests.Test): request = Request(method='GET', path=['context', 'context']) request.principal = 'user' stats.log(request) - request = Request(method='GET', path=['review', 'review']) - request.principal = 'user' - stats.log(request) - request = Request(method='GET', path=['feedback', 'feedback']) - request.principal = 'user' - stats.log(request) - request = Request(method='GET', path=['solution', 'solution']) - request.principal = 'user' - stats.log(request) - request = Request(method='GET', path=['artifact', 'artifact']) + request = Request(method='GET', path=['post', 'review']) request.principal = 'user' stats.log(request) self.assertEqual(1, stats._stats['user']['total']) self.assertEqual(1, stats._stats['context']['total']) - self.assertEqual(1, stats._stats['review']['total']) - self.assertEqual(1, stats._stats['feedback']['total']) - self.assertEqual(1, stats._stats['solution']['total']) - self.assertEqual(1, stats._stats['artifact']['total']) + self.assertEqual(1, stats._stats['post']['total']) ts = int(time.time()) stats.commit(ts) @@ -211,25 +162,10 @@ class StatsTest(tests.Test): self.assertEqual(1, stats._stats['user']['total']) self.assertEqual(1, stats._stats['context']['total']) - self.assertEqual(1, stats._stats['review']['total']) - self.assertEqual(1, stats._stats['feedback']['total']) - self.assertEqual(1, stats._stats['solution']['total']) - self.assertEqual(1, stats._stats['artifact']['total']) + self.assertEqual(1, stats._stats['post']['total']) self.assertEqual([ - [('comment', ts, { - 'total': 1.0, - })], - [('feedback', ts, { - 'total': 1.0, - })], - [('review', ts, { - 'total': 1.0, - })], - [('solution', ts, { - 'total': 1.0, - })], - [('artifact', ts, { + [('post', ts, { 'downloaded': 0.0, 'total': 1.0, })], @@ -250,7 +186,6 @@ class StatsTest(tests.Test): volume['context'].create({'guid': 'context', 'type': 'activity', 'title': '', 'summary': '', 'description': ''}) volume['release'].create({'guid': 'release', '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']) @@ -260,14 +195,11 @@ class StatsTest(tests.Test): request = Request(method='GET', path=['release', 'release', 'data']) request.principal = 'user' stats.log(request) - request = Request(method='POST', path=['review']) + request = Request(method='POST', path=['post']) request.principal = 'user' - request.content = {'context': 'context', 'rating': 5} - stats.log(request) - request = Request(method='POST', path=['review']) - request.principal = 'user' - request.content = {'artifact': 'artifact', 'rating': 5} + request.content = {'context': 'context', 'vote': 5, 'type': 'review', 'title': '', 'message': ''} stats.log(request) + stats.commit() stats.commit_objects() @@ -286,9 +218,9 @@ class StatsTest(tests.Test): request = Request(method='GET', path=['release', 'release', 'data']) request.principal = 'user' stats.log(request) - request = Request(method='POST', path=['review']) + request = Request(method='POST', path=['post']) request.principal = 'user' - request.content = {'context': 'context', 'rating': 1} + request.content = {'context': 'context', 'vote': 1, 'type': 'review', 'title': '', 'message': ''} stats.log(request) stats.commit() stats.commit_objects() @@ -297,51 +229,51 @@ class StatsTest(tests.Test): self.assertEqual([2, 6], volume['context'].get('context')['reviews']) self.assertEqual(3, volume['context'].get('context')['rating']) - def test_CommitArtifactStats(self): + def test_CommitTopicStats(self): volume = db.Volume('local', model.RESOURCES) volume['context'].create({'guid': 'context', 'type': 'activity', 'title': '', 'summary': '', 'description': ''}) - volume['artifact'].create({'guid': 'artifact', 'type': 'instance', 'context': 'context', 'title': '', 'description': ''}) + volume['post'].create({'guid': 'topic', 'type': 'object', 'context': 'context', 'title': '', 'message': ''}) - 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']) + self.assertEqual(0, volume['post'].get('topic')['downloads']) + self.assertEqual([0, 0], volume['post'].get('topic')['reviews']) + self.assertEqual(0, volume['post'].get('topic')['rating']) stats = Sniffer(volume, 'stats/node') - request = Request(method='GET', path=['artifact', 'artifact', 'data']) + request = Request(method='GET', path=['post', 'topic', 'data']) request.principal = 'user' stats.log(request) - request = Request(method='POST', path=['review']) + request = Request(method='POST', path=['post']) request.principal = 'user' - request.content = {'artifact': 'artifact', 'rating': 5} + request.content = {'topic': 'topic', 'vote': 5, 'type': 'feedback'} stats.log(request) stats.commit() stats.commit_objects() - 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']) + self.assertEqual(1, volume['post'].get('topic')['downloads']) + self.assertEqual([1, 5], volume['post'].get('topic')['reviews']) + self.assertEqual(5, volume['post'].get('topic')['rating']) stats.commit() stats.commit_objects() - 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']) + self.assertEqual(1, volume['post'].get('topic')['downloads']) + self.assertEqual([1, 5], volume['post'].get('topic')['reviews']) + self.assertEqual(5, volume['post'].get('topic')['rating']) - request = Request(method='GET', path=['artifact', 'artifact', 'data']) + request = Request(method='GET', path=['post', 'topic', 'data']) request.principal = 'user' stats.log(request) - request = Request(method='POST', path=['review']) + request = Request(method='POST', path=['post']) request.principal = 'user' - request.content = {'artifact': 'artifact', 'rating': 1} + request.content = {'topic': 'topic', 'vote': 1, 'type': 'feedback'} stats.log(request) stats.commit() stats.commit_objects() - 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']) + self.assertEqual(2, volume['post'].get('topic')['downloads']) + self.assertEqual([2, 6], volume['post'].get('topic')['reviews']) + self.assertEqual(3, volume['post'].get('topic')['rating']) def test_Suspend(self): stats_node_step.value = 5 diff --git a/tests/units/node/sync_online.py b/tests/units/node/sync_online.py index 400ba4b..7ee6dcb 100755 --- a/tests/units/node/sync_online.py +++ b/tests/units/node/sync_online.py @@ -14,7 +14,6 @@ from sugar_network.node.master import MasterRoutes from sugar_network.node.slave import SlaveRoutes from sugar_network.db.volume import Volume from sugar_network.model.user import User -from sugar_network.model.feedback import Feedback from sugar_network.toolkit.router import Router from sugar_network.toolkit import coroutine, http @@ -35,8 +34,23 @@ class SyncOnlineTest(tests.Test): self.override(stats_user, 'merge', stats_merge) self.override(stats_user, 'commit', lambda seq: self.stats_commit.append(seq)) - class Document(Feedback): - pass + class Document(db.Resource): + + @db.indexed_property(prefix='C') + def context(self, value): + return value + + @db.indexed_property(prefix='T') + def type(self, value): + return value + + @db.indexed_property(slot=1, prefix='N', full_text=True, localized=True) + def title(self, value): + return value + + @db.indexed_property(prefix='D', full_text=True, localized=True) + def message(self, value): + return value api_url.value = 'http://127.0.0.1:9000' @@ -66,35 +80,35 @@ class SyncOnlineTest(tests.Test): self.assertEqual([[4, None]], json.load(file('slave/pull.sequence'))) self.assertEqual([[2, None]], json.load(file('slave/push.sequence'))) - guid1 = client.post(['document'], {'context': '', 'content': '1', 'title': '', 'type': 'idea'}) - guid2 = client.post(['document'], {'context': '', 'content': '2', 'title': '', 'type': 'idea'}) + guid1 = client.post(['document'], {'context': '', 'message': '1', 'title': '', 'type': 'comment'}) + guid2 = client.post(['document'], {'context': '', 'message': '2', 'title': '', 'type': 'comment'}) client.post(cmd='online-sync') self.assertEqual([ - {'guid': guid1, 'content': {'en-us': '1'}}, - {'guid': guid2, 'content': {'en-us': '2'}}, + {'guid': guid1, 'message': {'en-us': '1'}}, + {'guid': guid2, 'message': {'en-us': '2'}}, ], - [i.properties(['guid', 'content']) for i in self.master_volume['document'].find()[0]]) + [i.properties(['guid', 'message']) for i in self.master_volume['document'].find()[0]]) self.assertEqual([[6, None]], json.load(file('slave/pull.sequence'))) self.assertEqual([[4, None]], json.load(file('slave/push.sequence'))) - guid3 = client.post(['document'], {'context': '', 'content': '3', 'title': '', 'type': 'idea'}) + guid3 = client.post(['document'], {'context': '', 'message': '3', 'title': '', 'type': 'comment'}) client.post(cmd='online-sync') self.assertEqual([ - {'guid': guid1, 'content': {'en-us': '1'}}, - {'guid': guid2, 'content': {'en-us': '2'}}, - {'guid': guid3, 'content': {'en-us': '3'}}, + {'guid': guid1, 'message': {'en-us': '1'}}, + {'guid': guid2, 'message': {'en-us': '2'}}, + {'guid': guid3, 'message': {'en-us': '3'}}, ], - [i.properties(['guid', 'content']) for i in self.master_volume['document'].find()[0]]) + [i.properties(['guid', 'message']) for i in self.master_volume['document'].find()[0]]) self.assertEqual([[7, None]], json.load(file('slave/pull.sequence'))) self.assertEqual([[5, None]], json.load(file('slave/push.sequence'))) coroutine.sleep(1) - client.put(['document', guid2], {'content': '22'}) + client.put(['document', guid2], {'message': '22'}) client.post(cmd='online-sync') self.assertEqual( - {'guid': guid2, 'content': {'en-us': '22'}}, - self.master_volume['document'].get(guid2).properties(['guid', 'content'])) + {'guid': guid2, 'message': {'en-us': '22'}}, + self.master_volume['document'].get(guid2).properties(['guid', 'message'])) self.assertEqual([[8, None]], json.load(file('slave/pull.sequence'))) self.assertEqual([[6, None]], json.load(file('slave/push.sequence'))) @@ -102,28 +116,28 @@ class SyncOnlineTest(tests.Test): client.delete(['document', guid1]) client.post(cmd='online-sync') self.assertEqual([ - {'guid': guid1, 'content': {'en-us': '1'}, 'layer': ['deleted']}, - {'guid': guid2, 'content': {'en-us': '22'}, 'layer': []}, - {'guid': guid3, 'content': {'en-us': '3'}, 'layer': []}, + {'guid': guid1, 'message': {'en-us': '1'}, 'layer': ['deleted']}, + {'guid': guid2, 'message': {'en-us': '22'}, 'layer': []}, + {'guid': guid3, 'message': {'en-us': '3'}, 'layer': []}, ], - [i.properties(['guid', 'content', 'layer']) for i in self.master_volume['document'].find()[0]]) + [i.properties(['guid', 'message', 'layer']) for i in self.master_volume['document'].find()[0]]) self.assertEqual([[9, None]], json.load(file('slave/pull.sequence'))) self.assertEqual([[7, None]], json.load(file('slave/push.sequence'))) coroutine.sleep(1) - client.put(['document', guid1], {'content': 'a'}) - client.put(['document', guid2], {'content': 'b'}) - client.put(['document', guid3], {'content': 'c'}) - guid4 = client.post(['document'], {'context': '', 'content': 'd', 'title': '', 'type': 'idea'}) + client.put(['document', guid1], {'message': 'a'}) + client.put(['document', guid2], {'message': 'b'}) + client.put(['document', guid3], {'message': 'c'}) + guid4 = client.post(['document'], {'context': '', 'message': 'd', 'title': '', 'type': 'comment'}) client.delete(['document', guid2]) client.post(cmd='online-sync') self.assertEqual([ - {'guid': guid1, 'content': {'en-us': 'a'}, 'layer': ['deleted']}, - {'guid': guid2, 'content': {'en-us': 'b'}, 'layer': ['deleted']}, - {'guid': guid3, 'content': {'en-us': 'c'}, 'layer': []}, - {'guid': guid4, 'content': {'en-us': 'd'}, 'layer': []}, + {'guid': guid1, 'message': {'en-us': 'a'}, 'layer': ['deleted']}, + {'guid': guid2, 'message': {'en-us': 'b'}, 'layer': ['deleted']}, + {'guid': guid3, 'message': {'en-us': 'c'}, 'layer': []}, + {'guid': guid4, 'message': {'en-us': 'd'}, 'layer': []}, ], - [i.properties(['guid', 'content', 'layer']) for i in self.master_volume['document'].find()[0]]) + [i.properties(['guid', 'message', 'layer']) for i in self.master_volume['document'].find()[0]]) self.assertEqual([[13, None]], json.load(file('slave/pull.sequence'))) self.assertEqual([[12, None]], json.load(file('slave/push.sequence'))) @@ -144,35 +158,35 @@ class SyncOnlineTest(tests.Test): self.assertEqual([[4, None]], json.load(file('slave/pull.sequence'))) self.assertEqual([[2, None]], json.load(file('slave/push.sequence'))) - guid1 = client.post(['document'], {'context': '', 'content': '1', 'title': '', 'type': 'idea'}) - guid2 = client.post(['document'], {'context': '', 'content': '2', 'title': '', 'type': 'idea'}) + guid1 = client.post(['document'], {'context': '', 'message': '1', 'title': '', 'type': 'comment'}) + guid2 = client.post(['document'], {'context': '', 'message': '2', 'title': '', 'type': 'comment'}) slave_client.post(cmd='online-sync') self.assertEqual([ - {'guid': guid1, 'content': {'en-us': '1'}}, - {'guid': guid2, 'content': {'en-us': '2'}}, + {'guid': guid1, 'message': {'en-us': '1'}}, + {'guid': guid2, 'message': {'en-us': '2'}}, ], - [i.properties(['guid', 'content']) for i in self.slave_volume['document'].find()[0]]) + [i.properties(['guid', 'message']) for i in self.slave_volume['document'].find()[0]]) self.assertEqual([[6, None]], json.load(file('slave/pull.sequence'))) self.assertEqual([[2, None]], json.load(file('slave/push.sequence'))) - guid3 = client.post(['document'], {'context': '', 'content': '3', 'title': '', 'type': 'idea'}) + guid3 = client.post(['document'], {'context': '', 'message': '3', 'title': '', 'type': 'comment'}) slave_client.post(cmd='online-sync') self.assertEqual([ - {'guid': guid1, 'content': {'en-us': '1'}}, - {'guid': guid2, 'content': {'en-us': '2'}}, - {'guid': guid3, 'content': {'en-us': '3'}}, + {'guid': guid1, 'message': {'en-us': '1'}}, + {'guid': guid2, 'message': {'en-us': '2'}}, + {'guid': guid3, 'message': {'en-us': '3'}}, ], - [i.properties(['guid', 'content']) for i in self.slave_volume['document'].find()[0]]) + [i.properties(['guid', 'message']) for i in self.slave_volume['document'].find()[0]]) self.assertEqual([[7, None]], json.load(file('slave/pull.sequence'))) self.assertEqual([[2, None]], json.load(file('slave/push.sequence'))) coroutine.sleep(1) - client.put(['document', guid2], {'content': '22'}) + client.put(['document', guid2], {'message': '22'}) slave_client.post(cmd='online-sync') self.assertEqual( - {'guid': guid2, 'content': {'en-us': '22'}}, - self.slave_volume['document'].get(guid2).properties(['guid', 'content'])) + {'guid': guid2, 'message': {'en-us': '22'}}, + self.slave_volume['document'].get(guid2).properties(['guid', 'message'])) self.assertEqual([[8, None]], json.load(file('slave/pull.sequence'))) self.assertEqual([[2, None]], json.load(file('slave/push.sequence'))) @@ -180,28 +194,28 @@ class SyncOnlineTest(tests.Test): client.delete(['document', guid1]) slave_client.post(cmd='online-sync') self.assertEqual([ - {'guid': guid1, 'content': {'en-us': '1'}, 'layer': ['deleted']}, - {'guid': guid2, 'content': {'en-us': '22'}, 'layer': []}, - {'guid': guid3, 'content': {'en-us': '3'}, 'layer': []}, + {'guid': guid1, 'message': {'en-us': '1'}, 'layer': ['deleted']}, + {'guid': guid2, 'message': {'en-us': '22'}, 'layer': []}, + {'guid': guid3, 'message': {'en-us': '3'}, 'layer': []}, ], - [i.properties(['guid', 'content', 'layer']) for i in self.slave_volume['document'].find()[0]]) + [i.properties(['guid', 'message', 'layer']) for i in self.slave_volume['document'].find()[0]]) self.assertEqual([[9, None]], json.load(file('slave/pull.sequence'))) self.assertEqual([[2, None]], json.load(file('slave/push.sequence'))) coroutine.sleep(1) - client.put(['document', guid1], {'content': 'a'}) - client.put(['document', guid2], {'content': 'b'}) - client.put(['document', guid3], {'content': 'c'}) - guid4 = client.post(['document'], {'context': '', 'content': 'd', 'title': '', 'type': 'idea'}) + client.put(['document', guid1], {'message': 'a'}) + client.put(['document', guid2], {'message': 'b'}) + client.put(['document', guid3], {'message': 'c'}) + guid4 = client.post(['document'], {'context': '', 'message': 'd', 'title': '', 'type': 'comment'}) client.delete(['document', guid2]) slave_client.post(cmd='online-sync') self.assertEqual([ - {'guid': guid1, 'content': {'en-us': 'a'}, 'layer': ['deleted']}, - {'guid': guid2, 'content': {'en-us': 'b'}, 'layer': ['deleted']}, - {'guid': guid3, 'content': {'en-us': 'c'}, 'layer': []}, - {'guid': guid4, 'content': {'en-us': 'd'}, 'layer': []}, + {'guid': guid1, 'message': {'en-us': 'a'}, 'layer': ['deleted']}, + {'guid': guid2, 'message': {'en-us': 'b'}, 'layer': ['deleted']}, + {'guid': guid3, 'message': {'en-us': 'c'}, 'layer': []}, + {'guid': guid4, 'message': {'en-us': 'd'}, 'layer': []}, ], - [i.properties(['guid', 'content', 'layer']) for i in self.slave_volume['document'].find()[0]]) + [i.properties(['guid', 'message', 'layer']) for i in self.slave_volume['document'].find()[0]]) self.assertEqual([[14, None]], json.load(file('slave/pull.sequence'))) self.assertEqual([[2, None]], json.load(file('slave/push.sequence'))) @@ -238,20 +252,20 @@ class SyncOnlineTest(tests.Test): self.assertEqual([[4, None]], json.load(file('slave/pull.sequence'))) self.assertEqual([[2, None]], json.load(file('slave/push.sequence'))) - guid = slave.post(['document'], {'context': '', 'content': '1', 'title': '1', 'type': 'idea'}) + guid = slave.post(['document'], {'context': '', 'message': '1', 'title': '1', 'type': 'comment'}) slave.post(cmd='online-sync') coroutine.sleep(1) - master.put(['document', guid], {'content': '1_'}) + master.put(['document', guid], {'message': '1_'}) slave.put(['document', guid], {'title': '1_'}) slave.post(cmd='online-sync') self.assertEqual( - {'content': {'en-us': '1_'}, 'title': {'en-us': '1_'}}, - self.master_volume['document'].get(guid).properties(['content', 'title'])) + {'message': {'en-us': '1_'}, 'title': {'en-us': '1_'}}, + self.master_volume['document'].get(guid).properties(['message', 'title'])) self.assertEqual( - {'content': {'en-us': '1_'}, 'title': {'en-us': '1_'}}, - self.slave_volume['document'].get(guid).properties(['content', 'title'])) + {'message': {'en-us': '1_'}, 'title': {'en-us': '1_'}}, + self.slave_volume['document'].get(guid).properties(['message', 'title'])) if __name__ == '__main__': diff --git a/tests/units/node/volume.py b/tests/units/node/volume.py index fc7df1f..10a1cdd 100755 --- a/tests/units/node/volume.py +++ b/tests/units/node/volume.py @@ -364,75 +364,69 @@ class VolumeTest(tests.Test): 'summary': {'value': {}, 'mtime': 1.0}, 'description': {'value': {}, 'mtime': 1.0}, }}, - {'resource': 'artifact'}, - {'guid': 'artifact', 'diff': { - 'guid': {'value': 'artifact', 'mtime': 1.0}, + {'resource': 'post'}, + {'guid': 'topic_1', 'diff': { + 'guid': {'value': 'topic_1', 'mtime': 1.0}, 'ctime': {'value': 1, 'mtime': 1.0}, 'mtime': {'value': 1, 'mtime': 1.0}, - 'type': {'value': ['instance'], 'mtime': 1.0}, + 'type': {'value': 'object', 'mtime': 1.0}, 'context': {'value': 'context', 'mtime': 1.0}, 'title': {'value': {}, 'mtime': 1.0}, - 'description': {'value': {}, 'mtime': 1.0}, + 'message': {'value': {}, 'mtime': 1.0}, + 'solution': {'value': 'solution_1', 'mtime': 1.0}, + }}, + {'guid': 'topic_2', 'diff': { + 'guid': {'value': 'topic_2', 'mtime': 1.0}, + 'ctime': {'value': 1, 'mtime': 1.0}, + 'mtime': {'value': 1, 'mtime': 1.0}, + 'type': {'value': 'object', 'mtime': 1.0}, + 'context': {'value': 'context', 'mtime': 1.0}, + 'title': {'value': {}, 'mtime': 1.0}, + 'message': {'value': {}, 'mtime': 1.0}, + 'solution': {'value': 'solution_2', 'mtime': 1.0}, }}, - {'resource': 'review'}, {'guid': 'context_review', 'diff': { 'guid': {'value': 'context_review', 'mtime': 1.0}, 'ctime': {'value': 1, 'mtime': 1.0}, 'mtime': {'value': 1, 'mtime': 1.0}, 'context': {'value': 'context', 'mtime': 1.0}, - 'artifact': {'value': 'artifact', 'mtime': 4.0}, - 'rating': {'value': 1, 'mtime': 1.0}, + 'vote': {'value': 1, 'mtime': 1.0}, 'author': {'mtime': 1, 'value': {}}, 'layer': {'mtime': 1, 'value': []}, 'tags': {'mtime': 1, 'value': []}, + 'type': {'value': 'review', 'mtime': 1.0}, }}, - {'guid': 'artifact_review', 'diff': { - 'guid': {'value': 'artifact_review', 'mtime': 1.0}, + {'guid': 'topic_review', 'diff': { + 'guid': {'value': 'topic_review', 'mtime': 1.0}, 'ctime': {'value': 1, 'mtime': 1.0}, 'mtime': {'value': 1, 'mtime': 1.0}, 'context': {'value': 'context', 'mtime': 1.0}, - 'rating': {'value': 1, 'mtime': 1.0}, + 'topic': {'value': 'topic_1', 'mtime': 1.0}, + 'vote': {'value': 1, 'mtime': 1.0}, 'author': {'mtime': 1, 'value': {}}, 'layer': {'mtime': 1, 'value': []}, 'tags': {'mtime': 1, 'value': []}, + 'type': {'value': 'feedback', 'mtime': 1.0}, }}, - {'resource': 'feedback'}, - {'guid': 'feedback_1', 'diff': { - 'guid': {'value': 'feedback_1', 'mtime': 1.0}, - 'ctime': {'value': 1, 'mtime': 1.0}, - 'mtime': {'value': 1, 'mtime': 1.0}, - 'type': {'value': ['idea'], 'mtime': 1.0}, - 'context': {'value': 'context', 'mtime': 1.0}, - 'title': {'value': {}, 'mtime': 1.0}, - 'content': {'value': {}, 'mtime': 1.0}, - 'solution': {'value': 'solution_1', 'mtime': 1.0}, - }}, - {'guid': 'feedback_2', 'diff': { - 'guid': {'value': 'feedback_2', 'mtime': 1.0}, - 'ctime': {'value': 1, 'mtime': 1.0}, - 'mtime': {'value': 1, 'mtime': 1.0}, - 'type': {'value': ['idea'], 'mtime': 1.0}, - 'context': {'value': 'context', 'mtime': 1.0}, - 'title': {'value': {}, 'mtime': 1.0}, - 'content': {'value': {}, 'mtime': 1.0}, - 'solution': {'value': 'solution_2', 'mtime': 1.0}, - }}, - {'resource': 'solution'}, {'guid': 'solution_1', 'diff': { 'guid': {'value': 'solution_1', 'mtime': 1.0}, 'ctime': {'value': 1, 'mtime': 1.0}, 'mtime': {'value': 1, 'mtime': 1.0}, 'context': {'value': 'context', 'mtime': 1.0}, - 'feedback': {'value': 'feedback_1', 'mtime': 1.0}, - 'content': {'value': {}, 'mtime': 1.0}, + 'topic': {'value': 'topic_1', 'mtime': 1.0}, + 'type': {'value': 'answer', 'mtime': 1.0}, + 'title': {'value': {}, 'mtime': 1.0}, + 'message': {'value': {}, 'mtime': 1.0}, }}, {'guid': 'solution_2', 'diff': { 'guid': {'value': 'solution_2', 'mtime': 1.0}, 'ctime': {'value': 1, 'mtime': 1.0}, 'mtime': {'value': 1, 'mtime': 1.0}, 'context': {'value': 'context', 'mtime': 1.0}, - 'feedback': {'value': 'feedback_1', 'mtime': 1.0}, - 'content': {'value': {}, 'mtime': 1.0}, + 'topic': {'value': 'topic_2', 'mtime': 1.0}, + 'type': {'value': 'answer', 'mtime': 1.0}, + 'title': {'value': {}, 'mtime': 1.0}, + 'message': {'value': {}, 'mtime': 1.0}, }}, {'resource': 'release'}, {'guid': 'release', 'diff': { @@ -445,14 +439,6 @@ class VolumeTest(tests.Test): 'stability': {'value': 'stable', 'mtime': 1.0}, 'notes': {'value': {}, 'mtime': 1.0}, }}, - {'resource': 'comment'}, - {'guid': 'comment', 'diff': { - 'guid': {'value': 'comment', 'mtime': 1.0}, - 'ctime': {'value': 1, 'mtime': 1.0}, - 'mtime': {'value': 1, 'mtime': 1.0}, - 'context': {'value': 'context', 'mtime': 1.0}, - 'message': {'value': {}, 'mtime': 1.0}, - }}, {'commit': [[1, 1]]}, ] merge(volume, records, stats=stats) @@ -461,21 +447,9 @@ class VolumeTest(tests.Test): stats.commit_objects() self.assertEqual([ - [('comment', ts, { - 'total': 1.0, - })], - [('feedback', ts, { - 'total': 2.0, - })], - [('review', ts, { - 'total': 2.0, - })], - [('solution', ts, { - 'total': 2.0, - })], - [('artifact', ts, { + [('post', ts, { 'downloaded': 0.0, - 'total': 1.0, + 'total': 6.0, })], [('user', ts, { 'total': 0.0, @@ -488,14 +462,14 @@ class VolumeTest(tests.Test): })], ], [[(j.name,) + i for i in j.get(j.last, j.last)] for j in Rrd('stats/node', 1)]) - self.assertEqual(1, volume['artifact'].get('artifact')['rating']) - self.assertEqual([1, 1], volume['artifact'].get('artifact')['reviews']) self.assertEqual(1, volume['context'].get('context')['rating']) self.assertEqual([1, 1], volume['context'].get('context')['reviews']) + self.assertEqual(1, volume['post'].get('topic_1')['rating']) + self.assertEqual([1, 1], volume['post'].get('topic_1')['reviews']) records = [ - {'resource': 'feedback'}, - {'guid': 'feedback_2', 'diff': {'solution': {'value': '', 'mtime': 2.0}}}, + {'resource': 'post'}, + {'guid': 'topic_2', 'diff': {'solution': {'value': '', 'mtime': 2.0}}}, {'commit': [[2, 2]]}, ] merge(volume, records, stats=stats) @@ -504,21 +478,9 @@ class VolumeTest(tests.Test): stats.commit_objects() self.assertEqual([ - [('comment', ts, { - 'total': 1.0, - })], - [('feedback', ts, { - 'total': 2.0, - })], - [('review', ts, { - 'total': 2.0, - })], - [('solution', ts, { - 'total': 2.0, - })], - [('artifact', ts, { + [('post', ts, { 'downloaded': 0.0, - 'total': 1.0, + 'total': 6.0, })], [('user', ts, { 'total': 0.0, @@ -535,15 +497,11 @@ class VolumeTest(tests.Test): records = [ {'resource': 'context'}, {'guid': 'context', 'diff': {'layer': {'value': ['deleted'], 'mtime': 3.0}}}, - {'resource': 'artifact'}, - {'guid': 'artifact', 'diff': {'layer': {'value': ['deleted'], 'mtime': 3.0}}}, - {'resource': 'review'}, + {'resource': 'post'}, + {'guid': 'topic_1', 'diff': {'layer': {'value': ['deleted'], 'mtime': 3.0}}}, + {'guid': 'topic_2', 'diff': {'layer': {'value': ['deleted'], 'mtime': 3.0}}}, {'guid': 'context_review', 'diff': {'layer': {'value': ['deleted'], 'mtime': 3.0}}}, - {'guid': 'artifact_review', 'diff': {'layer': {'value': ['deleted'], 'mtime': 3.0}}}, - {'resource': 'feedback'}, - {'guid': 'feedback_1', 'diff': {'layer': {'value': ['deleted'], 'mtime': 3.0}}}, - {'guid': 'feedback_2', 'diff': {'layer': {'value': ['deleted'], 'mtime': 3.0}}}, - {'resource': 'solution'}, + {'guid': 'topic_review', 'diff': {'layer': {'value': ['deleted'], 'mtime': 3.0}}}, {'guid': 'solution_1', 'diff': {'layer': {'value': ['deleted'], 'mtime': 3.0}}}, {'guid': 'solution_2', 'diff': {'layer': {'value': ['deleted'], 'mtime': 3.0}}}, {'resource': 'release'}, @@ -556,19 +514,7 @@ class VolumeTest(tests.Test): stats.commit_objects() self.assertEqual([ - [('comment', ts, { - 'total': 1.0, - })], - [('feedback', ts, { - 'total': 0.0, - })], - [('review', ts, { - 'total': 0.0, - })], - [('solution', ts, { - 'total': 0.0, - })], - [('artifact', ts, { + [('post', ts, { 'downloaded': 0.0, 'total': 0.0, })], -- cgit v0.9.1