Mercurial > kallithea
changeset 1085:3fe3285868d1 beta
implemented public journal for anonymous users, admin can control which repositories
are visible in such journal in admin panel
author | Marcin Kuzminski <marcin@python-works.com> |
---|---|
date | Fri, 25 Feb 2011 18:47:09 +0100 |
parents | 17721a2dfadb |
children | b25a9f13fda1 |
files | rhodecode/config/routing.py rhodecode/controllers/admin/repos.py rhodecode/controllers/journal.py rhodecode/public/css/style.css rhodecode/templates/admin/repos/repo_edit.html rhodecode/templates/base/base.html rhodecode/templates/journal/public_journal.html |
diffstat | 7 files changed, 184 insertions(+), 44 deletions(-) [+] |
line wrap: on
line diff
--- a/rhodecode/config/routing.py Fri Feb 25 01:36:17 2011 +0100 +++ b/rhodecode/config/routing.py Fri Feb 25 18:47:09 2011 +0100 @@ -86,6 +86,9 @@ m.connect('repo_cache', "/repos_cache/{repo_name:.*}", action="repo_cache", conditions=dict(method=["DELETE"], function=check_repo)) + m.connect('repo_public_journal', "/repos_public_journal/{repo_name:.*}", + action="repo_public_journal", conditions=dict(method=["PUT"], + function=check_repo)) #ADMIN USER REST ROUTES routes_map.resource('user', 'users', controller='admin/users', path_prefix='/_admin') @@ -145,6 +148,8 @@ #USER JOURNAL routes_map.connect('journal', '/_admin/journal', controller='journal',) + routes_map.connect('public_journal', '/_admin/public_journal', controller='journal', + action="public_journal") routes_map.connect('toggle_following', '/_admin/toggle_following', controller='journal', action='toggle_following', conditions=dict(method=["POST"]))
--- a/rhodecode/controllers/admin/repos.py Fri Feb 25 01:36:17 2011 +0100 +++ b/rhodecode/controllers/admin/repos.py Fri Feb 25 18:47:09 2011 +0100 @@ -41,7 +41,8 @@ HasPermissionAnyDecorator from rhodecode.lib.base import BaseController, render from rhodecode.lib.utils import invalidate_cache, action_logger, repo_name_slug -from rhodecode.model.db import User +from rhodecode.lib.helpers import get_token +from rhodecode.model.db import User, Repository, UserFollowing from rhodecode.model.forms import RepoForm from rhodecode.model.scm import ScmModel from rhodecode.model.repo import RepoModel @@ -50,7 +51,8 @@ log = logging.getLogger(__name__) class ReposController(BaseController): - """REST Controller styled on the Atom Publishing Protocol""" + """ + REST Controller styled on the Atom Publishing Protocol""" # To properly map this controller, ensure your config/routing.py # file has a resource setup: # map.resource('repo', 'repos') @@ -72,7 +74,8 @@ @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository') def create(self): - """POST /repos: Create a new item""" + """ + POST /repos: Create a new item""" # url('repos') repo_model = RepoModel() _form = RepoForm()() @@ -124,7 +127,8 @@ @HasPermissionAllDecorator('hg.admin') def update(self, repo_name): - """PUT /repos/repo_name: Update an existing item""" + """ + PUT /repos/repo_name: Update an existing item""" # Forms posted to this method should contain a hidden field: # <input type="hidden" name="_method" value="PUT" /> # Or using helpers: @@ -156,6 +160,11 @@ repo, dbrepo = ScmModel().get(repo_name, retval='repo') c.repo_last_rev = repo.count() if repo.revisions else 0 + c.default_user_id = User.by_username('default').user_id + c.in_public_journal = self.sa.query(UserFollowing)\ + .filter(UserFollowing.user_id == c.default_user_id)\ + .filter(UserFollowing.follows_repository == c.repo_info).scalar() + if last_rev == 0: c.stats_percentage = 0 else: @@ -182,7 +191,8 @@ @HasPermissionAllDecorator('hg.admin') def delete(self, repo_name): - """DELETE /repos/repo_name: Delete an existing item""" + """ + DELETE /repos/repo_name: Delete an existing item""" # Forms posted to this method should contain a hidden field: # <input type="hidden" name="_method" value="DELETE" /> # Or using helpers: @@ -216,7 +226,8 @@ @HasPermissionAllDecorator('hg.admin') def delete_perm_user(self, repo_name): - """DELETE an existing repository permission user + """ + DELETE an existing repository permission user :param repo_name: """ @@ -231,7 +242,8 @@ @HasPermissionAllDecorator('hg.admin') def delete_perm_users_group(self, repo_name): - """DELETE an existing repository permission users group + """ + DELETE an existing repository permission users group :param repo_name: """ @@ -246,7 +258,8 @@ @HasPermissionAllDecorator('hg.admin') def repo_stats(self, repo_name): - """DELETE an existing repository statistics + """ + DELETE an existing repository statistics :param repo_name: """ @@ -261,7 +274,8 @@ @HasPermissionAllDecorator('hg.admin') def repo_cache(self, repo_name): - """INVALIDATE existing repository cache + """ + INVALIDATE existing repository cache :param repo_name: """ @@ -274,6 +288,35 @@ return redirect(url('edit_repo', repo_name=repo_name)) @HasPermissionAllDecorator('hg.admin') + def repo_public_journal(self, repo_name): + """ + Set's this repository to be visible in public journal, + in other words assing default user to follow this repo + + :param repo_name: + """ + + cur_token = request.POST.get('auth_token') + token = get_token() + if cur_token == token: + try: + repo_id = Repository.by_repo_name(repo_name).repo_id + user_id = User.by_username('default').user_id + self.scm_model.toggle_following_repo(repo_id, user_id) + h.flash(_('Updated repository visibility in public journal'), + category='success') + except: + h.flash(_('An error occurred during setting this' + ' repository in public journal'), + category='error') + + else: + h.flash(_('Token mismatch'), category='error') + return redirect(url('edit_repo', repo_name=repo_name)) + + + + @HasPermissionAllDecorator('hg.admin') def show(self, repo_name, format='html'): """GET /repos/repo_name: Show a specific item""" # url('repo', repo_name=ID) @@ -296,6 +339,11 @@ return redirect(url('repos')) + c.default_user_id = User.by_username('default').user_id + c.in_public_journal = self.sa.query(UserFollowing)\ + .filter(UserFollowing.user_id == c.default_user_id)\ + .filter(UserFollowing.follows_repository == c.repo_info).scalar() + if c.repo_info.stats: last_rev = c.repo_info.stats.stat_on_revision else:
--- a/rhodecode/controllers/journal.py Fri Feb 25 01:36:17 2011 +0100 +++ b/rhodecode/controllers/journal.py Fri Feb 25 18:47:09 2011 +0100 @@ -45,42 +45,20 @@ @LoginRequired() - @NotAnonymous() def __before__(self): super(JournalController, self).__before__() + @NotAnonymous() def index(self): # Return a rendered template + p = int(request.params.get('page', 1)) c.following = self.sa.query(UserFollowing)\ .filter(UserFollowing.user_id == c.rhodecode_user.user_id)\ .options(joinedload(UserFollowing.follows_repository))\ .all() - - repo_ids = [x.follows_repository.repo_id for x in c.following - if x.follows_repository is not None] - user_ids = [x.follows_user.user_id for x in c.following - if x.follows_user is not None] - - filtering_criterion = None - - if repo_ids and user_ids: - filtering_criterion = or_(UserLog.repository_id.in_(repo_ids), - UserLog.user_id.in_(user_ids)) - if repo_ids and not user_ids: - filtering_criterion = UserLog.repository_id.in_(repo_ids) - if not repo_ids and user_ids: - filtering_criterion = UserLog.user_id.in_(user_ids) - if filtering_criterion is not None: - journal = self.sa.query(UserLog)\ - .options(joinedload(UserLog.user))\ - .options(joinedload(UserLog.repository))\ - .filter(filtering_criterion)\ - .order_by(UserLog.action_date.desc()) - else: - journal = [] - p = int(request.params.get('page', 1)) + journal = self._get_journal_data(c.following) c.journal_pager = Page(journal, page=p, items_per_page=20) @@ -105,6 +83,34 @@ return groups + def _get_journal_data(self, following_repos): + repo_ids = [x.follows_repository.repo_id for x in following_repos + if x.follows_repository is not None] + user_ids = [x.follows_user.user_id for x in following_repos + if x.follows_user is not None] + + filtering_criterion = None + + if repo_ids and user_ids: + filtering_criterion = or_(UserLog.repository_id.in_(repo_ids), + UserLog.user_id.in_(user_ids)) + if repo_ids and not user_ids: + filtering_criterion = UserLog.repository_id.in_(repo_ids) + if not repo_ids and user_ids: + filtering_criterion = UserLog.user_id.in_(user_ids) + if filtering_criterion is not None: + journal = self.sa.query(UserLog)\ + .options(joinedload(UserLog.user))\ + .options(joinedload(UserLog.repository))\ + .filter(filtering_criterion)\ + .order_by(UserLog.action_date.desc()) + else: + journal = [] + + + return journal + + @NotAnonymous() def toggle_following(self): cur_token = request.POST.get('auth_token') token = get_token() @@ -131,3 +137,26 @@ log.debug('token mismatch %s vs %s', cur_token, token) raise HTTPInternalServerError() + + + + + def public_journal(self): + # Return a rendered template + p = int(request.params.get('page', 1)) + + c.following = self.sa.query(UserFollowing)\ + .filter(UserFollowing.user_id == c.rhodecode_user.user_id)\ + .options(joinedload(UserFollowing.follows_repository))\ + .all() + + journal = self._get_journal_data(c.following) + + c.journal_pager = Page(journal, page=p, items_per_page=20) + + c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager) + + c.journal_data = render('journal/journal_data.html') + if request.params.get('partial'): + return c.journal_data + return render('journal/public_journal.html')
--- a/rhodecode/public/css/style.css Fri Feb 25 01:36:17 2011 +0100 +++ b/rhodecode/public/css/style.css Fri Feb 25 18:47:09 2011 +0100 @@ -1987,6 +1987,20 @@ text-align:left; padding-top:1px; } +.start_following_icon { +background:url("../images/icons/heart_add.png") no-repeat scroll 3px; +height:16px; +padding-left:20px; +text-align:left; +padding-top:1px; +} +.stop_following_icon { +background:url("../images/icons/heart_delete.png") no-repeat scroll 3px; +height:16px; +padding-left:20px; +text-align:left; +padding-top:1px; +} .action_button { border:0;
--- a/rhodecode/templates/admin/repos/repo_edit.html Fri Feb 25 01:36:17 2011 +0100 +++ b/rhodecode/templates/admin/repos/repo_edit.html Fri Feb 25 18:47:09 2011 +0100 @@ -302,7 +302,6 @@ <div class="form"> <div class="fields"> ${h.submit('reset_stats_%s' % c.repo_info.repo_name,_('Reset current statistics'),class_="refresh_icon action_button",onclick="return confirm('Confirm to remove current statistics');")} - <div class="field"> <ul> <li>${_('Fetched to rev')}: ${c.stats_revision}/${c.repo_last_rev}</li> @@ -323,6 +322,19 @@ </div> ${h.end_form()} + <h3>${_('Public journal')}</h3> + ${h.form(url('repo_public_journal', repo_name=c.repo_info.repo_name),method='put')} + <div class="form"> + <div class="fields"> + ${h.hidden('auth_token',str(h.get_token()))} + %if c.in_public_journal: + ${h.submit('set_public_%s' % c.repo_info.repo_name,_('Remove from public journal'),class_="stop_following_icon action_button")} + %else: + ${h.submit('set_public_%s' % c.repo_info.repo_name,_('Add to public journal'),class_="start_following_icon action_button")} + %endif + </div> + </div> + ${h.end_form()} <h3>${_('Delete')}</h3> ${h.form(url('repo', repo_name=c.repo_info.repo_name),method='delete')}
--- a/rhodecode/templates/base/base.html Fri Feb 25 01:36:17 2011 +0100 +++ b/rhodecode/templates/base/base.html Fri Feb 25 18:47:09 2011 +0100 @@ -38,12 +38,7 @@ </div> <div class="account"> %if c.rhodecode_user.username == 'default': - %if h.HasPermissionAny('hg.admin', 'hg.register.auto_activate', 'hg.register.manual_activate')(): - ${h.link_to('anonymous',h.url('register'),title='%s %s'%(c.rhodecode_user.name,c.rhodecode_user.lastname))} - %else: - ${h.link_to('anonymous',h.url('#'),title='%s %s'%(c.rhodecode_user.name,c.rhodecode_user.lastname))} - %endif - + <a href="${h.url('public_journal')}">${_('Public journal')}</a> %else: ${h.link_to(c.rhodecode_user.username,h.url('admin_settings_my_account'),title='%s %s'%(c.rhodecode_user.name,c.rhodecode_user.lastname))} %endif @@ -373,20 +368,26 @@ } } -function toggleFollowingUser(fallows_user_id,token){ +function toggleFollowingUser(target,fallows_user_id,token,user_id){ args = 'follows_user_id='+fallows_user_id; args+= '&auth_token='+token; + if(user_id != undefined){ + args+="&user_id="+user_id; + } YUC.asyncRequest('POST',base_url,{ success:function(o){ - onSuccess(); + onSuccess(target); } },args); return false; } -function toggleFollowingRepo(target,fallows_repo_id,token){ +function toggleFollowingRepo(target,fallows_repo_id,token,user_id){ args = 'follows_repo_id='+fallows_repo_id; args+= '&auth_token='+token; + if(user_id != undefined){ + args+="&user_id="+user_id; + } YUC.asyncRequest('POST',base_url,{ success:function(o){ onSuccess(target);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rhodecode/templates/journal/public_journal.html Fri Feb 25 18:47:09 2011 +0100 @@ -0,0 +1,31 @@ +## -*- coding: utf-8 -*- +<%inherit file="/base/base.html"/> +<%def name="title()"> + ${_('Journal')} - ${c.rhodecode_name} +</%def> +<%def name="breadcrumbs()"> + ${c.rhodecode_name} +</%def> +<%def name="page_nav()"> + ${self.menu('home')} +</%def> +<%def name="main()"> + + <div class="box"> + <!-- box / title --> + <div class="title"> + <h5>${_('Public Journal')}</h5> + </div> + <script type="text/javascript"> + function show_more_event(){ + YUE.on(YUD.getElementsByClassName('show_more'),'click',function(e){ + var el = e.target; + YUD.setStyle(YUD.get(el.id.substring(1)),'display',''); + YUD.setStyle(el.parentNode,'display','none'); + }); + } + </script> + <div id="journal">${c.journal_data}</div> + </div> + +</%def>