Mercurial > kallithea
changeset 1483:7b67b0dcad6d beta
Added initial support for creating new nodes in repos
author | Marcin Kuzminski <marcin@python-works.com> |
---|---|
date | Thu, 22 Sep 2011 04:33:29 +0300 |
parents | a39c0e5fca89 |
children | 1db451a44504 |
files | rhodecode/config/routing.py rhodecode/controllers/files.py rhodecode/lib/utils.py rhodecode/model/scm.py rhodecode/public/css/style.css rhodecode/templates/files/files_add.html rhodecode/templates/files/files_browser.html |
diffstat | 7 files changed, 208 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/rhodecode/config/routing.py Thu Sep 22 03:08:02 2011 +0300 +++ b/rhodecode/config/routing.py Thu Sep 22 04:33:29 2011 +0300 @@ -378,6 +378,11 @@ controller='files', action='edit', revision='tip', f_path='', conditions=dict(function=check_repo)) + rmap.connect('files_add_home', + '/{repo_name:.*}/add/{revision}/{f_path:.*}', + controller='files', action='add', revision='tip', + f_path='', conditions=dict(function=check_repo)) + rmap.connect('files_archive_home', '/{repo_name:.*}/archive/{fname}', controller='files', action='archivefile', conditions=dict(function=check_repo))
--- a/rhodecode/controllers/files.py Thu Sep 22 03:08:02 2011 +0300 +++ b/rhodecode/controllers/files.py Thu Sep 22 04:33:29 2011 +0300 @@ -57,7 +57,7 @@ super(FilesController, self).__before__() c.cut_off_limit = self.cut_off_limit - def __get_cs_or_redirect(self, rev, repo_name): + def __get_cs_or_redirect(self, rev, repo_name, redirect_after=True): """ Safe way to get changeset if error occur it redirects to tip with proper message @@ -69,7 +69,14 @@ try: return c.rhodecode_repo.get_changeset(rev) except EmptyRepositoryError, e: - h.flash(_('There are no files yet'), category='warning') + if not redirect_after: + return None + url_ = url('files_add_home', + repo_name=c.repo_name, + revision=0,f_path='') + add_new = '<a href="%s">[%s]</a>' % (url_,_('add new')) + h.flash(h.literal(_('There are no files yet %s' % add_new)), + category='warning') redirect(h.url('summary_home', repo_name=repo_name)) except RepositoryError, e: @@ -247,7 +254,6 @@ return redirect(url('files_home', repo_name=c.repo_name, revision=c.cs.raw_id, f_path=f_path)) - c.file_history = self._get_node_history(c.cs, f_path) c.f_path = f_path if r_post: @@ -286,6 +292,49 @@ return render('files/files_edit.html') + @HasRepoPermissionAnyDecorator('repository.write', 'repository.admin') + def add(self, repo_name, revision, f_path): + r_post = request.POST + c.cs = self.__get_cs_or_redirect(revision, repo_name, + redirect_after=False) + if c.cs is None: + c.cs = EmptyChangeset(alias=c.rhodecode_repo.alias) + + c.f_path = f_path + + if r_post: + unix_mode = 0 + content = convert_line_endings(r_post.get('content'), unix_mode) + + message = r_post.get('message') or (_('Added %s via RhodeCode') + % (f_path)) + location = r_post.get('location') + filename = r_post.get('filename') + node_path = os.path.join(location, filename) + author = self.rhodecode_user.full_contact + + if not content: + h.flash(_('No content'), category='warning') + return redirect(url('changeset_home', repo_name=c.repo_name, + revision='tip')) + + try: + self.scm_model.create_node(repo=c.rhodecode_repo, + repo_name=repo_name, cs=c.cs, + user=self.rhodecode_user, + author=author, message=message, + content=content, f_path=node_path) + h.flash(_('Successfully committed to %s' % node_path), + category='success') + + except Exception: + log.error(traceback.format_exc()) + h.flash(_('Error occurred during commit'), category='error') + return redirect(url('changeset_home', + repo_name=c.repo_name, revision='tip')) + + return render('files/files_add.html') + @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', 'repository.admin') def archivefile(self, repo_name, fname):
--- a/rhodecode/lib/utils.py Thu Sep 22 03:08:02 2011 +0300 +++ b/rhodecode/lib/utils.py Thu Sep 22 04:33:29 2011 +0300 @@ -42,6 +42,7 @@ from vcs.backends.base import BaseChangeset from vcs.utils.lazy import LazyProperty +from vcs import get_backend from rhodecode.model import meta from rhodecode.model.caching_query import FromCache @@ -313,7 +314,7 @@ an EmptyChangeset """ - def __init__(self, cs='0' * 40, repo=None,requested_revision=None): + def __init__(self, cs='0' * 40, repo=None, requested_revision=None, alias=None): self._empty_cs = cs self.revision = -1 self.message = '' @@ -321,7 +322,8 @@ self.date = '' self.repository = repo self.requested_revision = requested_revision - + self.alias = alias + @LazyProperty def raw_id(self): """Returns raw string identifying this changeset, useful for web @@ -331,6 +333,10 @@ return self._empty_cs @LazyProperty + def branch(self): + return get_backend(self.alias).DEFAULT_BRANCH_NAME + + @LazyProperty def short_id(self): return self.raw_id[:12] @@ -602,3 +608,4 @@ path_to_ini_file = os.path.realpath(conf) conf = paste.deploy.appconfig('config:' + path_to_ini_file) pylonsconfig.init_app(conf.global_conf, conf.local_conf) +
--- a/rhodecode/model/scm.py Thu Sep 22 03:08:02 2011 +0300 +++ b/rhodecode/model/scm.py Thu Sep 22 04:33:29 2011 +0300 @@ -39,7 +39,7 @@ from rhodecode.lib import safe_str from rhodecode.lib.auth import HasRepoPermissionAny from rhodecode.lib.utils import get_repos as get_filesystem_repos, make_ui, \ - action_logger + action_logger, EmptyChangeset from rhodecode.model import BaseModel from rhodecode.model.user import UserModel from rhodecode.model.db import Repository, RhodeCodeUi, CacheInvalidation, \ @@ -352,6 +352,37 @@ self.mark_for_invalidation(repo_name) + def create_node(self, repo, repo_name, cs, user, author, message, content, + f_path): + if repo.alias == 'hg': + from vcs.backends.hg import MercurialInMemoryChangeset as IMC + elif repo.alias == 'git': + from vcs.backends.git import GitInMemoryChangeset as IMC + # decoding here will force that we have proper encoded values + # in any other case this will throw exceptions and deny commit + content = safe_str(content) + message = safe_str(message) + path = safe_str(f_path) + author = safe_str(author) + m = IMC(repo) + + if isinstance(cs, EmptyChangeset): + # Emptychangeset means we we're editing empty repository + parents = None + else: + parents = [cs] + + m.add(FileNode(path, content=content)) + tip = m.commit(message=message, + author=author, + parents=parents, branch=cs.branch) + new_cs = tip.short_id + action = 'push_local:%s' % new_cs + + action_logger(user, action, repo_name) + + self.mark_for_invalidation(repo_name) + def get_unread_journal(self): return self.sa.query(UserLog).count() @@ -368,3 +399,4 @@ .scalar() return ret +
--- a/rhodecode/public/css/style.css Thu Sep 22 03:08:02 2011 +0300 +++ b/rhodecode/public/css/style.css Thu Sep 22 04:33:29 2011 +0300 @@ -1867,9 +1867,21 @@ div.browserblock .browser-search{ clear:both; padding:8px 8px 0px 5px; -} - -div.browserblock .search_activate #filter_activate{ + height: 20px; +} +div.browserblock #node_filter_box { +} + +div.browserblock .search_activate{ + float: left +} + +div.browserblock .add_node{ + float: left; + padding-left: 5px; +} + +div.browserblock .search_activate #filter_activate,div.browserblock .add_node a{ vertical-align: sub; border: 1px solid; padding:2px; @@ -1882,7 +1894,7 @@ color: #515151; } -div.browserblock .search_activate a:hover{ +div.browserblock .search_activate a:hover,div.browserblock .add_node a:hover{ text-decoration: none !important; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rhodecode/templates/files/files_add.html Thu Sep 22 04:33:29 2011 +0300 @@ -0,0 +1,85 @@ +<%inherit file="/base/base.html"/> + +<%def name="title()"> + ${c.repo_name} ${_('Edit file')} - ${c.rhodecode_name} +</%def> + +<%def name="js_extra()"> +<script type="text/javascript" src="${h.url('/js/codemirror.js')}"></script> +</%def> +<%def name="css_extra()"> +<link rel="stylesheet" type="text/css" href="${h.url('/css/codemirror.css')}"/> +</%def> + +<%def name="breadcrumbs_links()"> + ${h.link_to(u'Home',h.url('/'))} + » + ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))} + » + ${_('add file')} @ R${c.cs.revision}:${h.short_id(c.cs.raw_id)} +</%def> + +<%def name="page_nav()"> + ${self.menu('files')} +</%def> +<%def name="main()"> +<div class="box"> + <!-- box / title --> + <div class="title"> + ${self.breadcrumbs()} + <ul class="links"> + <li> + <span style="text-transform: uppercase;"> + <a href="#">${_('branch')}: ${c.cs.branch}</a></span> + </li> + </ul> + </div> + <div class="table"> + <div id="files_data"> + ${h.form(h.url.current(),method='post',id='eform')} + <h3>${_('Add new file')}</h3> + <div class="form"> + <div class="fields"> + <div class="field"> + <div class="label"> + <label for="location">${_('Location')}</label> + </div> + <div class="input"> + <input type="text" value="${c.f_path}" size="30" name="location" id="location"> + </div> + </div> + + <div class="field"> + <div class="label"> + <label for="filename">${_('File Name')}:</label> + </div> + <div class="input"> + <input type="text" value="" size="30" name="filename" id="filename"> + </div> + </div> + </div> + </div> + <div id="body" class="codeblock"> + <pre id="editor_pre"></pre> + <textarea id="editor" name="content" style="display:none"></textarea> + <div style="padding-top: 10px;">${_('commit message')}</div> + <textarea id="commit" name="message" style="height: 100px;width: 99%"></textarea> + </div> + <div style="text-align: right;padding-top: 5px"> + <input id="reset" type="button" value="${_('Reset')}" class="ui-button-small" /> + ${h.submit('commit',_('Commit changes'),class_="ui-button-small-blue")} + </div> + ${h.end_form()} + <script type="text/javascript"> + var myCodeMirror = CodeMirror.fromTextArea(YUD.get('editor'),{ + mode: "null", + lineNumbers:true + }); + YUE.on('reset','click',function(){ + window.location="${h.url('files_home',repo_name=c.repo_name,revision=c.cs.revision,f_path=c.f_path)}"; + }) + </script> + </div> + </div> +</div> +</%def> \ No newline at end of file
--- a/rhodecode/templates/files/files_browser.html Thu Sep 22 03:08:02 2011 +0300 +++ b/rhodecode/templates/files/files_browser.html Thu Sep 22 04:33:29 2011 +0300 @@ -23,11 +23,12 @@ <label>${_('follow current branch')}</label> </div> <div class="browser-search"> - <div class="search_activate"> - <a id="filter_activate" href="#">${_('search file list')}</a> - </div> - - + <div id="search_activate_id" class="search_activate"> + <a id="filter_activate" href="#">${_('search file list')}</a> + </div> + <div id="add_node_id" class="add_node"> + <a href="${h.url('files_add_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=c.f_path)}">${_('add new file')}</a> + </div> <div> <div id="node_filter_box_loading" style="display:none">${_('Loading file list...')}</div> <div id="node_filter_box" style="display:none"> @@ -67,7 +68,8 @@ F.initFilter = function(){ YUD.setStyle('node_filter_box_loading','display',''); - YUD.setStyle('filter_activate','display','none'); + YUD.setStyle('search_activate_id','display','none'); + YUD.setStyle('add_node_id','display','none'); YUC.initHeader('X-PARTIAL-XHR',true); YUC.asyncRequest('GET',url,{ success:function(o){