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+= '&amp;auth_token='+token;
+    if(user_id != undefined){
+    	args+="&amp;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+= '&amp;auth_token='+token;
+    if(user_id != undefined){
+        args+="&amp;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>