diff --git a/rhodecode/config/routing.py b/rhodecode/config/routing.py
--- a/rhodecode/config/routing.py
+++ b/rhodecode/config/routing.py
@@ -89,6 +89,10 @@ def make_map(config):
m.connect('repo_public_journal', "/repos_public_journal/{repo_name:.*}",
action="repo_public_journal", conditions=dict(method=["PUT"],
function=check_repo))
+ m.connect('repo_pull', "/repo_pull/{repo_name:.*}",
+ action="repo_pull", conditions=dict(method=["PUT"],
+ function=check_repo))
+
#ADMIN USER REST ROUTES
routes_map.resource('user', 'users', controller='admin/users', path_prefix='/_admin')
diff --git a/rhodecode/controllers/admin/repos.py b/rhodecode/controllers/admin/repos.py
--- a/rhodecode/controllers/admin/repos.py
+++ b/rhodecode/controllers/admin/repos.py
@@ -374,7 +374,22 @@ class ReposController(BaseController):
h.flash(_('Token mismatch'), category='error')
return redirect(url('edit_repo', repo_name=repo_name))
+ @HasPermissionAllDecorator('hg.admin')
+ def repo_pull(self, repo_name):
+ """
+ Runs task to update given repository with remote changes,
+ ie. make pull on remote location
+
+ :param repo_name:
+ """
+ try:
+ ScmModel().pull_changes(repo_name, c.rhodecode_user.username)
+ h.flash(_('Pulled from remote location'), category='success')
+ except Exception, e:
+ h.flash(_('An error occurred during pull from remote location'),
+ category='error')
+ return redirect(url('edit_repo', repo_name=repo_name))
@HasPermissionAllDecorator('hg.admin')
def show(self, repo_name, format='html'):
diff --git a/rhodecode/lib/helpers.py b/rhodecode/lib/helpers.py
--- a/rhodecode/lib/helpers.py
+++ b/rhodecode/lib/helpers.py
@@ -507,6 +507,7 @@ def action_parser(user_log, feed=False):
'admin_forked_repo':(_('[forked] repository'), None),
'admin_updated_repo':(_('[updated] repository'), None),
'push':(_('[pushed] into'), get_cs_links),
+ 'push_remote':(_('[pulled from remote] into'), get_cs_links),
'pull':(_('[pulled] from'), None),
'started_following_repo':(_('[started following] repository'), None),
'stopped_following_repo':(_('[stopped following] repository'), None),
@@ -518,9 +519,10 @@ def action_parser(user_log, feed=False):
else:
action = action_str[0].replace('[', '')\
.replace(']', '')
+
action_params_func = lambda :""
- if action_str[1] is not None:
+ if callable(action_str[1]):
action_params_func = action_str[1]
return [literal(action), action_params_func]
@@ -533,7 +535,7 @@ def action_parser_icon(user_log):
if len(x) > 1:
action, action_params = x
- tmpl = """"""
+ tmpl = """
"""
map = {'user_deleted_repo':'database_delete.png',
'user_created_repo':'database_add.png',
'user_forked_repo':'arrow_divide.png',
@@ -543,6 +545,7 @@ def action_parser_icon(user_log):
'admin_forked_repo':'arrow_divide.png',
'admin_updated_repo':'database_edit.png',
'push':'script_add.png',
+ 'push_remote':'connect.png',
'pull':'down_16.png',
'started_following_repo':'heart_add.png',
'stopped_following_repo':'heart_delete.png',
diff --git a/rhodecode/lib/hooks.py b/rhodecode/lib/hooks.py
--- a/rhodecode/lib/hooks.py
+++ b/rhodecode/lib/hooks.py
@@ -91,7 +91,7 @@ def log_push_action(ui, repo, **kwargs):
extra_params = dict(repo.ui.configitems('rhodecode_extras'))
username = extra_params['username']
repository = extra_params['repository']
- action = 'push:%s'
+ action = extra_params['action'] + ':%s'
node = kwargs['node']
def get_revs(repo, rev_opt):
diff --git a/rhodecode/model/scm.py b/rhodecode/model/scm.py
--- a/rhodecode/model/scm.py
+++ b/rhodecode/model/scm.py
@@ -232,8 +232,6 @@ class ScmModel(BaseModel):
return r, dbr
-
-
def mark_for_invalidation(self, repo_name):
"""Puts cache invalidation task into db for
further global cache invalidation
@@ -359,6 +357,25 @@ class ScmModel(BaseModel):
== RepoModel().get_by_repo_name(repo_id)).count()
+ def pull_changes(self, repo_name, username):
+ repo, dbrepo = self.get(repo_name, retval='all')
+
+ try:
+ extras = {'ip':'',
+ 'username':username,
+ 'action':'push_remote',
+ 'repository':repo_name}
+
+ #inject ui extra param to log this action via push logger
+ for k, v in extras.items():
+ repo._repo.ui.setconfig('rhodecode_extras', k, v)
+
+ repo.pull(dbrepo.clone_uri)
+ self.mark_for_invalidation(repo_name)
+ except:
+ log.error(traceback.format_exc())
+ raise
+
def get_unread_journal(self):
return self.sa.query(UserLog).count()
diff --git a/rhodecode/public/css/style.css b/rhodecode/public/css/style.css
--- a/rhodecode/public/css/style.css
+++ b/rhodecode/public/css/style.css
@@ -1964,6 +1964,14 @@ padding-top:1px;
text-align:left;
}
+.pull_icon {
+background:url("../images/icons/connect.png") no-repeat scroll 3px;
+height:16px;
+padding-left:20px;
+padding-top:1px;
+text-align:left;
+}
+
.rss_icon {
background:url("../images/icons/rss_16.png") no-repeat scroll 3px;
height:16px;
diff --git a/rhodecode/templates/admin/repos/repo_edit.html b/rhodecode/templates/admin/repos/repo_edit.html
--- a/rhodecode/templates/admin/repos/repo_edit.html
+++ b/rhodecode/templates/admin/repos/repo_edit.html
@@ -314,12 +314,11 @@