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