Commit b33f268b27b907d95b08a7a861bb64e78f8f1b1f
1 parent
368d79e5
Exists in
master
Oculta projetos de acordo com o perfil.
Showing
7 changed files
with
44 additions
and
29 deletions
Show diff stats
pybossa/api/api_base.py
| @@ -166,9 +166,9 @@ class APIBase(MethodView): | @@ -166,9 +166,9 @@ class APIBase(MethodView): | ||
| 166 | 166 | ||
| 167 | def _set_limit_and_offset(self): | 167 | def _set_limit_and_offset(self): |
| 168 | try: | 168 | try: |
| 169 | - limit = min(100, int(request.args.get('limit'))) | 169 | + limit = min(ratelimits.get('RETRIEVE_LIMIT'), int(request.args.get('limit'))) |
| 170 | except (ValueError, TypeError): | 170 | except (ValueError, TypeError): |
| 171 | - limit = 20 | 171 | + limit = ratelimits.get('RETRIEVE_LIMIT') |
| 172 | try: | 172 | try: |
| 173 | offset = int(request.args.get('offset')) | 173 | offset = int(request.args.get('offset')) |
| 174 | except (ValueError, TypeError): | 174 | except (ValueError, TypeError): |
pybossa/api/user.py
| @@ -47,7 +47,7 @@ class UserAPI(APIBase): | @@ -47,7 +47,7 @@ class UserAPI(APIBase): | ||
| 47 | 47 | ||
| 48 | # Attributes that are visible only for admins or everyone if the user | 48 | # Attributes that are visible only for admins or everyone if the user |
| 49 | # has privacy_mode disabled | 49 | # has privacy_mode disabled |
| 50 | - allowed_attributes = ('name', 'locale', 'fullname', 'created') | 50 | + allowed_attributes = ('name', 'locale', 'fullname', 'created', 'info') |
| 51 | 51 | ||
| 52 | def _select_attributes(self, user_data): | 52 | def _select_attributes(self, user_data): |
| 53 | privacy = self._is_user_private(user_data) | 53 | privacy = self._is_user_private(user_data) |
| @@ -64,7 +64,10 @@ class UserAPI(APIBase): | @@ -64,7 +64,10 @@ class UserAPI(APIBase): | ||
| 64 | privacy and attribute not in self.public_attributes) | 64 | privacy and attribute not in self.public_attributes) |
| 65 | 65 | ||
| 66 | def _is_user_private(self, user): | 66 | def _is_user_private(self, user): |
| 67 | - return not self._is_requester_admin() and user['privacy_mode'] | 67 | + return not self._is_requesting_own_data(user) and not self._is_requester_admin() and user['privacy_mode'] |
| 68 | + | ||
| 69 | + def _is_requesting_own_data(self, user): | ||
| 70 | + return current_user.is_authenticated() and current_user.name == user['name'] | ||
| 68 | 71 | ||
| 69 | def _is_requester_admin(self): | 72 | def _is_requester_admin(self): |
| 70 | return current_user.is_authenticated() and current_user.admin | 73 | return current_user.is_authenticated() and current_user.admin |
pybossa/cache/projects.py
| @@ -19,6 +19,7 @@ | @@ -19,6 +19,7 @@ | ||
| 19 | from sqlalchemy.sql import text | 19 | from sqlalchemy.sql import text |
| 20 | from pybossa.core import db, timeouts | 20 | from pybossa.core import db, timeouts |
| 21 | from pybossa.model.project import Project | 21 | from pybossa.model.project import Project |
| 22 | +from pybossa.model.profile import Profile | ||
| 22 | from pybossa.util import pretty_date | 23 | from pybossa.util import pretty_date |
| 23 | from pybossa.cache import memoize, cache, delete_memoized, delete_cached | 24 | from pybossa.cache import memoize, cache, delete_memoized, delete_cached |
| 24 | 25 | ||
| @@ -203,7 +204,6 @@ def last_activity(project_id): | @@ -203,7 +204,6 @@ def last_activity(project_id): | ||
| 203 | else: # pragma: no cover | 204 | else: # pragma: no cover |
| 204 | return None | 205 | return None |
| 205 | 206 | ||
| 206 | - | ||
| 207 | def project_last_answers_data(project_id): | 207 | def project_last_answers_data(project_id): |
| 208 | """Return last answers from a project.""" | 208 | """Return last answers from a project.""" |
| 209 | sql = text(''' | 209 | sql = text(''' |
| @@ -266,7 +266,7 @@ def _n_featured(): | @@ -266,7 +266,7 @@ def _n_featured(): | ||
| 266 | 266 | ||
| 267 | # This function does not change too much, so cache it for a longer time | 267 | # This function does not change too much, so cache it for a longer time |
| 268 | @memoize(timeout=timeouts.get('STATS_FRONTPAGE_TIMEOUT')) | 268 | @memoize(timeout=timeouts.get('STATS_FRONTPAGE_TIMEOUT')) |
| 269 | -def get_all_featured(category=None): | 269 | +def get_all_featured(category=None, profile=None): |
| 270 | """Return a list of featured projects with a pagination.""" | 270 | """Return a list of featured projects with a pagination.""" |
| 271 | sql = text( | 271 | sql = text( |
| 272 | '''SELECT project.id, project.name, project.short_name, project.info, | 272 | '''SELECT project.id, project.name, project.short_name, project.info, |
| @@ -326,7 +326,7 @@ def _n_draft(): | @@ -326,7 +326,7 @@ def _n_draft(): | ||
| 326 | 326 | ||
| 327 | 327 | ||
| 328 | @memoize(timeout=timeouts.get('STATS_FRONTPAGE_TIMEOUT')) | 328 | @memoize(timeout=timeouts.get('STATS_FRONTPAGE_TIMEOUT')) |
| 329 | -def get_all_draft(category=None): | 329 | +def get_all_draft(category=None, profile=None): |
| 330 | """Return list of all draft projects.""" | 330 | """Return list of all draft projects.""" |
| 331 | sql = text( | 331 | sql = text( |
| 332 | '''SELECT project.id, project.name, project.short_name, project.created, | 332 | '''SELECT project.id, project.name, project.short_name, project.created, |
| @@ -361,12 +361,19 @@ def get_draft(category=None, page=1, per_page=5): | @@ -361,12 +361,19 @@ def get_draft(category=None, page=1, per_page=5): | ||
| 361 | 361 | ||
| 362 | 362 | ||
| 363 | @memoize(timeout=timeouts.get('N_APPS_PER_CATEGORY_TIMEOUT')) | 363 | @memoize(timeout=timeouts.get('N_APPS_PER_CATEGORY_TIMEOUT')) |
| 364 | -def n_count(category): | 364 | +def n_count(category, profile=None): |
| 365 | """Count the number of projects in a given category.""" | 365 | """Count the number of projects in a given category.""" |
| 366 | if category == 'featured': | 366 | if category == 'featured': |
| 367 | return _n_featured() | 367 | return _n_featured() |
| 368 | if category == 'draft': | 368 | if category == 'draft': |
| 369 | return _n_draft() | 369 | return _n_draft() |
| 370 | + | ||
| 371 | + filter_by_profile = '' | ||
| 372 | + access = None | ||
| 373 | + if profile is not None: | ||
| 374 | + access = profile.access | ||
| 375 | + filter_by_profile = '''AND project.short_name = ANY (:access)''' | ||
| 376 | + | ||
| 370 | sql = text(''' | 377 | sql = text(''' |
| 371 | WITH uniq AS ( | 378 | WITH uniq AS ( |
| 372 | SELECT COUNT(project.id) FROM project | 379 | SELECT COUNT(project.id) FROM project |
| @@ -375,11 +382,12 @@ def n_count(category): | @@ -375,11 +382,12 @@ def n_count(category): | ||
| 375 | category.short_name=:category | 382 | category.short_name=:category |
| 376 | AND project.published=true | 383 | AND project.published=true |
| 377 | AND (project.info->>'passwd_hash') IS NULL | 384 | AND (project.info->>'passwd_hash') IS NULL |
| 385 | + %s | ||
| 378 | GROUP BY project.id) | 386 | GROUP BY project.id) |
| 379 | SELECT COUNT(*) FROM uniq | 387 | SELECT COUNT(*) FROM uniq |
| 380 | - ''') | 388 | + ''' % (filter_by_profile)) |
| 381 | 389 | ||
| 382 | - results = session.execute(sql, dict(category=category)) | 390 | + results = session.execute(sql, dict(category=category, access=access)) |
| 383 | count = 0 | 391 | count = 0 |
| 384 | for row in results: | 392 | for row in results: |
| 385 | count = row[0] | 393 | count = row[0] |
| @@ -387,7 +395,13 @@ def n_count(category): | @@ -387,7 +395,13 @@ def n_count(category): | ||
| 387 | 395 | ||
| 388 | 396 | ||
| 389 | @memoize(timeout=timeouts.get('APP_TIMEOUT')) | 397 | @memoize(timeout=timeouts.get('APP_TIMEOUT')) |
| 390 | -def get_all(category): | 398 | +def get_all(category, profile=None): |
| 399 | + filter_by_profile = '' | ||
| 400 | + access = None | ||
| 401 | + if profile is not None: | ||
| 402 | + access = profile.access | ||
| 403 | + filter_by_profile = '''AND project.short_name = ANY (:access)''' | ||
| 404 | + | ||
| 391 | """Return a list of published projects for a given category. | 405 | """Return a list of published projects for a given category. |
| 392 | """ | 406 | """ |
| 393 | sql = text( | 407 | sql = text( |
| @@ -401,9 +415,10 @@ def get_all(category): | @@ -401,9 +415,10 @@ def get_all(category): | ||
| 401 | AND "user".id=project.owner_id | 415 | AND "user".id=project.owner_id |
| 402 | AND project.published=true | 416 | AND project.published=true |
| 403 | AND (project.info->>'passwd_hash') IS NULL | 417 | AND (project.info->>'passwd_hash') IS NULL |
| 404 | - GROUP BY project.id, "user".id ORDER BY project.name;''') | 418 | + %s |
| 419 | + GROUP BY project.id, "user".id ORDER BY project.name;''' % (filter_by_profile)) | ||
| 405 | 420 | ||
| 406 | - results = session.execute(sql, dict(category=category)) | 421 | + results = session.execute(sql, dict(category=category, access=access)) |
| 407 | projects = [] | 422 | projects = [] |
| 408 | for row in results: | 423 | for row in results: |
| 409 | project = dict(id=row.id, | 424 | project = dict(id=row.id, |
pybossa/cache/users.py
| @@ -74,8 +74,7 @@ def get_user_leaderboard_data(user_id, project_id=None): | @@ -74,8 +74,7 @@ def get_user_leaderboard_data(user_id, project_id=None): | ||
| 74 | SELECT user_id, COUNT(*) AS score FROM task_run | 74 | SELECT user_id, COUNT(*) AS score FROM task_run |
| 75 | WHERE user_id IS NOT NULL %s | 75 | WHERE user_id IS NOT NULL %s |
| 76 | GROUP BY user_id) | 76 | GROUP BY user_id) |
| 77 | - SELECT user_id, score, rank() OVER | ||
| 78 | - (ORDER BY score desc) | 77 | + SELECT user_id, score, dense_rank() OVER (ORDER BY score desc) AS rank |
| 79 | FROM scores) | 78 | FROM scores) |
| 80 | SELECT rank, id, name, fullname, email_addr, info, created, | 79 | SELECT rank, id, name, fullname, email_addr, info, created, |
| 81 | score FROM global_rank | 80 | score FROM global_rank |
| @@ -115,7 +114,7 @@ def get_leaderboard_by_project_id(project_id, n=None, user_id=None): | @@ -115,7 +114,7 @@ def get_leaderboard_by_project_id(project_id, n=None, user_id=None): | ||
| 115 | WITH scores AS ( | 114 | WITH scores AS ( |
| 116 | SELECT user_id, COUNT(*) AS score FROM task_run | 115 | SELECT user_id, COUNT(*) AS score FROM task_run |
| 117 | WHERE user_id IS NOT NULL AND task_run.project_id =:project_id GROUP BY user_id) | 116 | WHERE user_id IS NOT NULL AND task_run.project_id =:project_id GROUP BY user_id) |
| 118 | - SELECT user_id, score, rank() OVER (ORDER BY score desc) | 117 | + SELECT user_id, score, dense_rank() OVER (ORDER BY score desc) AS rank |
| 119 | FROM scores) | 118 | FROM scores) |
| 120 | SELECT rank, id, name, fullname, score FROM global_rank | 119 | SELECT rank, id, name, fullname, score FROM global_rank |
| 121 | JOIN public."user" on (user_id=public."user".id) ORDER BY rank | 120 | 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): | @@ -151,13 +150,9 @@ def get_complete_leaderboard(n=None, user_id=None): | ||
| 151 | SELECT id, short_name FROM project | 150 | SELECT id, short_name FROM project |
| 152 | ''') | 151 | ''') |
| 153 | results = session.execute(sql) | 152 | results = session.execute(sql) |
| 154 | - | ||
| 155 | - complete_leaderboard = [] | 153 | + complete_leaderboard = dict() |
| 156 | for row in results: | 154 | for row in results: |
| 157 | - leaderboard = dict() | ||
| 158 | - leaderboard['project_name'] = row.short_name | ||
| 159 | - leaderboard['leaderboard'] = get_leaderboard_by_project_id(row.id, n, user_id) | ||
| 160 | - complete_leaderboard.append(leaderboard) | 155 | + complete_leaderboard[row.short_name] = get_leaderboard_by_project_id(row.id, n, user_id) |
| 161 | return complete_leaderboard | 156 | return complete_leaderboard |
| 162 | 157 | ||
| 163 | 158 |
pybossa/core.py
| @@ -551,6 +551,7 @@ def setup_ratelimits(app): | @@ -551,6 +551,7 @@ def setup_ratelimits(app): | ||
| 551 | global ratelimits | 551 | global ratelimits |
| 552 | ratelimits['LIMIT'] = app.config['LIMIT'] | 552 | ratelimits['LIMIT'] = app.config['LIMIT'] |
| 553 | ratelimits['PER'] = app.config['PER'] | 553 | ratelimits['PER'] = app.config['PER'] |
| 554 | + ratelimits['RETRIEVE_LIMIT'] = app.config['RETRIEVE_LIMIT'] | ||
| 554 | 555 | ||
| 555 | 556 | ||
| 556 | def setup_cache_timeouts(app): | 557 | def setup_cache_timeouts(app): |
pybossa/default_settings.py
| @@ -94,10 +94,6 @@ TEMPLATE_TASKS = { | @@ -94,10 +94,6 @@ TEMPLATE_TASKS = { | ||
| 94 | 'map': "https://docs.google.com/spreadsheet/ccc?key=0AsNlt0WgPAHwdGZnbjdwcnhKRVNlN1dGXy0tTnNWWXc&usp=sharing", | 94 | 'map': "https://docs.google.com/spreadsheet/ccc?key=0AsNlt0WgPAHwdGZnbjdwcnhKRVNlN1dGXy0tTnNWWXc&usp=sharing", |
| 95 | 'pdf': "https://docs.google.com/spreadsheet/ccc?key=0AsNlt0WgPAHwdEVVamc0R0hrcjlGdXRaUXlqRXlJMEE&usp=sharing"} | 95 | 'pdf': "https://docs.google.com/spreadsheet/ccc?key=0AsNlt0WgPAHwdEVVamc0R0hrcjlGdXRaUXlqRXlJMEE&usp=sharing"} |
| 96 | 96 | ||
| 97 | -# Rate limits default values | ||
| 98 | -LIMIT = 300 | ||
| 99 | -PER = 15 * 60 | ||
| 100 | - | ||
| 101 | # Expiration time for password protected project cookies | 97 | # Expiration time for password protected project cookies |
| 102 | PASSWD_COOKIE_TIMEOUT = 60 * 30 | 98 | PASSWD_COOKIE_TIMEOUT = 60 * 30 |
| 103 | 99 | ||
| @@ -105,8 +101,9 @@ PASSWD_COOKIE_TIMEOUT = 60 * 30 | @@ -105,8 +101,9 @@ PASSWD_COOKIE_TIMEOUT = 60 * 30 | ||
| 105 | ACCOUNT_LINK_EXPIRATION = 5 * 60 * 60 | 101 | ACCOUNT_LINK_EXPIRATION = 5 * 60 * 60 |
| 106 | 102 | ||
| 107 | # Rate limits default values | 103 | # Rate limits default values |
| 108 | -LIMIT = 300 | 104 | +LIMIT = 600 |
| 109 | PER = 15 * 60 | 105 | PER = 15 * 60 |
| 106 | +RETRIEVE_LIMIT = 300 | ||
| 110 | 107 | ||
| 111 | # Disable new account confirmation (via email) | 108 | # Disable new account confirmation (via email) |
| 112 | ACCOUNT_CONFIRMATION_DISABLED = True | 109 | ACCOUNT_CONFIRMATION_DISABLED = True |
pybossa/view/projects.py
| @@ -150,11 +150,15 @@ def project_index(page, lookup, category, fallback, use_count): | @@ -150,11 +150,15 @@ def project_index(page, lookup, category, fallback, use_count): | ||
| 150 | 150 | ||
| 151 | per_page = current_app.config['APPS_PER_PAGE'] | 151 | per_page = current_app.config['APPS_PER_PAGE'] |
| 152 | 152 | ||
| 153 | - ranked_projects = rank(lookup(category)) | 153 | + profile = None |
| 154 | + if current_user.is_authenticated() and not current_user.admin: | ||
| 155 | + profile = user_repo.get_profile(current_user.profile_id) | ||
| 156 | + | ||
| 157 | + ranked_projects = rank(lookup(category, profile)) | ||
| 154 | offset = (page - 1) * per_page | 158 | offset = (page - 1) * per_page |
| 155 | projects = ranked_projects[offset:offset+per_page] | 159 | projects = ranked_projects[offset:offset+per_page] |
| 156 | 160 | ||
| 157 | - count = cached_projects.n_count(category) | 161 | + count = cached_projects.n_count(category, profile) |
| 158 | 162 | ||
| 159 | data = [] | 163 | data = [] |
| 160 | 164 |