mirror of
https://github.com/minetest/contentdb.git
synced 2024-11-09 17:13:45 +01:00
Add per-package download tracking
This commit is contained in:
parent
02ef7e09e4
commit
d11d638144
@ -114,6 +114,9 @@ def download_release(package, id):
|
|||||||
|
|
||||||
ip = request.headers.get("X-Forwarded-For") or request.remote_addr
|
ip = request.headers.get("X-Forwarded-For") or request.remote_addr
|
||||||
if ip is not None and not is_user_bot():
|
if ip is not None and not is_user_bot():
|
||||||
|
is_minetest = (request.headers.get("User-Agent") or "").startswith("Minetest")
|
||||||
|
PackageDailyStats.update(package, is_minetest, request.args.get("reason"))
|
||||||
|
|
||||||
key = make_download_key(ip, release.package)
|
key = make_download_key(ip, release.package)
|
||||||
if not has_key(key):
|
if not has_key(key):
|
||||||
set_key(key, "true")
|
set_key(key, "true")
|
||||||
@ -130,7 +133,7 @@ def download_release(package, id):
|
|||||||
"score": Package.score + bonus
|
"score": Package.score + bonus
|
||||||
})
|
})
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
return redirect(release.url)
|
return redirect(release.url)
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ from flask_babel import lazy_gettext
|
|||||||
from flask_sqlalchemy import BaseQuery
|
from flask_sqlalchemy import BaseQuery
|
||||||
from sqlalchemy_searchable import SearchQueryMixin
|
from sqlalchemy_searchable import SearchQueryMixin
|
||||||
from sqlalchemy_utils.types import TSVectorType
|
from sqlalchemy_utils.types import TSVectorType
|
||||||
|
from sqlalchemy.dialects.postgresql import insert
|
||||||
|
|
||||||
from . import db
|
from . import db
|
||||||
from .users import Permission, UserRank, User
|
from .users import Permission, UserRank, User
|
||||||
@ -1200,3 +1201,49 @@ class PackageAlias(db.Model):
|
|||||||
|
|
||||||
def getAsDictionary(self):
|
def getAsDictionary(self):
|
||||||
return f"{self.author}/{self.name}"
|
return f"{self.author}/{self.name}"
|
||||||
|
|
||||||
|
|
||||||
|
class PackageDailyStats(db.Model):
|
||||||
|
package_id = db.Column(db.Integer, db.ForeignKey("package.id"), primary_key=True)
|
||||||
|
package = db.relationship("Package", foreign_keys=[package_id])
|
||||||
|
date = db.Column(db.Date, primary_key=True)
|
||||||
|
|
||||||
|
platform_minetest = db.Column(db.Integer, nullable=False, default=0)
|
||||||
|
platform_other = db.Column(db.Integer, nullable=False, default=0)
|
||||||
|
|
||||||
|
reason_new = db.Column(db.Integer, nullable=False, default=0)
|
||||||
|
reason_dependency = db.Column(db.Integer, nullable=False, default=0)
|
||||||
|
reason_update = db.Column(db.Integer, nullable=False, default=0)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def update(package: Package, is_minetest: bool, reason: str):
|
||||||
|
date = datetime.date.today()
|
||||||
|
to_update = dict()
|
||||||
|
kwargs = {
|
||||||
|
"package_id": package.id, "date": date
|
||||||
|
}
|
||||||
|
|
||||||
|
field_platform = "platform_minetest" if is_minetest else "platform_other"
|
||||||
|
to_update[field_platform] = getattr(PackageDailyStats, field_platform) + 1
|
||||||
|
kwargs[field_platform] = 1
|
||||||
|
|
||||||
|
field_reason = None
|
||||||
|
if reason == "new":
|
||||||
|
field_reason = "reason_new"
|
||||||
|
elif reason == "dep":
|
||||||
|
field_reason = "reason_dependency"
|
||||||
|
elif reason == "update":
|
||||||
|
field_reason = "./reason_update"
|
||||||
|
|
||||||
|
if field_reason:
|
||||||
|
to_update[field_reason] = getattr(PackageDailyStats, field_reason) + 1
|
||||||
|
kwargs[field_reason] = 1
|
||||||
|
|
||||||
|
stmt = insert(PackageDailyStats).values(**kwargs)
|
||||||
|
stmt = stmt.on_conflict_do_update(
|
||||||
|
index_elements=[PackageDailyStats.package_id, PackageDailyStats.date],
|
||||||
|
set_=to_update
|
||||||
|
)
|
||||||
|
|
||||||
|
conn = db.session.connection()
|
||||||
|
conn.execute(stmt)
|
||||||
|
5
app/tests/unit/test_utils.py
Normal file
5
app/tests/unit/test_utils.py
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import user_agents
|
||||||
|
|
||||||
|
|
||||||
|
def test_minetest_is_not_bot():
|
||||||
|
assert not user_agents.parse("Minetest/5.5.1 (Linux/4.14.193+-ab49821 aarch64)").is_bot
|
34
migrations/versions/ea83ce985e55_.py
Normal file
34
migrations/versions/ea83ce985e55_.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
"""empty message
|
||||||
|
|
||||||
|
Revision ID: ea83ce985e55
|
||||||
|
Revises: 16eb610b7751
|
||||||
|
Create Date: 2022-11-05 22:09:50.875158
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy.dialects import postgresql
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = 'ea83ce985e55'
|
||||||
|
down_revision = '16eb610b7751'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
op.create_table('package_daily_stats',
|
||||||
|
sa.Column('package_id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('date', sa.Date(), nullable=False),
|
||||||
|
sa.Column('platform_minetest', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('platform_other', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('reason_new', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('reason_dependency', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('reason_update', sa.Integer(), nullable=False),
|
||||||
|
sa.ForeignKeyConstraint(['package_id'], ['package.id'], ),
|
||||||
|
sa.PrimaryKeyConstraint('package_id', 'date')
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
op.drop_table('package_daily_stats')
|
Loading…
Reference in New Issue
Block a user