Changeset - 269905fac50a
[Not reviewed]
beta
0 6 0
Marcin Kuzminski - 14 years ago 2011-09-23 00:52:48
marcin@python-works.com
added uploading of files from web interface directly into repo
6 files changed with 83 insertions and 31 deletions:
0 comments (0 inline, 0 general)
rhodecode/controllers/files.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
"""
 
    rhodecode.controllers.files
 
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

	
 
    Files controller for RhodeCode
 

	
 
    :created_on: Apr 21, 2010
 
    :author: marcink
 
    :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
 
    :license: GPLv3, see COPYING for more details.
 
"""
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
import os
 
import logging
 
import traceback
 

	
 
from os.path import join as jn
 

	
 
from pylons import request, response, session, tmpl_context as c, url
 
from pylons.i18n.translation import _
 
from pylons.controllers.util import redirect
 
from pylons.decorators import jsonify
 

	
 
from vcs.conf import settings
 
from vcs.exceptions import RepositoryError, ChangesetDoesNotExistError, \
 
    EmptyRepositoryError, ImproperArchiveTypeError, VCSError
 
    EmptyRepositoryError, ImproperArchiveTypeError, VCSError, NodeAlreadyExistsError
 
from vcs.nodes import FileNode, NodeKind
 
from vcs.utils import diffs as differ
 

	
 
from rhodecode.lib import convert_line_endings, detect_mode, safe_str
 
from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
 
from rhodecode.lib.base import BaseRepoController, render
 
from rhodecode.lib.utils import EmptyChangeset
 
import rhodecode.lib.helpers as h
 
