Improve package scoring

This commit is contained in:
rubenwardy 2019-11-21 22:16:35 +00:00 committed by GitHub
parent 94426e97aa
commit 33b2b38308
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 55 additions and 13 deletions

@ -75,7 +75,7 @@ def admin_page():
return redirect(url_for("admin.admin_page")) return redirect(url_for("admin.admin_page"))
elif action == "recalcscores": elif action == "recalcscores":
for p in Package.query.all(): for p in Package.query.all():
p.recalcScore() p.setStartScore()
db.session.commit() db.session.commit()
return redirect(url_for("admin.admin_page")) return redirect(url_for("admin.admin_page"))

@ -130,9 +130,18 @@ def download_release(package, id):
if not has_key(key): if not has_key(key):
set_key(key, "true") set_key(key, "true")
bonus = 1
if not package.getIsFOSS():
bonus *= 0.1
PackageRelease.query.filter_by(id=release.id).update({ PackageRelease.query.filter_by(id=release.id).update({
"downloads": PackageRelease.downloads + 1 "downloads": PackageRelease.downloads + 1
}) })
Package.query.filter_by(id=package.id).update({
"score": Package.score + bonus
})
db.session.commit() db.session.commit()
return redirect(release.url, code=300) return redirect(release.url, code=300)

@ -24,6 +24,7 @@ from flask import Flask, url_for
from flask_sqlalchemy import SQLAlchemy, BaseQuery from flask_sqlalchemy import SQLAlchemy, BaseQuery
from flask_migrate import Migrate from flask_migrate import Migrate
from flask_user import login_required, UserManager, UserMixin, SQLAlchemyAdapter from flask_user import login_required, UserManager, UserMixin, SQLAlchemyAdapter
from sqlalchemy import func
from sqlalchemy.orm import validates from sqlalchemy.orm import validates
from sqlalchemy_searchable import SearchQueryMixin from sqlalchemy_searchable import SearchQueryMixin
from sqlalchemy_utils.types import TSVectorType from sqlalchemy_utils.types import TSVectorType
@ -425,6 +426,9 @@ class Package(db.Model):
for e in PackagePropertyKey: for e in PackagePropertyKey:
setattr(self, e.name, getattr(package, e.name)) setattr(self, e.name, getattr(package, e.name))
def getIsFOSS(self):
return self.license.is_foss and self.media_license.is_foss
def getState(self): def getState(self):
if self.approved: if self.approved:
return "approved" return "approved"
@ -602,16 +606,20 @@ class Package(db.Model):
else: else:
raise Exception("Permission {} is not related to packages".format(perm.name)) raise Exception("Permission {} is not related to packages".format(perm.name))
def recalcScore(self): def setStartScore(self):
self.score = 10 downloads = db.session.query(func.sum(PackageRelease.downloads)). \
filter(PackageRelease.package_id == self.id).scalar() or 0
if self.forums is not None: forum_score = 0
topic = ForumTopic.query.get(self.forums) forum_bonus = 0
topic = self.forums and ForumTopic.query.get(self.forums)
if topic: if topic:
days = (datetime.datetime.now() - topic.created_at).days months = (datetime.datetime.now() - topic.created_at).days / 30
months = days / 30 years = months / 12
years = days / 365 forum_score = topic.views / max(years, 0.0416) + 80*min(max(months, 0.5), 6)
self.score = topic.views / max(years, 0.0416) + 80*min(max(months, 0.5), 6) forum_bonus = topic.views + topic.posts
self.score = max(downloads, forum_score * 0.6) + forum_bonus
if self.getMainScreenshotURL() is None: if self.getMainScreenshotURL() is None:
self.score *= 0.8 self.score *= 0.8
@ -619,6 +627,7 @@ class Package(db.Model):
if not self.license.is_foss or not self.media_license.is_foss: if not self.license.is_foss or not self.media_license.is_foss:
self.score *= 0.1 self.score *= 0.1
class MetaPackage(db.Model): class MetaPackage(db.Model):
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), unique=True, nullable=False) name = db.Column(db.String(100), unique=True, nullable=False)

@ -69,6 +69,10 @@ CELERYBEAT_SCHEDULE = {
'topic_list_import': { 'topic_list_import': {
'task': 'app.tasks.forumtasks.importTopicList', 'task': 'app.tasks.forumtasks.importTopicList',
'schedule': crontab(minute=1, hour=1), 'schedule': crontab(minute=1, hour=1),
},
'package_score_update': {
'task': 'app.tasks.pkgtasks.updatePackageScores',
'schedule': crontab(minute=10, hour=1),
} }
} }
celery.conf.beat_schedule = CELERYBEAT_SCHEDULE celery.conf.beat_schedule = CELERYBEAT_SCHEDULE

@ -171,7 +171,4 @@ def importTopicList():
topic.views = int(info["views"]) topic.views = int(info["views"])
topic.created_at = info["date"] topic.created_at = info["date"]
for p in Package.query.all():
p.recalcScore()
db.session.commit() db.session.commit()

23
app/tasks/pkgtasks.py Normal file

@ -0,0 +1,23 @@
# Content DB
# Copyright (C) 2018 rubenwardy
#
# 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 <https://www.gnu.org/licenses/>.
from app.models import Package, PackageRelease
from app.tasks import celery
@celery.task()
def updatePackageScores():
Package.query.update({ "score": PackageRelease.score * 0.8 })