Permalink
Fetching contributors…
Cannot retrieve contributors at this time
64 lines (54 sloc) 2.4 KB
from __future__ import division, unicode_literals
from re import sub, split
from django.conf import settings
from django.utils.timezone import now
def order_by_score(queryset, score_fields, date_field, reverse=True):
"""
Take some queryset (links or comments) and order them by score,
which is basically "rating_sum / age_in_seconds ^ scale", where
scale is a constant that can be used to control how quickly scores
reduce over time. To perform this in the database, it needs to
support a POW function, which Postgres and MySQL do. For databases
that don't such as SQLite, we perform the scoring/sorting in
memory, which will suffice for development.
"""
scale = getattr(settings, "SCORE_SCALE_FACTOR", 2)
# Timestamp SQL function snippets mapped to DB backends.
# Defining these assumes the SQL functions POW() and NOW()
# are available for the DB backend.
timestamp_sqls = {
"mysql": "UNIX_TIMESTAMP(%s)",
"postgresql_psycopg2": "EXTRACT(EPOCH FROM %s)" ,
}
now_tz_sqls = {
"mysql": "UTC_TIMESTAMP()",
"postgresql_psycopg2": "NOW() AT TIME ZONE 'utc'",
}
db_engine = settings.DATABASES[queryset.db]["ENGINE"].rsplit(".", 1)[1]
timestamp_sql = timestamp_sqls.get(db_engine)
now_sql = now_tz_sqls.get(db_engine) if settings.USE_TZ else "NOW()",
if timestamp_sql and now_sql:
score_sql = "(%s) / POW(%s - %s, %s)" % (
" + ".join(score_fields),
timestamp_sql % now_sql,
timestamp_sql % date_field,
scale,
)
order_by = "-score" if reverse else "score"
return queryset.extra(select={"score": score_sql}).order_by(order_by)
else:
for obj in queryset:
age = (now() - getattr(obj, date_field)).total_seconds()
score_fields_sum = sum([getattr(obj, f) for f in score_fields])
score = score_fields_sum / pow(age, scale)
setattr(obj, "score", score)
return sorted(queryset, key=lambda obj: obj.score, reverse=reverse)
def auto_tag(link_obj):
"""
Split's the link object's title into words. Default function for the
``AUTO_TAG_FUNCTION`` setting.
"""
variations = lambda word: [word,
sub("^([^A-Za-z0-9])*|([^A-Za-z0-9]|s)*$", "", word),
sub("^([^A-Za-z0-9])*|([^A-Za-z0-9])*$", "", word)]
return sum(map(variations, split("\s|/", link_obj.title)), [])