Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/sugar_network
diff options
context:
space:
mode:
authorAleksey Lim <alsroot@sugarlabs.org>2014-02-02 09:29:43 (GMT)
committer Aleksey Lim <alsroot@sugarlabs.org>2014-02-02 09:29:43 (GMT)
commit726ac1d66321ee7ac6b4cc7eff17001b5aeb6c5e (patch)
tree76416a704a112f70b9f8ce73833054ddd55a680f /sugar_network
parentde24419942178dbf17acd9311d0c0edf8d49be17 (diff)
Smplify raiting resource property
Diffstat (limited to 'sugar_network')
-rw-r--r--sugar_network/db/index.py16
-rw-r--r--sugar_network/db/metadata.py148
-rw-r--r--sugar_network/model/context.py17
-rw-r--r--sugar_network/model/post.py11
-rw-r--r--sugar_network/node/stats_node.py13
5 files changed, 72 insertions, 133 deletions
diff --git a/sugar_network/db/index.py b/sugar_network/db/index.py
index 824423a..aa75f80 100644
--- a/sugar_network/db/index.py
+++ b/sugar_network/db/index.py
@@ -201,7 +201,7 @@ class IndexReader(object):
parser.add_prefix(name, prop.prefix)
parser.add_prefix('', prop.prefix)
if prop.slot is not None and \
- prop.typecast in [int, float, bool]:
+ prop.sortable_serialise is not None:
value_range = xapian.NumberValueRangeProcessor(
prop.slot, name + ':')
parser.add_valuerangeprocessor(value_range)
@@ -359,14 +359,14 @@ class IndexWriter(IndexReader):
else properties.get(name, prop.default)
if prop.slot is not None:
- if prop.typecast in [int, float, bool]:
- value_ = xapian.sortable_serialise(value)
+ if prop.sortable_serialise is not None:
+ slotted_value = xapian.sortable_serialise(
+ prop.sortable_serialise(value))
+ elif prop.localized:
+ slotted_value = toolkit.gettext(value) or ''
else:
- if prop.localized:
- value_ = toolkit.gettext(value) or ''
- else:
- value_ = next(_fmt_prop_value(prop, value))
- document.add_value(prop.slot, value_)
+ slotted_value = next(_fmt_prop_value(prop, value))
+ document.add_value(prop.slot, slotted_value)
if prop.prefix or prop.full_text:
for value_ in _fmt_prop_value(prop, value):
diff --git a/sugar_network/db/metadata.py b/sugar_network/db/metadata.py
index d22bb6f..7cba5ce 100644
--- a/sugar_network/db/metadata.py
+++ b/sugar_network/db/metadata.py
@@ -116,67 +116,47 @@ class Property(object):
"""Basic class to collect information about document property."""
def __init__(self, name, acl=ACL.PUBLIC, typecast=None,
- parse=None, fmt=None, default=None):
+ parse=None, fmt=None, default=None, sortable_serialise=None):
+ """
+ :param name:
+ property name;
+ :param acl:
+ access to the property,
+ might be an ORed composition of `db.ACCESS_*` constants;
+ :param typecast:
+ cast property value before storing in the system;
+ supported values are `None` (strings), `int` (intergers),
+ `float` (floats), `bool` (booleans repesented by symbols
+ `0` and `1`), a sequence of strings (property value should
+ confirm one of values from the sequencei);
+ :param parse:
+ parse property value from a string;
+ :param fmt:
+ format property value to a string or a list of strings;
+ :param default:
+ default property value or None;
+ :param sortable_serialise:
+ cast property value before storing as a srotable value.
+
+ """
if typecast is bool:
if fmt is None:
fmt = lambda x: '1' if x else '0'
if parse is None:
parse = lambda x: str(x).lower() in ('true', '1', 'on', 'yes')
+ if sortable_serialise is None and typecast in [int, float, bool]:
+ sortable_serialise = typecast
+
self.setter = None
self.on_get = lambda self, x: x
self.on_set = None
- self._name = name
- self._acl = acl
- self._typecast = typecast
- self._parse = parse
- self._fmt = fmt
- self._default = default
-
- @property
- def name(self):
- """Property name."""
- return self._name
-
- @property
- def acl(self):
- """Specify access to the property.
-
- Value might be ORed composition of `db.ACCESS_*`
- constants.
-
- """
- return self._acl
-
- @property
- def typecast(self):
- """Cast property value before storing in the system.
-
- Supported values are:
-
- * `None`, string values
- * `int`, interger values
- * `float`, float values
- * `bool`, boolean values repesented by symbols `0` and `1`
- * sequence of strings, property value should confirm one of values
- from the sequence
-
- """
- return self._typecast
-
- @property
- def parse(self):
- """Parse property value from a string."""
- return self._parse
-
- @property
- def fmt(self):
- """Format property value to a string or a list of strings."""
- return self._fmt
-
- @property
- def default(self):
- """Default property value or None."""
- return self._default
+ self.name = name
+ self.acl = acl
+ self.typecast = typecast
+ self.parse = parse
+ self.fmt = fmt
+ self.default = default
+ self.sortable_serialise = sortable_serialise
def assert_access(self, mode):
"""Is access to the property permitted.
@@ -200,11 +180,13 @@ class StoredProperty(Property):
def __init__(self, name, localized=False, typecast=None, fmt=None,
**kwargs):
"""
+ :param: localized:
+ property value will be stored per locale;
:param: **kwargs
:class:`.Property` arguments
"""
- self._localized = localized
+ self.localized = localized
if localized:
enforce(typecast is None,
@@ -216,11 +198,6 @@ class StoredProperty(Property):
Property.__init__(self, name, typecast=typecast, fmt=fmt, **kwargs)
- @property
- def localized(self):
- """Property value will be stored per locale."""
- return self._localized
-
class IndexedProperty(StoredProperty):
"""Property which needs to be indexed."""
@@ -228,6 +205,14 @@ class IndexedProperty(StoredProperty):
def __init__(self, name, slot=None, prefix=None, full_text=False,
boolean=False, **kwargs):
"""
+ :param slot:
+ Xapian document's slot number to add property value to;
+ :param prefix:
+ Xapian serach term prefix, if `None`, property is not a term;
+ :param full_text:
+ property takes part in full-text search;
+ :param boolean:
+ Xapian will use boolean search for this property;
:param: **kwargs
:class:`.StoredProperty` arguments
@@ -242,35 +227,16 @@ class IndexedProperty(StoredProperty):
'For %r property, either slot, prefix or full_text '
'need to be set',
name)
- enforce(slot is None or _is_sloted_prop(kwargs.get('typecast')),
+ enforce(slot is None or _is_sloted_prop(kwargs.get('typecast')) or
+ kwargs.get('sortable_serialise'),
'Slot can be set only for properties for str, int, float, '
'bool types, or, for list of these types')
StoredProperty.__init__(self, name, **kwargs)
- self._slot = slot
- self._prefix = prefix
- self._full_text = full_text
- self._boolean = boolean
-
- @property
- def slot(self):
- """Xapian document's slot number to add property value to."""
- return self._slot
-
- @property
- def prefix(self):
- """Xapian serach term prefix, if `None`, property is not a term."""
- return self._prefix
-
- @property
- def full_text(self):
- """Property takes part in full-text search."""
- return self._full_text
-
- @property
- def boolean(self):
- """Xapian will use boolean search for this property."""
- return self._boolean
+ self.slot = slot
+ self.prefix = prefix
+ self.full_text = full_text
+ self.boolean = boolean
class BlobProperty(Property):
@@ -279,21 +245,15 @@ class BlobProperty(Property):
def __init__(self, name, acl=ACL.PUBLIC,
mime_type='application/octet-stream'):
"""
+ :param mime_type:
+ MIME type for BLOB content;
+ by default, MIME type is application/octet-stream;
:param: **kwargs
:class:`.Property` arguments
"""
Property.__init__(self, name, acl=acl)
- self._mime_type = mime_type
-
- @property
- def mime_type(self):
- """MIME type for BLOB content.
-
- By default, MIME type is application/octet-stream.
-
- """
- return self._mime_type
+ self.mime_type = mime_type
def _is_sloted_prop(typecast):
diff --git a/sugar_network/model/context.py b/sugar_network/model/context.py
index 872d74d..85d9be8 100644
--- a/sugar_network/model/context.py
+++ b/sugar_network/model/context.py
@@ -115,25 +115,12 @@ class Context(db.Resource):
def downloads(self, value):
return value
- @db.indexed_property(slot=3, typecast=model.RATINGS, default=0,
+ @db.indexed_property(slot=3, typecast=[], default=[0, 0],
+ sortable_serialise=lambda x: float(x[1]) / x[0] if x[0] else 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]
-
- @reviews.setter
- def reviews(self, value):
- if isinstance(value, int):
- return [value, 0]
- else:
- return value
-
@db.stored_property(typecast=[], default=[], acl=ACL.PUBLIC | ACL.LOCAL)
def dependencies(self, value):
"""Software dependencies.
diff --git a/sugar_network/model/post.py b/sugar_network/model/post.py
index d7a742c..602ad02 100644
--- a/sugar_network/model/post.py
+++ b/sugar_network/model/post.py
@@ -79,15 +79,8 @@ class Post(db.Resource):
def downloads(self, value):
return value
- @db.indexed_property(slot=3, typecast=model.RATINGS, default=0,
+ @db.indexed_property(slot=3, typecast=[], default=[0, 0],
+ sortable_serialise=lambda x: float(x[1]) / x[0] if x[0] else 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/node/stats_node.py b/sugar_network/node/stats_node.py
index ed2c0bd..d37819b 100644
--- a/sugar_network/node/stats_node.py
+++ b/sugar_network/node/stats_node.py
@@ -118,7 +118,7 @@ class Sniffer(object):
for resource, stats in self._stats.items():
old = {
'downloads': 0,
- 'reviews': (0, 0),
+ 'rating': (0, 0),
}
directory = self._volume[resource]
for guid, new in stats.objects.items():
@@ -131,12 +131,11 @@ class Sniffer(object):
patch = {}
if 'downloads' in new:
patch['downloads'] = new['downloads'] + old['downloads']
- if 'reviews' in new:
- reviews, rating = old['reviews']
- reviews += new['reviews']
+ if 'votes' in new:
+ votes, rating = old['rating']
+ votes += new['votes']
rating += new['rating']
- patch['reviews'] = [reviews, rating]
- patch['rating'] = int(round(float(rating) / reviews))
+ patch['rating'] = [votes, rating]
directory.update(guid, patch)
stats.objects.clear()
@@ -296,7 +295,7 @@ class _PostStats(_ResourceStats):
stats = self._stats['post']
guid = request.content['topic']
if stats:
- stats.inc(guid, 'reviews')
+ stats.inc(guid, 'votes')
stats.inc(guid, 'rating', request.content.get('vote') or 0)
elif request.method == 'GET' and request.prop == 'data':