summaryrefslogtreecommitdiff
path: root/packages_statistics.patch
diff options
context:
space:
mode:
Diffstat (limited to 'packages_statistics.patch')
-rw-r--r--packages_statistics.patch208
1 files changed, 0 insertions, 208 deletions
diff --git a/packages_statistics.patch b/packages_statistics.patch
deleted file mode 100644
index 9560d71..0000000
--- a/packages_statistics.patch
+++ /dev/null
@@ -1,208 +0,0 @@
-diff --git a/coprs_frontend/coprs/__init__.py b/coprs_frontend/coprs/__init__.py
-index 5332f21e..652ce93a 100644
---- a/coprs_frontend/coprs/__init__.py
-+++ b/coprs_frontend/coprs/__init__.py
-@@ -94,6 +94,7 @@ cache_rcp = RedisConnectionProvider(config=app.config, db=1)
- cache = Cache(app, config={
- 'CACHE_REDIS_HOST': cache_rcp.host,
- 'CACHE_REDIS_PORT': cache_rcp.port,
-+ 'CACHE_REDIS_PASSWORD': cache_rcp.password,
- })
- app.cache = cache
-
-diff --git a/coprs_frontend/coprs/logic/packages_logic.py b/coprs_frontend/coprs/logic/packages_logic.py
-index 84f23d6e..be2b067c 100644
---- a/coprs_frontend/coprs/logic/packages_logic.py
-+++ b/coprs_frontend/coprs/logic/packages_logic.py
-@@ -1,7 +1,7 @@
- import json
- from typing import List, Optional
-
--from sqlalchemy import bindparam, Integer, func, or_
-+from sqlalchemy import bindparam, Integer, func, or_, and_
- from sqlalchemy.sql import true, text
- from sqlalchemy.orm import selectinload
-
-@@ -22,10 +22,18 @@ log = app.logger
- class PackagesLogic(object):
-
- @classmethod
-- def count(cls):
-+ def count(cls, success=True):
- """
- Get packages count
- """
-+ if success:
-+ id = "succeed_package_count"
-+ count = app.cache.get(id)
-+ if not count:
-+ count = cls.get_all_success_packages().count()
-+ app.cache.set(id, count, 3600)
-+ return count
-+
- return models.Package.query.count()
-
- @classmethod
-@@ -433,3 +441,116 @@ class PackagesLogic(object):
- user.name,
- package.name,
- package.copr.full_name)
-+
-+ @classmethod
-+ def get_all_success_packages(cls):
-+ """
-+ Get all succeed packages
-+ """
-+ copr_ids = [
-+ copr.id
-+ for copr in models.Copr.query.filter(models.Copr.deleted == False)
-+ .with_entities(models.Copr.id)
-+ .all()
-+ ]
-+
-+ pkg_ids = [
-+ pkg.id
-+ for pkg in models.Package.query.filter(models.Package.copr_id.in_(copr_ids))
-+ .with_entities(models.Package.id)
-+ .all()
-+ ]
-+
-+ pkg_ids = cls.get_packages_with_success_builds_ids(pkg_ids)
-+
-+ packages = models.Package.query.filter(
-+ and_(models.Package.id.in_(pkg_ids), models.Package.copr_id.in_(copr_ids))
-+ ).order_by(models.Package.name)
-+
-+ return packages
-+
-+ @classmethod
-+ def get_packages_with_success_builds_ids(cls, pkg_ids):
-+ """
-+ Obtain the list of package ids with the latest build assigned.
-+ Parameters:
-+
-+ :param packages: Don't query the list of Package objects from DB, but
-+ use the given 'packages' array.
-+ :return: array of Package ids, with assigned latest Build object
-+ """
-+ builds_ids = (
-+ models.Build.query.join(models.CoprDir)
-+ .filter(models.Build.package_id.in_(pkg_ids))
-+ .with_entities(func.max(models.Build.id))
-+ .group_by(models.Build.package_id)
-+ )
-+
-+ builds = (
-+ models.Build.query.filter(models.Build.id.in_(builds_ids))
-+ .options(selectinload("build_chroots"))
-+ .yield_per(1000)
-+ .all()
-+ )
-+
-+ results = []
-+ for build in builds:
-+ if build.status == StatusEnum("succeeded"):
-+ results.append(build.package_id)
-+
-+ return results
-+
-+ @classmethod
-+ def get_packages_with_succ_builds(cls, small_build=True, packages=None):
-+ """
-+ Obtain the list of package objects with the
-+ latest build assigned.
-+ Parameters:
-+
-+ :param small_build: Don't assign full Build objects, but only a limited
-+ objects with necessary info.
-+ :param packages: Don't query the list of Package objects from DB, but
-+ use the given 'packages' array.
-+ :return: array of Package objects, with assigned latest Build object
-+ """
-+ if packages is None:
-+ return
-+
-+ pkg_ids = [package.id for package in packages]
-+ builds_ids = (
-+ models.Build.query.join(models.CoprDir)
-+ .filter(models.Build.package_id.in_(pkg_ids))
-+ .with_entities(func.max(models.Build.id))
-+ .group_by(models.Build.package_id)
-+ )
-+
-+ # map package.id => package object in packages array
-+ packages_map = {package.id: package for package in packages}
-+
-+ builds = (
-+ models.Build.query.filter(models.Build.id.in_(builds_ids))
-+ .options(selectinload("build_chroots"))
-+ .yield_per(1000)
-+ )
-+
-+ for build in builds:
-+
-+ class SmallBuild:
-+ pass
-+
-+ if not build.package_id:
-+ continue
-+
-+ if small_build:
-+ small_build_object = SmallBuild()
-+ for param in ["state", "status", "pkg_version", "submitted_on"]:
-+ # we don't want to keep all the attributes here in memory, and
-+ # also we don't need any further info about assigned
-+ # build_chroot(s). So we only pick the info we need, and throw
-+ # the expensive objects away.
-+ setattr(small_build_object, param, getattr(build, param))
-+ packages_map[build.package_id].latest_build = small_build_object
-+ else:
-+ packages_map[build.package_id].latest_build = build
-+
-+ return packages
-diff --git a/coprs_frontend/coprs/views/coprs_ns/coprs_packages.py b/coprs_frontend/coprs/views/coprs_ns/coprs_packages.py
-index 527c73d1..363c532f 100644
---- a/coprs_frontend/coprs/views/coprs_ns/coprs_packages.py
-+++ b/coprs_frontend/coprs/views/coprs_ns/coprs_packages.py
-@@ -23,6 +23,7 @@ from coprs.views.misc import (
- from coprs.logic.complex_logic import ComplexLogic
- from coprs.logic.packages_logic import PackagesLogic
- from coprs.logic.users_logic import UsersLogic
-+from coprs.logic.coprs_logic import CoprsLogic
- from coprs.exceptions import (ActionInProgressException, ObjectNotFound, NoPackageSourceException,
- InsufficientRightsException, MalformedArgumentException)
-
-@@ -322,3 +323,32 @@ def copr_delete_package(copr, package_id):
- flask.flash("Package has been deleted successfully.")
-
- return flask.redirect(helpers.copr_url("coprs_ns.copr_packages", copr))
-+
-+
-+@coprs_ns.route("/packages_statistics")
-+@req_with_pagination
-+def packages_statistics(page=1):
-+ flashes = flask.session.pop('_flashes', [])
-+ query_packages = PackagesLogic.get_all_success_packages()
-+
-+ count = query_packages.count()
-+
-+ pagination = None
-+ if query_packages.count() > 1000:
-+ pagination = query_packages.paginate(page=page, per_page=50)
-+ packages = pagination.items
-+ else:
-+ packages = query_packages.all()
-+
-+ packages = PackagesLogic.get_packages_with_succ_builds(packages=packages)
-+
-+ response = flask.Response(
-+ stream_with_context(helpers.stream_template(
-+ "coprs/show/package_statistics.html",
-+ packages=packages,
-+ flashes=flashes,
-+ serverside_pagination=pagination,
-+ count=count,
-+ )))
-+ flask.session.pop('_flashes', [])
-+ return response
-\ No newline at end of file