from rhodecode.model.repo import RepoModel
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class FilesController(BaseRepoController):
 

	
 
    @LoginRequired()
 
    def __before__(self):
 
        super(FilesController, self).__before__()
 
        c.cut_off_limit = self.cut_off_limit
 

	
 
    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
 

	
 
        :param rev: revision to fetch
 
        :param repo_name: repo name to redirect after
 
        """
 

	
 
        try:
 
            return c.rhodecode_repo.get_changeset(rev)
 
        except EmptyRepositoryError, e:
 
            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)), 
 
                       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:
 
            h.flash(str(e), category='warning')
 
            redirect(h.url('files_home', repo_name=repo_name, revision='tip'))
 

	
 
    def __get_filenode_or_redirect(self, repo_name, cs, path):
 
        """
 
        Returns file_node, if error occurs or given path is directory,
 
        it'll redirect to top level path
 

	
 
        :param repo_name: repo_name
 
        :param cs: given changeset
 
        :param path: path to lookup
 
        """
 

	
 
        try:
 
            file_node = cs.get_node(path)
 
            if file_node.is_dir():
 
                raise RepositoryError('given path is a directory')
 
        except RepositoryError, e:
 
            h.flash(str(e), category='warning')
 
            redirect(h.url('files_home', repo_name=repo_name,
 
                           revision=cs.raw_id))
 

	
 
        return file_node
 

	
 

	
 
    def __get_paths(self, changeset, starting_path):
 
        """recursive walk in root dir and return a set of all path in that dir
 
        based on repository walk function
 
        """
 
        _files = list()
 
        _dirs = list()
 

	
 
        try:
 
            tip = changeset
 
            for topnode, dirs, files in tip.walk(starting_path):
 
                for f in files:
 
                    _files.append(f.path)
 
                for d in dirs:
 
                    _dirs.append(d.path)
 
        except RepositoryError, e:
 
            log.debug(traceback.format_exc())
 
            pass
 
        return _dirs, _files
 

	
 
@@ -250,132 +250,139 @@ class FilesController(BaseRepoController
 
        c.cs = self.__get_cs_or_redirect(revision, repo_name)
 
        c.file = self.__get_filenode_or_redirect(repo_name, c.cs, f_path)
 

	
 
        if c.file.is_binary:
 
            return redirect(url('files_home', repo_name=c.repo_name,
 
                         revision=c.cs.raw_id, f_path=f_path))
 

	
 
        c.f_path = f_path
 

	
 
        if r_post:
 

	
 
            old_content = c.file.content
 
            sl = old_content.splitlines(1)
 
            first_line = sl[0] if sl else ''
 
            # modes:  0 - Unix, 1 - Mac, 2 - DOS
 
            mode = detect_mode(first_line, 0)
 
            content = convert_line_endings(r_post.get('content'), mode)
 

	
 
            message = r_post.get('message') or (_('Edited %s via RhodeCode')
 
                                                % (f_path))
 
            author = self.rhodecode_user.full_contact
 

	
 
            if content == old_content:
 
                h.flash(_('No changes'),
 
                    category='warning')
 
                return redirect(url('changeset_home', repo_name=c.repo_name,
 
                                    revision='tip'))
 

	
 
            try:
 
                self.scm_model.commit_change(repo=c.rhodecode_repo,
 
                                             repo_name=repo_name, cs=c.cs,
 
                                             user=self.rhodecode_user,
 
                                             author=author, message=message,
 
                                             content=content, f_path=f_path)
 
                h.flash(_('Successfully committed to %s' % f_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_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, 
 
        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')
 
            file_obj = r_post.get('upload_file', None)
 

	
 
            if file_obj is not None and hasattr(file_obj, 'filename'):
 
                filename = file_obj.filename
 
                content = file_obj.file
 

	
 
            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'))
 
            if not filename:
 
                h.flash(_('No filename'), category='warning')
 
                return redirect(url('changeset_home', repo_name=c.repo_name,
 
                                    revision='tip'))                
 
                                    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 NodeAlreadyExistsError, e:
 
                h.flash(_(e), category='error')
 
            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):
 

	
 
        fileformat = None
 
        revision = None
 
        ext = None
 
        subrepos = request.GET.get('subrepos') == 'true'
 

	
 
        for a_type, ext_data in settings.ARCHIVE_SPECS.items():
 
            archive_spec = fname.split(ext_data[1])
 
            if len(archive_spec) == 2 and archive_spec[1] == '':
 
                fileformat = a_type or ext_data[1]
 
                revision = archive_spec[0]
 
                ext = ext_data[1]
 

	
 
        try:
 
            dbrepo = RepoModel().get_by_repo_name(repo_name)
 
            if dbrepo.enable_downloads is False:
 
                return _('downloads disabled')
 

	
 
            cs = c.rhodecode_repo.get_changeset(revision)
 
            content_type = settings.ARCHIVE_SPECS[fileformat][0]
 
        except ChangesetDoesNotExistError:
 
            return _('Unknown revision %s') % revision
 
        except EmptyRepositoryError:
 
            return _('Empty repository')
 
        except (ImproperArchiveTypeError, KeyError):
 
            return _('Unknown archive type')
 

	
 
        response.content_type = content_type
 
        response.content_disposition = 'attachment; filename=%s-%s%s' \
 
            % (repo_name, revision, ext)
 

	
 
        import tempfile
 
        archive = tempfile.mkstemp()[1]
 
        t = open(archive, 'wb')
 
        cs.fill_archive(stream=t, kind=fileformat, subrepos=subrepos)
 

	
 
        def get_chunked_archive(archive):
rhodecode/model/scm.py
Show inline comments
 
@@ -315,88 +315,93 @@ class ScmModel(BaseModel):
 
                      '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 commit_change(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)
 
        m.change(FileNode(path, content))
 
        tip = m.commit(message=message,
 
                 author=author,
 
                 parents=[cs], 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 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)
 
        
 
        if isinstance(content,(basestring,)):
 
            content = safe_str(content)
 
        elif isinstance(content,file):
 
            content = content.read()
 
            
 
        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()
 

	
 
    def _should_invalidate(self, repo_name):
 
        """Looks up database for invalidation signals for this repo_name
 

	
 
        :param repo_name:
 
        """
 

	
 
        ret = self.sa.query(CacheInvalidation)\
 
            .filter(CacheInvalidation.cache_key == repo_name)\
 
            .filter(CacheInvalidation.cache_active == False)\
 
            .scalar()
 

	
 
        return ret
 

	
rhodecode/public/css/codemirror.css
Show inline comments
 
.CodeMirror {
 
  overflow: auto;
 
  height: 450px;
 
  line-height: 1em;
 
  font-family: monospace;
 
  _position: relative; /* IE6 hack */
 
  margin:20px;
 
}
 

	
 
.CodeMirror-gutter {
 
  position: absolute; left: 0; top: 0;
 
  background-color: #f7f7f7;
 
  border-right: 1px solid #eee;
 
  min-width: 2em;
 
  height: 100%;
 
}
 
.CodeMirror-gutter-text {
 
  color: #aaa;
 
  text-align: right;
 
  padding: .4em .2em .4em .4em;
 
}
 
.CodeMirror-lines {
 
  padding: .4em;
 
}
 

	
 
.CodeMirror pre {
 
  -moz-border-radius: 0;
 
  -webkit-border-radius: 0;
 
  -o-border-radius: 0;
 
  border-radius: 0;
 
  border-width: 0; margin: 0; padding: 0; background: transparent;
 
  font-family: inherit;
 
}
 

	
 
.CodeMirror-cursor {
 
  z-index: 10;
 
  position: absolute;
 
  visibility: hidden;
 
  border-left: 1px solid black !important;
 
}
 
.CodeMirror-focused .CodeMirror-cursor {
 
  visibility: visible;
 
}
 

	
 
span.CodeMirror-selected {
 
  background: #ccc !important;
 
  color: HighlightText !important;
 
}
 
.CodeMirror-focused span.CodeMirror-selected {
 
  background: Highlight !important;
 
}
 

	
 
.CodeMirror-matchingbracket {color: #0f0 !important;}
 
.CodeMirror-nonmatchingbracket {color: #f22 !important;}
 
.CodeMirror-gutter-text{color: #003367 !important;}
 
\ No newline at end of file
rhodecode/public/css/style.css
Show inline comments
 
@@ -883,113 +883,127 @@ padding:0;
 
}
 
 
#content div.box div.form div.fields div.field span.success {
 
height:1%;
 
display:block;
 
color:#316309;
 
margin:8px 0 0;
 
padding:0;
 
}
 
 
#content div.box div.form div.fields div.field div.label {
 
left:70px;
 
width:155px;
 
position:absolute;
 
margin:0;
 
padding:8px 0 0 5px;
 
}
 
 
#content div.box-left div.form div.fields div.field div.label,#content div.box-right div.form div.fields div.field div.label {
 
clear:both;
 
overflow:hidden;
 
left:0;
 
width:auto;
 
position:relative;
 
margin:0;
 
padding:0 0 8px;
 
}
 
 
#content div.box div.form div.fields div.field div.label-select {
 
padding:5px 0 0 5px;
 
}
 
 
#content div.box-left div.form div.fields div.field div.label-select,#content div.box-right div.form div.fields div.field div.label-select {
 
padding:0 0 8px;
 
}
 
 
#content div.box-left div.form div.fields div.field div.label-textarea,#content div.box-right div.form div.fields div.field div.label-textarea {
 
padding:0 0 8px !important;
 
}
 
 
#content div.box div.form div.fields div.field div.label label, div.label label{
 
color:#393939;
 
font-weight:700;
 
}
 
 
#content div.box div.form div.fields div.field div.input {
 
margin:0 0 0 200px;
 
}
 
#content div.box div.form div.fields div.field div.file {
 
margin:0 0 0 200px;
 
}
 
#content div.box-left div.form div.fields div.field div.input,#content div.box-right div.form div.fields div.field div.input {
 
margin:0 0 0 0px;
 
}
 
 
#content div.box div.form div.fields div.field div.input input {
 
background:#FFF;
 
border-top:1px solid #b3b3b3;
 
border-left:1px solid #b3b3b3;
 
border-right:1px solid #eaeaea;
 
border-bottom:1px solid #eaeaea;
 
color:#000;
 
font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
 
font-size:11px;
 
margin:0;
 
padding:7px 7px 6px;
 
}
 
 
#content div.box div.form div.fields div.field div.file input {
 
    background: none repeat scroll 0 0 #FFFFFF;
 
    border-color: #B3B3B3 #EAEAEA #EAEAEA #B3B3B3;
 
    border-style: solid;
 
    border-width: 1px;
 
    color: #000000;
 
    font-family: Lucida Grande,Verdana,Lucida Sans Regular,Lucida Sans Unicode,Arial,sans-serif;
 
    font-size: 11px;
 
    margin: 0;
 
    padding: 7px 7px 6px;
 
}
 
 
 
#content div.box div.form div.fields div.field div.input input.small {
 
width:30%;
 
}
 
 
#content div.box div.form div.fields div.field div.input input.medium {
 
width:55%;
 
}
 
 
#content div.box div.form div.fields div.field div.input input.large {
 
width:85%;
 
}
 
 
#content div.box div.form div.fields div.field div.input input.date {
 
width:177px;
 
}
 
 
#content div.box div.form div.fields div.field div.input input.button {
 
background:#D4D0C8;
 
border-top:1px solid #FFF;
 
border-left:1px solid #FFF;
 
border-right:1px solid #404040;
 
border-bottom:1px solid #404040;
 
color:#000;
 
margin:0;
 
padding:4px 8px;
 
}
 
 
#content div.box div.form div.fields div.field div.textarea {
 
border-top:1px solid #b3b3b3;
 
border-left:1px solid #b3b3b3;
 
border-right:1px solid #eaeaea;
 
border-bottom:1px solid #eaeaea;
 
margin:0 0 0 200px;
 
padding:10px;
 
}
 
 
#content div.box div.form div.fields div.field div.textarea-editor {
 
border:1px solid #ddd;
 
padding:0;
 
}
 
 
#content div.box div.form div.fields div.field div.textarea textarea {
 
width:100%;
 
height:220px;
 
overflow:hidden;
 
background:#FFF;
 
@@ -2314,110 +2328,110 @@ font-size:0.8em;
 
}
 
 
table#permissions_manage tr#add_perm_input td {
 
vertical-align:middle;
 
}
 
 
div.gravatar {
 
background-color:#FFF;
 
border:1px solid #D0D0D0;
 
float:left;
 
margin-right:0.7em;
 
padding:2px 2px 0;
 
 
-webkit-border-radius: 6px;
 
-khtml-border-radius: 6px; 
 
-moz-border-radius: 6px;
 
border-radius: 6px;
 
 
}
 
 
div.gravatar img {
 
-webkit-border-radius: 4px;
 
-khtml-border-radius: 4px; 
 
-moz-border-radius: 4px;
 
border-radius: 4px;	
 
}
 
 
#header,#content,#footer {
 
min-width:978px;
 
}
 
 
#content {
 
clear:both;
 
overflow:hidden;
 
padding:14px 10px;
 
}
 
 
#content div.box div.title div.search {
 
background:url("../images/title_link.png") no-repeat top left;
 
border-left:1px solid #316293;
 
}
 
 
#content div.box div.title div.search div.input input {
 
border:1px solid #316293;
 
}
 
 
 
input.ui-button-small {
 
background:#e5e3e3 url("../images/button.png") repeat-x;
 
border-top:1px solid #DDD;
 
border-left:1px solid #c6c6c6;
 
border-right:1px solid #DDD;
 
border-bottom:1px solid #c6c6c6;
 
color:#515151;
 
outline:none;
 
margin:0;
 
-webkit-border-radius: 4px 4px 4px 4px;
 
-khtml-border-radius: 4px 4px 4px 4px; 
 
-moz-border-radius: 4px 4px 4px 4px;
 
border-radius: 4px 4px 4px 4px;
 
box-shadow: 0 1px 0 #ececec;
 
cursor: pointer;
 
background:#e5e3e3 url("../images/button.png") repeat-x !important;
 
border-top:1px solid #DDD !important;
 
border-left:1px solid #c6c6c6 !important;
 
border-right:1px solid #DDD !important;
 
border-bottom:1px solid #c6c6c6 !important;
 
color:#515151 !important;
 
outline:none !important;
 
margin:0 !important;
 
-webkit-border-radius: 4px 4px 4px 4px !important;
 
-khtml-border-radius: 4px 4px 4px 4px !important; 
 
-moz-border-radius: 4px 4px 4px 4px !important;
 
border-radius: 4px 4px 4px 4px !important;
 
box-shadow: 0 1px 0 #ececec !important;
 
cursor: pointer !important;
 
}
 
 
input.ui-button-small:hover {
 
background:#b4b4b4 url("../images/button_selected.png") repeat-x;
 
border-top:1px solid #ccc;
 
border-left:1px solid #bebebe;
 
border-right:1px solid #b1b1b1;
 
border-bottom:1px solid #afafaf;	
 
}
 
 
input.ui-button-small-blue {
 
background:#4e85bb url("../images/button_highlight.png") repeat-x;
 
border-top:1px solid #5c91a4;
 
border-left:1px solid #2a6f89;
 
border-right:1px solid #2b7089;
 
border-bottom:1px solid #1a6480;
 
color:#fff;
 
-webkit-border-radius: 4px 4px 4px 4px;
 
-khtml-border-radius: 4px 4px 4px 4px; 
 
-moz-border-radius: 4px 4px 4px 4px;
 
border-radius: 4px 4px 4px 4px;
 
box-shadow: 0 1px 0 #ececec;
 
cursor: pointer;
 
}
 
 
input.ui-button-small-blue:hover {
 
	
 
}
 
 
 
ins,div.options a:hover {
 
text-decoration:none;
 
}
 
 
img,#header #header-inner #quick li a:hover span.normal,#header #header-inner #quick li ul li.last,#content div.box div.form div.fields div.field div.textarea table td table td a,#clone_url {
 
border:none;
 
}
 
 
img.icon,.right .merge img {
 
vertical-align:bottom;
 
}
 
 
#header ul#logged-user,#content div.box div.title ul.links,#content div.box div.message div.dismiss,#content div.box div.traffic div.legend ul {
 
float:right;
 
margin:0;
 
padding:0;
 
}
 
rhodecode/templates/files/files_add.html
Show inline comments
 
<%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('/'))}
 
    &raquo;
 
    ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
 
    &raquo;
 
    ${_('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')}
 
		  ${h.form(h.url.current(),method='post',id='eform',enctype="multipart/form-data")}
 
            <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">
 
                                ${_('use / to separate directories')}
 
                            </div>
 
                         </div>
 
                                      
 
                        <div class="field">
 
                        <div id="filename_container" class="field file">
 
                            <div class="label">
 
                                <label for="filename">${_('File Name')}:</label>
 
                            </div>
 
                            <div class="input">
 
                                <input type="text" value="" size="30" name="filename" id="filename">
 
                                <input type="button" class="ui-button-small" value="upload file" id="upload_file_enable">
 
                            </div>
 
                        </div>                                                    
 
                        </div>
 
                        <div id="upload_file_container" class="field" style="display:none">
 
                          <div class="label">
 
                              <label for="location">${_('Upload file')}</label>
 
                          </div>
 
                          <div class="file">
 
                              <input type="file"  size="30" name="upload_file" id="upload_file">
 
                              <input type="button" class="ui-button-small" value="create file" id="file_enable">                        
 
                          </div>
 
                        </div>                                                                      
 
                    </div>
 
            </div>            
 
			<div id="body" class="codeblock">
 
			    <pre id="editor_pre"></pre>
 
				<textarea id="editor" name="content" style="display:none"></textarea>
 
			    <div id="editor_container">    
 
                    <pre id="editor_pre"></pre>
 
				    <textarea id="editor" name="content" style="display:none"></textarea>
 
                </div>
 
				<div style="padding: 10px;color:#666666">${_('commit message')}</div>
 
				<textarea id="commit" name="message" style="height: 100px;width: 99%"></textarea>
 
				<textarea id="commit" name="message" style="height: 100px;width: 99%;margin-left:4px"></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(){
 
			 YUE.on('reset','click',function(e){
 
				 window.location="${h.url('files_home',repo_name=c.repo_name,revision=c.cs.revision,f_path=c.f_path)}";
 
			 })
 
			 });
 
             
 
			 YUE.on('file_enable','click',function(){
 
                 YUD.setStyle('editor_container','display','');
 
                 YUD.setStyle('upload_file_container','display','none');
 
                 YUD.setStyle('filename_container','display','');
 
             });
 
             
 
			 YUE.on('upload_file_enable','click',function(){
 
				 YUD.setStyle('editor_container','display','none');
 
				 YUD.setStyle('upload_file_container','display','');
 
				 YUD.setStyle('filename_container','display','none');
 
			 });
 
			 
 
			</script>
 
		</div>    
 
    </div>
 
</div>    
 
</%def>   
 
\ No newline at end of file
rhodecode/templates/files/files_edit.html
Show inline comments
 
<%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('/'))}
 
    &raquo;
 
    ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
 
    &raquo;
 
    ${_('edit 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">
 
			<h3 class="files_location">${_('Location')}: ${h.files_breadcrumbs(c.repo_name,c.cs.revision,c.file.path)}</h3>
 
			${h.form(h.url.current(),method='post',id='eform')}
 
			<div id="body" class="codeblock">
 
			    <pre id="editor_pre"></pre>
 
				<textarea id="editor" name="content" style="display:none">${c.file.content|n}</textarea>
 
				<div style="padding: 10px;color:#666666">${_('commit message')}</div>
 
				<textarea id="commit" name="message" style="height: 100px;width: 99%"></textarea>
 
				<textarea id="commit" name="message" style="height: 60px;width: 99%;margin-left:4px"></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.file.path)}";
 
			 })
 
			</script>
 
		</div>    
 
    </div>
 
</div>    
 
</%def>   
 
\ No newline at end of file
0 comments (0 inline, 0 general)