From b33f268b27b907d95b08a7a861bb64e78f8f1b1f Mon Sep 17 00:00:00 2001 From: Adabriand Furtado Date: Fri, 1 Jul 2016 22:47:00 -0300 Subject: [PATCH] Oculta projetos de acordo com o perfil. --- pybossa/api/api_base.py | 4 ++-- pybossa/api/user.py | 7 +++++-- pybossa/cache/projects.py | 33 ++++++++++++++++++++++++--------- pybossa/cache/users.py | 13 ++++--------- pybossa/core.py | 1 + pybossa/default_settings.py | 7 ++----- pybossa/view/projects.py | 8 ++++++-- 7 files changed, 44 insertions(+), 29 deletions(-) diff --git a/pybossa/api/api_base.py b/pybossa/api/api_base.py index 1bb4d7d..4c082a5 100644 --- a/pybossa/api/api_base.py +++ b/pybossa/api/api_base.py @@ -166,9 +166,9 @@ class APIBase(MethodView): def _set_limit_and_offset(self): try: - limit = min(100, int(request.args.get('limit'))) + limit = min(ratelimits.get('RETRIEVE_LIMIT'), int(request.args.get('limit'))) except (ValueError, TypeError): - limit = 20 + limit = ratelimits.get('RETRIEVE_LIMIT') try: offset = int(request.args.get('offset')) except (ValueError, TypeError): diff --git a/pybossa/api/user.py b/pybossa/api/user.py index 0e0c8ed..2ea76ca 100644 --- a/pybossa/api/user.py +++ b/pybossa/api/user.py @@ -47,7 +47,7 @@ class UserAPI(APIBase): # Attributes that are visible only for admins or everyone if the user # has privacy_mode disabled - allowed_attributes = ('name', 'locale', 'fullname', 'created') + allowed_attributes = ('name', 'locale', 'fullname', 'created', 'info') def _select_attributes(self, user_data): privacy = self._is_user_private(user_data) @@ -64,7 +64,10 @@ class UserAPI(APIBase): privacy and attribute not in self.public_attributes) def _is_user_private(self, user): - return not self._is_requester_admin() and user['privacy_mode'] + return not self._is_requesting_own_data(user) and not self._is_requester_admin() and user['privacy_mode'] + + def _is_requesting_own_data(self, user): + return current_user.is_authenticated() and current_user.name == user['name'] def _is_requester_admin(self): return current_user.is_authenticated() and current_user.admin diff --git a/pybossa/cache/projects.py b/pybossa/cache/projects.py index f5b7ba3..809f2ce 100644 --- a/pybossa/cache/projects.py +++ b/pybossa/cache/projects.py @@ -19,6 +19,7 @@ from sqlalchemy.sql import text from pybossa.core import db, timeouts from pybossa.model.project import Project +from pybossa.model.profile import Profile from pybossa.util import pretty_date from pybossa.cache import memoize, cache, delete_memoized, delete_cached @@ -203,7 +204,6 @@ def last_activity(project_id): else: # pragma: no cover return None - def project_last_answers_data(project_id): """Return last answers from a project.""" sql = text(''' @@ -266,7 +266,7 @@ def _n_featured(): # This function does not change too much, so cache it for a longer time @memoize(timeout=timeouts.get('STATS_FRONTPAGE_TIMEOUT')) -def get_all_featured(category=None): +def get_all_featured(category=None, profile=None): """Return a list of featured projects with a pagination.""" sql = text( '''SELECT project.id, project.name, project.short_name, project.info, @@ -326,7 +326,7 @@ def _n_draft(): @memoize(timeout=timeouts.get('STATS_FRONTPAGE_TIMEOUT')) -def get_all_draft(category=None): +def get_all_draft(category=None, profile=None): """Return list of all draft projects.""" sql = text( '''SELECT project.id, project.name, project.short_name, project.created, @@ -361,12 +361,19 @@ def get_draft(category=None, page=1, per_page=5): @memoize(timeout=timeouts.get('N_APPS_PER_CATEGORY_TIMEOUT')) -def n_count(category): +def n_count(category, profile=None): """Count the number of projects in a given category.""" if category == 'featured': return _n_featured() if category == 'draft': return _n_draft() + + filter_by_profile = '' + access = None + if profile is not None: + access = profile.access + filter_by_profile = '''AND project.short_name = ANY (:access)''' + sql = text(''' WITH uniq AS ( SELECT COUNT(project.id) FROM project @@ -375,11 +382,12 @@ def n_count(category): category.short_name=:category AND project.published=true AND (project.info->>'passwd_hash') IS NULL + %s GROUP BY project.id) SELECT COUNT(*) FROM uniq - ''') + ''' % (filter_by_profile)) - results = session.execute(sql, dict(category=category)) + results = session.execute(sql, dict(category=category, access=access)) count = 0 for row in results: count = row[0] @@ -387,7 +395,13 @@ def n_count(category): @memoize(timeout=timeouts.get('APP_TIMEOUT')) -def get_all(category): +def get_all(category, profile=None): + filter_by_profile = '' + access = None + if profile is not None: + access = profile.access + filter_by_profile = '''AND project.short_name = ANY (:access)''' + """Return a list of published projects for a given category. """ sql = text( @@ -401,9 +415,10 @@ def get_all(category): AND "user".id=project.owner_id AND project.published=true AND (project.info->>'passwd_hash') IS NULL - GROUP BY project.id, "user".id ORDER BY project.name;''') + %s + GROUP BY project.id, "user".id ORDER BY project.name;''' % (filter_by_profile)) - results = session.execute(sql, dict(category=category)) + results = session.execute(sql, dict(category=category, access=access)) projects = [] for row in results: project = dict(id=row.id, diff --git a/pybossa/cache/users.py b/pybossa/cache/users.py index 1b66cfa..7303387 100644 --- a/pybossa/cache/users.py +++ b/pybossa/cache/users.py @@ -74,8 +74,7 @@ def get_user_leaderboard_data(user_id, project_id=None): SELECT user_id, COUNT(*) AS score FROM task_run WHERE user_id IS NOT NULL %s GROUP BY user_id) - SELECT user_id, score, rank() OVER - (ORDER BY score desc) + SELECT user_id, score, dense_rank() OVER (ORDER BY score desc) AS rank FROM scores) SELECT rank, id, name, fullname, email_addr, info, created, score FROM global_rank @@ -115,7 +114,7 @@ def get_leaderboard_by_project_id(project_id, n=None, user_id=None): WITH scores AS ( SELECT user_id, COUNT(*) AS score FROM task_run WHERE user_id IS NOT NULL AND task_run.project_id =:project_id GROUP BY user_id) - SELECT user_id, score, rank() OVER (ORDER BY score desc) + SELECT user_id, score, dense_rank() OVER (ORDER BY score desc) AS rank FROM scores) SELECT rank, id, name, fullname, score FROM global_rank JOIN public."user" on (user_id=public."user".id) ORDER BY rank @@ -151,13 +150,9 @@ def get_complete_leaderboard(n=None, user_id=None): SELECT id, short_name FROM project ''') results = session.execute(sql) - - complete_leaderboard = [] + complete_leaderboard = dict() for row in results: - leaderboard = dict() - leaderboard['project_name'] = row.short_name - leaderboard['leaderboard'] = get_leaderboard_by_project_id(row.id, n, user_id) - complete_leaderboard.append(leaderboard) + complete_leaderboard[row.short_name] = get_leaderboard_by_project_id(row.id, n, user_id) return complete_leaderboard diff --git a/pybossa/core.py b/pybossa/core.py index ca7b758..f5d380e 100644 --- a/pybossa/core.py +++ b/pybossa/core.py @@ -551,6 +551,7 @@ def setup_ratelimits(app): global ratelimits ratelimits['LIMIT'] = app.config['LIMIT'] ratelimits['PER'] = app.config['PER'] + ratelimits['RETRIEVE_LIMIT'] = app.config['RETRIEVE_LIMIT'] def setup_cache_timeouts(app): diff --git a/pybossa/default_settings.py b/pybossa/default_settings.py index deda8c1..c2ba738 100644 --- a/pybossa/default_settings.py +++ b/pybossa/default_settings.py @@ -94,10 +94,6 @@ TEMPLATE_TASKS = { 'map': "https://docs.google.com/spreadsheet/ccc?key=0AsNlt0WgPAHwdGZnbjdwcnhKRVNlN1dGXy0tTnNWWXc&usp=sharing", 'pdf': "https://docs.google.com/spreadsheet/ccc?key=0AsNlt0WgPAHwdEVVamc0R0hrcjlGdXRaUXlqRXlJMEE&usp=sharing"} -# Rate limits default values -LIMIT = 300 -PER = 15 * 60 - # Expiration time for password protected project cookies PASSWD_COOKIE_TIMEOUT = 60 * 30 @@ -105,8 +101,9 @@ PASSWD_COOKIE_TIMEOUT = 60 * 30 ACCOUNT_LINK_EXPIRATION = 5 * 60 * 60 # Rate limits default values -LIMIT = 300 +LIMIT = 600 PER = 15 * 60 +RETRIEVE_LIMIT = 300 # Disable new account confirmation (via email) ACCOUNT_CONFIRMATION_DISABLED = True diff --git a/pybossa/view/projects.py b/pybossa/view/projects.py index 4c6b820..8638f26 100644 --- a/pybossa/view/projects.py +++ b/pybossa/view/projects.py @@ -150,11 +150,15 @@ def project_index(page, lookup, category, fallback, use_count): per_page = current_app.config['APPS_PER_PAGE'] - ranked_projects = rank(lookup(category)) + profile = None + if current_user.is_authenticated() and not current_user.admin: + profile = user_repo.get_profile(current_user.profile_id) + + ranked_projects = rank(lookup(category, profile)) offset = (page - 1) * per_page projects = ranked_projects[offset:offset+per_page] - count = cached_projects.n_count(category) + count = cached_projects.n_count(category, profile) data = [] -- libgit2 0.21.2