Mercurial > kallithea
changeset 612:79457e03ef68
Merge with b0a411f5ec7056bc0b32c8263538b308c33b82f6
author | Marcin Kuzminski <marcin@python-works.com> |
---|---|
date | Mon, 18 Oct 2010 15:29:56 +0200 |
parents | edf8567be8ed (diff) b0a411f5ec70 (current diff) |
children | 956952fea94c |
files | development.ini production.ini rhodecode/config/deployment.ini_tmpl rhodecode/controllers/changelog.py rhodecode/lib/auth.py rhodecode/model/meta.py |
diffstat | 38 files changed, 318 insertions(+), 526 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Tue Oct 12 16:49:28 2010 +0200 +++ b/.hgtags Mon Oct 18 15:29:56 2010 +0200 @@ -14,5 +14,4 @@ ca41d544dbdfd2f81bd0304168492a26276aadb6 v0.8.3 2fa16ec5822da0c6fade3dd1ed9b6c0655e5dbbf v0.8.4 16ba57d8fe2317c49dbd422afd07ab497687aa02 v0.8.5 -2cd05c5803ade0f491d697fe75ce417138fe2295 v1.0.0rc1 -2ec9b6c8cacee06a773713f455a516d622241a25 v1.0.0rc2 +53128b6b9a4ddb6ee9554cbb83a082a6d1316b42 v1.0.0rc4
--- a/development.ini Tue Oct 12 16:49:28 2010 +0200 +++ b/development.ini Mon Oct 18 15:29:56 2010 +0200 @@ -50,14 +50,16 @@ beaker.cache.data_dir=/%(here)s/data/cache/data beaker.cache.lock_dir=/%(here)s/data/cache/lock beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long -beaker.cache.long_term.type=memory -beaker.cache.long_term.expire=36000 + +beaker.cache.super_short_term.type=memory +beaker.cache.super_short_term.expire=10 beaker.cache.short_term.type=memory beaker.cache.short_term.expire=60 -beaker.cache.super_short_term.type=memory -beaker.cache.super_short_term.expire=10 +beaker.cache.long_term.type=memory +beaker.cache.long_term.expire=36000 + beaker.cache.sql_cache_short.type=memory beaker.cache.sql_cache_short.expire=5
--- a/docs/changelog.rst Tue Oct 12 16:49:28 2010 +0200 +++ b/docs/changelog.rst Mon Oct 18 15:29:56 2010 +0200 @@ -3,12 +3,20 @@ Changelog ========= +1.0.0rc4 (**2010-10-12**) -1.0.0rc3 (**tip**) +- fixed python2.5 missing simplejson imports (thanks to Jens Bäckman) +- removed cache_manager settings from sqlalchemy meta +- added sqlalchemy cache settings to ini files +- validated password length and added second try of failure on paster setup-app +- fixed setup database destroy prompt even when there was no db + + +1.0.0rc3 (**2010-10-11**) - fixed i18n during installation. -1.0.0rc2 (**tip**) +1.0.0rc2 (**2010-10-11**) - Disabled dirsize in file browser, it's causing nasty bug when dir renames occure. After vcs is fixed it'll be put back again.
--- a/docs/setup.rst Tue Oct 12 16:49:28 2010 +0200 +++ b/docs/setup.rst Mon Oct 18 15:29:56 2010 +0200 @@ -17,7 +17,7 @@ :: - paster setup-app production.ini` + paster setup-app production.ini - This command will create all needed tables and an admin account. When asked for a path You can either use a new location of one with already @@ -26,7 +26,7 @@ - Remember that the given path for mercurial_ repositories must be write accessible for the application. It's very important since RhodeCode web interface will work even without such an access but, when trying to do a push it'll - eventually faile with permission denied errors. + eventually fail with permission denied errors. - Run :: @@ -35,15 +35,12 @@ - This command runs the rhodecode server the app should be available at the 127.0.0.1:5000. This ip and port is configurable via the production.ini - file created in previos step + file created in previous step - Use admin account you created to login. - Default permissions on each repository is read, and owner is admin. So - remember to update these. - -- All needed configs are inside rhodecode sources ie. celeryconfig.py, - development.ini, production.ini You can configure the email, ports, loggers, - workers from there. + remember to update these if needed. + Setting up Whoosh ----------------- @@ -51,7 +48,7 @@ :: - python /var/www/rhodecode/rhodecode/lib/indexers/daemon.py incremental <put_here_path_to_repos> + python /var/www/rhodecode/<rhodecode_installation_path>/lib/indexers/daemon.py incremental <put_here_path_to_repos> When using incremental mode whoosh will check last modification date of each file and add it to reindex if newer file is available. Also indexing daemon checks @@ -69,7 +66,7 @@ listen 80; server_name hg.myserver.com; access_log /var/log/nginx/rhodecode.access.log; - error_log /var/log/nginx/rhodecode.error.log; + error_log /var/log/nginx/rhodecode.error.log; location / { root /var/www/rhodecode/rhodecode/public/; if (!-f $request_filename){ @@ -81,7 +78,7 @@ } } -Here's the proxy.conf. It's tunned so it'll not timeout on long +Here's the proxy.conf. It's tuned so it'll not timeout on long pushes and also on large pushes:: proxy_redirect off; @@ -111,7 +108,7 @@ lang=en cache_dir = %(here)s/data -To not have the statics served by the application. +To not have the statics served by the application. And improve speed. Other configuration files
--- a/production.ini Tue Oct 12 16:49:28 2010 +0200 +++ b/production.ini Mon Oct 18 15:29:56 2010 +0200 @@ -50,14 +50,16 @@ beaker.cache.data_dir=/%(here)s/data/cache/data beaker.cache.lock_dir=/%(here)s/data/cache/lock beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long -beaker.cache.long_term.type=memory -beaker.cache.long_term.expire=36000 + +beaker.cache.super_short_term.type=memory +beaker.cache.super_short_term.expire=10 beaker.cache.short_term.type=memory beaker.cache.short_term.expire=60 -beaker.cache.super_short_term.type=memory -beaker.cache.super_short_term.expire=10 +beaker.cache.long_term.type=memory +beaker.cache.long_term.expire=36000 + beaker.cache.sql_cache_short.type=memory beaker.cache.sql_cache_short.expire=5
--- a/rhodecode/__init__.py Tue Oct 12 16:49:28 2010 +0200 +++ b/rhodecode/__init__.py Mon Oct 18 15:29:56 2010 +0200 @@ -24,7 +24,7 @@ @author: marcink """ -VERSION = (1, 0, 0, 'rc3') +VERSION = (1, 0, 0, 'rc4') __version__ = '.'.join((str(each) for each in VERSION[:4]))
--- a/rhodecode/config/deployment.ini_tmpl Tue Oct 12 16:49:28 2010 +0200 +++ b/rhodecode/config/deployment.ini_tmpl Mon Oct 18 15:29:56 2010 +0200 @@ -51,14 +51,15 @@ beaker.cache.data_dir=/%(here)s/data/cache/data beaker.cache.lock_dir=/%(here)s/data/cache/lock beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long -beaker.cache.long_term.type=memory -beaker.cache.long_term.expire=36000 + +beaker.cache.super_short_term.type=memory +beaker.cache.super_short_term.expire=10 beaker.cache.short_term.type=memory beaker.cache.short_term.expire=60 -beaker.cache.super_short_term.type=memory -beaker.cache.super_short_term.expire=10 +beaker.cache.long_term.type=memory +beaker.cache.long_term.expire=36000 beaker.cache.sql_cache_short.type=memory beaker.cache.sql_cache_short.expire=5
--- a/rhodecode/config/routing.py Tue Oct 12 16:49:28 2010 +0200 +++ b/rhodecode/config/routing.py Mon Oct 18 15:29:56 2010 +0200 @@ -1,4 +1,5 @@ -"""Routes configuration +""" +Routes configuration The more specific and detailed routes should be defined first so they may take precedent over the more generic routes. For more information @@ -15,24 +16,28 @@ map.minimization = False map.explicit = False + def check_repo(environ, match_dict): + """ + check for valid repository for proper 404 handling + :param environ: + :param match_dict: + """ + repo_name = match_dict.get('repo_name') + return not cr(repo_name, config['base_path']) + # The ErrorController route (handles 404/500 error pages); it should # likely stay at the top, ensuring it can always be resolved map.connect('/error/{action}', controller='error') map.connect('/error/{action}/{id}', controller='error') + #========================================================================== # CUSTOM ROUTES HERE + #========================================================================== + + #MAIN PAGE map.connect('hg_home', '/', controller='hg', action='index') - - def check_repo(environ, match_dict): - """ - check for valid repository for proper 404 handling - @param environ: - @param match_dict: - """ - repo_name = match_dict.get('repo_name') - return not cr(repo_name, config['base_path']) - - #REST REPO MAP + + #ADMIN REPOSITORY REST ROUTES with map.submapper(path_prefix='/_admin', controller='admin/repos') as m: m.connect("repos", "/repos", action="create", conditions=dict(method=["POST"])) @@ -67,11 +72,14 @@ m.connect('delete_repo_user', "/repos_delete_user/{repo_name:.*}", action="delete_perm_user", conditions=dict(method=["DELETE"], function=check_repo)) - + + #ADMIN USER REST ROUTES map.resource('user', 'users', controller='admin/users', path_prefix='/_admin') + + #ADMIN PERMISSIONS REST ROUTES map.resource('permission', 'permissions', controller='admin/permissions', path_prefix='/_admin') - - #REST SETTINGS MAP + + #ADMIN SETTINGS REST ROUTES with map.submapper(path_prefix='/_admin', controller='admin/settings') as m: m.connect("admin_settings", "/settings", action="create", conditions=dict(method=["POST"])) @@ -101,8 +109,8 @@ action="my_account_update", conditions=dict(method=["PUT"])) m.connect("admin_settings_create_repository", "/create_repository", action="create_repository", conditions=dict(method=["GET"])) - - #ADMIN + + #ADMIN MAIN PAGES with map.submapper(path_prefix='/_admin', controller='admin/admin') as m: m.connect('admin_home', '', action='index')#main page m.connect('admin_add_repo', '/add_repo/{new_repo:[a-z0-9\. _-]*}', @@ -110,13 +118,13 @@ #SEARCH map.connect('search', '/_admin/search', controller='search',) map.connect('search_repo', '/_admin/search/{search_repo:.*}', controller='search') - + #LOGIN/LOGOUT/REGISTER/SIGN IN map.connect('login_home', '/_admin/login', controller='login') map.connect('logout_home', '/_admin/logout', controller='login', action='logout') map.connect('register', '/_admin/register', controller='login', action='register') map.connect('reset_password', '/_admin/password_reset', controller='login', action='password_reset') - + #FEEDS map.connect('rss_feed_home', '/{repo_name:.*}/feed/rss', controller='feed', action='rss', @@ -124,9 +132,9 @@ map.connect('atom_feed_home', '/{repo_name:.*}/feed/atom', controller='feed', action='atom', conditions=dict(function=check_repo)) - - - #OTHERS + + + #REPOSITORY ROUTES map.connect('changeset_home', '/{repo_name:.*}/changeset/{revision}', controller='changeset', revision='tip', conditions=dict(function=check_repo)) @@ -142,7 +150,7 @@ map.connect('tags_home', '/{repo_name:.*}/tags', controller='tags', conditions=dict(function=check_repo)) map.connect('changelog_home', '/{repo_name:.*}/changelog', - controller='changelog', conditions=dict(function=check_repo)) + controller='changelog', conditions=dict(function=check_repo)) map.connect('files_home', '/{repo_name:.*}/files/{revision}/{f_path:.*}', controller='files', revision='tip', f_path='', conditions=dict(function=check_repo)) @@ -157,10 +165,10 @@ conditions=dict(function=check_repo)) map.connect('files_annotate_home', '/{repo_name:.*}/annotate/{revision}/{f_path:.*}', controller='files', action='annotate', revision='tip', f_path='', - conditions=dict(function=check_repo)) + conditions=dict(function=check_repo)) map.connect('files_archive_home', '/{repo_name:.*}/archive/{revision}/{fileformat}', controller='files', action='archivefile', revision='tip', - conditions=dict(function=check_repo)) + conditions=dict(function=check_repo)) map.connect('repo_settings_delete', '/{repo_name:.*}/settings', controller='settings', action="delete", conditions=dict(method=["DELETE"], function=check_repo)) @@ -177,5 +185,5 @@ map.connect('repo_fork_home', '/{repo_name:.*}/fork', controller='settings', action='fork', conditions=dict(function=check_repo)) - + return map
--- a/rhodecode/controllers/admin/repos.py Tue Oct 12 16:49:28 2010 +0200 +++ b/rhodecode/controllers/admin/repos.py Mon Oct 18 15:29:56 2010 +0200 @@ -193,7 +193,7 @@ def delete_perm_user(self, repo_name): """ DELETE an existing repository permission user - @param repo_name: + :param repo_name: """ try:
--- a/rhodecode/controllers/changelog.py Tue Oct 12 16:49:28 2010 +0200 +++ b/rhodecode/controllers/changelog.py Mon Oct 18 15:29:56 2010 +0200 @@ -22,6 +22,7 @@ changelog controller for pylons @author: marcink """ + try: import json except ImportError:
--- a/rhodecode/lib/auth.py Tue Oct 12 16:49:28 2010 +0200 +++ b/rhodecode/lib/auth.py Mon Oct 18 15:29:56 2010 +0200 @@ -67,7 +67,7 @@ def get_crypt_password(password): """Cryptographic function used for password hashing based on sha1 - @param password: password to hash + :param password: password to hash """ return bcrypt.hashpw(password, bcrypt.gensalt(10)) @@ -121,7 +121,7 @@ permission given in db. We don't wannt to check each time from db for new permissions since adding a new permission also requires application restart ie. to decorate new views with the newly created permission - @param config: + :param config: """ log.info('getting information about all available permissions') try: @@ -139,7 +139,7 @@ """ Fills user data with those from database and log out user if not present in database - @param user: + :param user: """ sa = meta.Session dbuser = sa.query(User).options(FromCache('sql_cache_short', @@ -159,7 +159,7 @@ def fill_perms(user): """ Fills user permission attribute with permissions taken from database - @param user: + :param user: """ sa = meta.Session @@ -234,7 +234,7 @@ def get_user(session): """ Gets user from session, and wraps permissions into user - @param session: + :param session: """ user = session.get('rhodecode_user', AuthUser()) if user.is_authenticated:
--- a/rhodecode/lib/celerylib/tasks.py Tue Oct 12 16:49:28 2010 +0200 +++ b/rhodecode/lib/celerylib/tasks.py Mon Oct 18 15:29:56 2010 +0200 @@ -308,9 +308,10 @@ 'yaws'] repos_path = get_hg_ui_settings()['paths_root_path'].replace('*', '') repo = MercurialRepository(repos_path + repo_name) - + tip = repo.get_changeset() + code_stats = {} - for topnode, dirs, files in repo.walk('/', 'tip'): + for topnode, dirs, files in tip.walk('/'): for f in files: k = f.mimetype if f.extension in LANGUAGES_EXTENSIONS:
--- a/rhodecode/lib/db_manage.py Tue Oct 12 16:49:28 2010 +0200 +++ b/rhodecode/lib/db_manage.py Mon Oct 18 15:29:56 2010 +0200 @@ -56,7 +56,6 @@ log.info('checking for existing db in %s', db_path) if os.path.isfile(db_path): self.db_exists = True - log.info('database exist') if not override: raise Exception('database already exists') @@ -65,7 +64,7 @@ Create a auth database """ self.check_for_db(override) - if override: + if self.db_exists: log.info("database exist and it's going to be destroyed") if self.tests: destroy = True @@ -79,15 +78,33 @@ meta.Base.metadata.create_all(checkfirst=checkfirst) log.info('Created tables for %s', self.dbname) - def admin_prompt(self): + def admin_prompt(self, second=False): if not self.tests: import getpass + + + def get_password(): + password = getpass.getpass('Specify admin password (min 6 chars):') + confirm = getpass.getpass('Confirm password:') + + if password != confirm: + log.error('passwords mismatch') + return False + if len(password) < 6: + log.error('password is to short use at least 6 characters') + return False + + return password + username = raw_input('Specify admin username:') - password = getpass.getpass('Specify admin password:') - confirm = getpass.getpass('Confirm password:') - if password != confirm: - log.error('passwords mismatch') - sys.exit() + + password = get_password() + if not password: + #second try + password = get_password() + if not password: + sys.exit() + email = raw_input('Specify admin email:') self.create_user(username, password, email, True) else:
--- a/rhodecode/lib/helpers.py Tue Oct 12 16:49:28 2010 +0200 +++ b/rhodecode/lib/helpers.py Mon Oct 18 15:29:56 2010 +0200 @@ -28,8 +28,8 @@ class _Link(object): ''' Make a url based on label and url with help of url_for - @param label:name of link if not defined url is used - @param url: the url for link + :param label:name of link if not defined url is used + :param url: the url for link ''' def __call__(self, label='', *url_, **urlargs): @@ -52,8 +52,8 @@ def recursive_replace(str, replace=' '): """ Recursive replace of given sign to just one instance - @param str: given string - @param replace:char to find and replace multiple instances + :param str: given string + :param replace:char to find and replace multiple instances Examples:: >>> recursive_replace("Mighty---Mighty-Bo--sstones",'-') @@ -72,7 +72,7 @@ """ Special function just to wrap our text into nice formatted autowrapped text - @param tooltip_title: + :param tooltip_title: """ return wrap_paragraphs(escape(tooltip_title), trim_at)\ @@ -226,7 +226,7 @@ def pygmentize(filenode, **kwargs): """ pygmentize function using pygments - @param filenode: + :param filenode: """ return literal(code_highlight(filenode.content, filenode.lexer, CodeHtmlFormatter(**kwargs))) @@ -234,7 +234,7 @@ def pygmentize_annotation(filenode, **kwargs): """ pygmentize function for annotation - @param filenode: + :param filenode: """ color_dict = {}
--- a/rhodecode/lib/hooks.py Tue Oct 12 16:49:28 2010 +0200 +++ b/rhodecode/lib/hooks.py Mon Oct 18 15:29:56 2010 +0200 @@ -53,9 +53,9 @@ def user_action_mapper(ui, repo, hooktype=None, **kwargs): """ Maps user last push action to new changeset id, from mercurial - @param ui: - @param repo: - @param hooktype: + :param ui: + :param repo: + :param hooktype: """ try:
--- a/rhodecode/lib/indexers/__init__.py Tue Oct 12 16:49:28 2010 +0200 +++ b/rhodecode/lib/indexers/__init__.py Mon Oct 18 15:29:56 2010 +0200 @@ -115,8 +115,8 @@ Smart function that implements chunking the content but not overlap chunks so it doesn't highlight the same close occurrences twice. - @param matcher: - @param size: + :param matcher: + :param size: """ memory = [(0, 0)] for span in self.matcher.spans():
--- a/rhodecode/lib/indexers/daemon.py Tue Oct 12 16:49:28 2010 +0200 +++ b/rhodecode/lib/indexers/daemon.py Mon Oct 18 15:29:56 2010 +0200 @@ -86,8 +86,9 @@ based on repository walk function """ index_paths_ = set() + tip = repo.get_changeset() try: - for topnode, dirs, files in repo.walk('/', 'tip'): + for topnode, dirs, files in tip.walk('/'): for f in files: index_paths_.add(jn(repo.path, f.path)) for dir in dirs:
--- a/rhodecode/lib/middleware/simplehg.py Tue Oct 12 16:49:28 2010 +0200 +++ b/rhodecode/lib/middleware/simplehg.py Mon Oct 18 15:29:56 2010 +0200 @@ -39,7 +39,7 @@ import logging import os import traceback - + log = logging.getLogger(__name__) class SimpleHg(object): @@ -49,7 +49,7 @@ self.config = config #authenticate this mercurial request using self.authenticate = AuthBasicAuthenticator('', authfunc) - + def __call__(self, environ, start_response): if not is_mercurial(environ): return self.application(environ, start_response) @@ -66,7 +66,7 @@ REMOTE_USER.update(environ, result) else: return result.wsgi_application(environ, start_response) - + try: repo_name = '/'.join(environ['PATH_INFO'].split('/')[1:]) if repo_name.endswith('/'): @@ -74,7 +74,7 @@ except: log.error(traceback.format_exc()) return HTTPInternalServerError()(environ, start_response) - + #=================================================================== # CHECK PERMISSIONS FOR THIS REQUEST #=================================================================== @@ -86,25 +86,29 @@ except: log.error(traceback.format_exc()) return HTTPInternalServerError()(environ, start_response) + #check permissions for this repository - if action == 'pull': + if action == 'push': + if not HasPermissionAnyMiddleware('repository.write', + 'repository.admin')\ + (user, repo_name): + return HTTPForbidden()(environ, start_response) + + else: + #any other action need at least read permission if not HasPermissionAnyMiddleware('repository.read', 'repository.write', 'repository.admin')\ (user, repo_name): return HTTPForbidden()(environ, start_response) - if action == 'push': - if not HasPermissionAnyMiddleware('repository.write', - 'repository.admin')\ - (user, repo_name): - return HTTPForbidden()(environ, start_response) - - #log action - proxy_key = 'HTTP_X_REAL_IP' - def_key = 'REMOTE_ADDR' - ipaddr = environ.get(proxy_key, environ.get(def_key, '0.0.0.0')) - self.__log_user_action(user, action, repo_name, ipaddr) - + + #log action + if action in ('push', 'pull', 'clone'): + proxy_key = 'HTTP_X_REAL_IP' + def_key = 'REMOTE_ADDR' + ipaddr = environ.get(proxy_key, environ.get(def_key, '0.0.0.0')) + self.__log_user_action(user, action, repo_name, ipaddr) + #=================================================================== # MERCURIAL REQUEST HANDLING #=================================================================== @@ -124,16 +128,16 @@ except Exception: log.error(traceback.format_exc()) return HTTPInternalServerError()(environ, start_response) - + #invalidate cache on push if action == 'push': self.__invalidate_cache(repo_name) messages = [] messages.append('thank you for using rhodecode') - + return self.msg_wrapper(app, environ, start_response, messages) else: - return app(environ, start_response) + return app(environ, start_response) def msg_wrapper(self, app, environ, start_response, messages=[]): @@ -141,9 +145,9 @@ Wrapper for custom messages that come out of mercurial respond messages is a list of messages that the user will see at the end of response from merurial protocol actions that involves remote answers - @param app: - @param environ: - @param start_response: + :param app: + :param environ: + :param start_response: """ def custom_messages(msg_list): for msg in msg_list: @@ -154,68 +158,70 @@ def __make_app(self): hgserve = hgweb(str(self.repo_path), baseui=self.baseui) return self.__load_web_settings(hgserve) - + def __get_environ_user(self, environ): return environ.get('REMOTE_USER') - + def __get_user(self, username): return get_user_cached(username) - + def __get_action(self, environ): """ - Maps mercurial request commands into a pull or push command. - @param environ: + Maps mercurial request commands into a clone,pull or push command. + This should always return a valid command string + :param environ: """ mapping = {'changegroup': 'pull', 'changegroupsubset': 'pull', 'stream_out': 'pull', - 'listkeys': 'pull', + #'listkeys': 'pull', 'unbundle': 'push', 'pushkey': 'push', } - for qry in environ['QUERY_STRING'].split('&'): if qry.startswith('cmd'): cmd = qry.split('=')[-1] if mapping.has_key(cmd): return mapping[cmd] - + else: + return cmd + def __log_user_action(self, user, action, repo, ipaddr): action_logger(user, action, repo, ipaddr) - + def __invalidate_cache(self, repo_name): """we know that some change was made to repositories and we should invalidate the cache to see the changes right away but only for push requests""" invalidate_cache('cached_repo_list') invalidate_cache('full_changelog', repo_name) - - + + def __load_web_settings(self, hgserve): - #set the global ui for hgserve + #set the global ui for hgserve instance passed hgserve.repo.ui = self.baseui - + hgrc = os.path.join(self.repo_path, '.hg', 'hgrc') repoui = make_ui('file', hgrc, False) - - + + if repoui: #overwrite our ui instance with the section from hgrc file for section in ui_sections: for k, v in repoui.configitems(section): hgserve.repo.ui.setconfig(section, k, v) - + return hgserve - - - - - - - - - - - - - - + + + + + + + + + + + + + +
--- a/rhodecode/lib/pidlock.py Tue Oct 12 16:49:28 2010 +0200 +++ b/rhodecode/lib/pidlock.py Mon Oct 18 15:29:56 2010 +0200 @@ -109,8 +109,8 @@ def makelock(self, lockname, pidfile): """ this function will make an actual lock - @param lockname: acctual pid of file - @param pidfile: the file to write the pid in + :param lockname: acctual pid of file + :param pidfile: the file to write the pid in """ if self.debug: print 'creating a file %s and pid: %s' % (pidfile, lockname)
--- a/rhodecode/lib/smtp_mailer.py Tue Oct 12 16:49:28 2010 +0200 +++ b/rhodecode/lib/smtp_mailer.py Mon Oct 18 15:29:56 2010 +0200 @@ -108,7 +108,7 @@ ''' Get content based on type, if content is a string do open first else just read because it's a probably open file object - @param msg_file: + :param msg_file: ''' if isinstance(msg_file, str): return open(msg_file, "rb").read()
--- a/rhodecode/lib/utils.py Tue Oct 12 16:49:28 2010 +0200 +++ b/rhodecode/lib/utils.py Mon Oct 18 15:29:56 2010 +0200 @@ -36,7 +36,7 @@ log = logging.getLogger(__name__) -def get_repo_slug(request): +def get_repo_slug(request): return request.environ['pylons.routes_dict'].get('repo_name') def is_mercurial(environ): @@ -49,14 +49,26 @@ return True return False +def is_git(environ): + """ + Returns True if request's target is git server. ``HTTP_USER_AGENT`` would + then have git client version given. + + :param environ: + """ + http_user_agent = environ.get('HTTP_USER_AGENT') + if http_user_agent.startswith('git'): + return True + return False + def action_logger(user, action, repo, ipaddr, sa=None): """ Action logger for various action made by users """ - + if not sa: - sa = meta.Session - + sa = meta.Session + try: if hasattr(user, 'user_id'): user_id = user.user_id @@ -64,7 +76,7 @@ user_id = sa.query(User).filter(User.username == user).one() else: raise Exception('You have to provide user object or username') - + repo_name = repo.lstrip('/') user_log = UserLog() user_log.user_id = user_id @@ -82,7 +94,7 @@ raise sa.rollback() log.error('could not log user action:%s', str(e)) - + def check_repo_dir(paths): repos_path = paths[0][1].split('/') if repos_path[-1] in ['*', '**']: @@ -122,7 +134,7 @@ retries = retries - 1 if retries < 0: raise IOError print complaint - + @cache_region('super_short_term', 'cached_hg_ui') def get_hg_ui_cached(): try: @@ -139,13 +151,13 @@ ret = sa.query(RhodeCodeSettings).all() finally: meta.Session.remove() - + if not ret: raise Exception('Could not get application settings !') settings = {} for each in ret: - settings['rhodecode_' + each.app_settings_name] = each.app_settings_value - + settings['rhodecode_' + each.app_settings_name] = each.app_settings_value + return settings def get_hg_ui_settings(): @@ -154,7 +166,7 @@ ret = sa.query(RhodeCodeUi).all() finally: meta.Session.remove() - + if not ret: raise Exception('Could not get application ui settings !') settings = {} @@ -163,15 +175,15 @@ v = each.ui_value if k == '/': k = 'root_path' - + if k.find('.') != -1: k = k.replace('.', '_') - + if each.ui_section == 'hooks': v = each.ui_active - - settings[each.ui_section + '_' + k] = v - + + settings[each.ui_section + '_' + k] = v + return settings #propagated from mercurial documentation @@ -185,15 +197,15 @@ 'paths', 'profiling', 'server', 'trusted', 'ui', 'web', ] - -def make_ui(read_from='file', path=None, checkpaths=True): + +def make_ui(read_from='file', path=None, checkpaths=True): """ A function that will read python rc files or database and make an mercurial ui object from read options - @param path: path to mercurial config file - @param checkpaths: check the path - @param read_from: read from 'file' or 'db' + :param path: path to mercurial config file + :param checkpaths: check the path + :param read_from: read from 'file' or 'db' """ baseui = ui.ui() @@ -209,52 +221,52 @@ for k, v in cfg.items(section): baseui.setconfig(section, k, v) log.debug('settings ui from file[%s]%s:%s', section, k, v) - if checkpaths:check_repo_dir(cfg.items('paths')) - - + if checkpaths:check_repo_dir(cfg.items('paths')) + + elif read_from == 'db': hg_ui = get_hg_ui_cached() for ui_ in hg_ui: if ui_.ui_active: log.debug('settings ui from db[%s]%s:%s', ui_.ui_section, ui_.ui_key, ui_.ui_value) baseui.setconfig(ui_.ui_section, ui_.ui_key, ui_.ui_value) - - + + return baseui def set_rhodecode_config(config): hgsettings = get_hg_settings() - + for k, v in hgsettings.items(): config[k] = v def invalidate_cache(name, *args): """Invalidates given name cache""" - + from beaker.cache import region_invalidate log.info('INVALIDATING CACHE FOR %s', name) - + """propagate our arguments to make sure invalidation works. First argument has to be the name of cached func name give to cache decorator without that the invalidation would not work""" tmp = [name] tmp.extend(args) args = tuple(tmp) - + if name == 'cached_repo_list': from rhodecode.model.hg_model import _get_repos_cached region_invalidate(_get_repos_cached, None, *args) - + if name == 'full_changelog': from rhodecode.model.hg_model import _full_changelog_cached region_invalidate(_full_changelog_cached, None, *args) - + class EmptyChangeset(BaseChangeset): """ An dummy empty changeset. """ - + revision = -1 message = '' author = '' @@ -266,35 +278,35 @@ representation. """ return '0' * 40 - + @LazyProperty def short_id(self): return self.raw_id[:12] def get_file_changeset(self, path): return self - + def get_file_content(self, path): return u'' - + def get_file_size(self, path): return 0 - + def repo2db_mapper(initial_repo_list, remove_obsolete=False): """ maps all found repositories into db """ from rhodecode.model.repo_model import RepoModel - + sa = meta.Session user = sa.query(User).filter(User.admin == True).first() - + rm = RepoModel() - + for name, repo in initial_repo_list.items(): if not sa.query(Repository).filter(Repository.repo_name == name).scalar(): log.info('repository %s not found creating default', name) - + form_data = { 'repo_name':name, 'description':repo.description if repo.description != 'unknown' else \ @@ -311,7 +323,7 @@ sa.delete(repo) sa.commit() - + meta.Session.remove() from UserDict import DictMixin @@ -421,25 +433,25 @@ #=============================================================================== def create_test_index(repo_location, full_index): """Makes default test index - @param repo_location: - @param full_index: + :param repo_location: + :param full_index: """ from rhodecode.lib.indexers.daemon import WhooshIndexingDaemon from rhodecode.lib.pidlock import DaemonLock, LockHeld from rhodecode.lib.indexers import IDX_LOCATION import shutil - + if os.path.exists(IDX_LOCATION): shutil.rmtree(IDX_LOCATION) - + try: l = DaemonLock() WhooshIndexingDaemon(repo_location=repo_location)\ .run(full_index=full_index) l.release() except LockHeld: - pass - + pass + def create_test_env(repos_test_path, config): """Makes a fresh database and install test repository into tmp dir @@ -448,7 +460,7 @@ import tarfile import shutil from os.path import dirname as dn, join as jn, abspath - + log = logging.getLogger('TestEnvCreator') # create logger log.setLevel(logging.DEBUG) @@ -456,20 +468,20 @@ # create console handler and set level to debug ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) - + # create formatter formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") - + # add formatter to ch ch.setFormatter(formatter) - + # add ch to logger log.addHandler(ch) - + #PART ONE create db dbname = config['sqlalchemy.db1.url'].split('/')[-1] log.debug('making test db %s', dbname) - + dbmanage = DbManage(log_sql=True, dbname=dbname, root=config['here'], tests=True) dbmanage.create_tables(override=True) @@ -478,12 +490,12 @@ dbmanage.admin_prompt() dbmanage.create_permissions() dbmanage.populate_default_permissions() - + #PART TWO make test repo log.debug('making test vcs repo') if os.path.isdir('/tmp/vcs_test'): shutil.rmtree('/tmp/vcs_test') - + cur_dir = dn(dn(abspath(__file__))) tar = tarfile.open(jn(cur_dir, 'tests', "vcs_test.tar.gz")) tar.extractall('/tmp')
--- a/rhodecode/model/meta.py Tue Oct 12 16:49:28 2010 +0200 +++ b/rhodecode/model/meta.py Mon Oct 18 15:29:56 2010 +0200 @@ -3,9 +3,6 @@ from sqlalchemy.orm import scoped_session, sessionmaker from rhodecode.model import caching_query from beaker import cache -import os -from os.path import join as jn, dirname as dn, abspath -import time # Beaker CacheManager. A home base for cache configurations. cache_manager = cache.CacheManager() @@ -25,9 +22,5 @@ #For another db... #Base2 = declarative_base() -#=============================================================================== -# CACHE OPTIONS -#=============================================================================== -#Configured globally in .ini files #to use cache use this in query #.options(FromCache("sqlalchemy_cache_type", "cachekey"))
--- a/rhodecode/public/css/style.css Tue Oct 12 16:49:28 2010 +0200 +++ b/rhodecode/public/css/style.css Mon Oct 18 15:29:56 2010 +0200 @@ -139,30 +139,6 @@ padding:0; } -div.color a.blue { -background:#376ea6; -} - -div.color a.green { -background:#85924b; -} - -div.color a.brown { -background:#9b6e42; -} - -div.color a.purple { -background:#88528b; -} - -div.color a.red { -background:#bd3220; -} - -div.color a.greyblue { -background:#566e86; -} - div.options { clear:both; overflow:hidden; @@ -180,6 +156,35 @@ padding:3px 8px; } +.top-left-rounded-corner { +-webkit-border-top-left-radius: 8px; +-khtml-border-radius-topleft: 8px; +-moz-border-radius-topleft: 8px; +border-top-left-radius: 8px; +} + +.top-right-rounded-corner { +-webkit-border-top-right-radius: 8px; +-khtml-border-radius-topright: 8px; +-moz-border-radius-topright: 8px; +border-top-right-radius: 8px; +} + +.bottom-left-rounded-corner { +-webkit-border-bottom-left-radius: 8px; +-khtml-border-radius-bottomleft: 8px; +-moz-border-radius-bottomleft: 8px; +border-bottom-left-radius: 8px; +} + +.bottom-right-rounded-corner { +-webkit-border-bottom-right-radius: 8px; +-khtml-border-radius-bottomright: 8px; +-moz-border-radius-bottomright: 8px; +border-bottom-right-radius: 8px; +} + + #header { margin:0; padding:0 30px; @@ -357,7 +362,6 @@ max-height:275px; overflow-x:hidden; overflow-y:auto; -white-space:nowrap; } #header #header-inner #quick li ul li { @@ -376,22 +380,11 @@ padding:7px 9px; } -#header #header-inner #quick li ul li a.childs { -width:167px; -background:#FFF url("../../resources/images/plus.png") no-repeat 8px 9px; -margin:0; -padding:7px 9px 7px 24px; -} - #header #header-inner #quick li ul li a:hover { color:#000; background:#FFF; } -#header #header-inner #quick li ul li a.childs:hover { -background:#FFF url("../../resources/images/minus.png") no-repeat 8px 9px; -} - #header #header-inner #quick ul ul { top:auto; } @@ -488,184 +481,12 @@ padding:12px 9px 7px 24px; } -#header #header-inner div.corner { -height:6px; -width:6px; -position:absolute; -background:url("../../images/header_inner_corners.png") no-repeat; -} - #content #left { left:0; width:280px; position:absolute; } -#content #left #menu { -clear:both; -overflow:hidden; -margin:5px 10px 0 60px; -padding:0; -} - -#content #left #menu h6 { -clear:both; -overflow:hidden; -background:#dfdfdf url("../images/menu.png") repeat-x; -color:#6e6e6e; -margin:5px 0 0; -padding:0; -} - -#content #left #menu h6 a { -height:1%; -display:block; -clear:both; -overflow:hidden; -background:url("../images/menu_l.png") no-repeat top left; -color:#6e6e6e; -text-decoration:none; -margin:0; -padding:0; -} - -#content #left #menu h6 span { -height:1%; -display:block; -background:url("../images/menu_r.png") no-repeat top right; -margin:0; -padding:9px 10px 10px; -} - -#content #left #menu h6.selected { -color:#FFF; -background:#00376e url("../../images/menu_selected.png") repeat-x; -} - -#content #left #menu h6.selected a { -color:#fff; -background:url("../../images/menu_l_selected.png") no-repeat top left; -} - -#content #left #menu h6.selected span { -background:url("../../images/menu_r_selected.png") no-repeat top right; -} - -#content #left #menu ul { -background:#376ea6; -margin:0; -padding:0; -} - -#content #left #menu li { -clear:both; -overflow:hidden; -list-style:none; -color:#fff; -border-top:1px solid #4377ab; -border-bottom:1px solid #326395; -margin:0; -padding:0; -} - -#content #left #menu li a { -height:1%; -display:block; -float:left; -color:#fff; -text-decoration:none; -background:url("../../images/menu_arrow.png") no-repeat 0 9px; -margin:0 0 0 6px; -padding:8px 0 8px 18px; -} - -#content #left #menu li a:hover { -color:#b9dcff; -} - -#content #left #menu li.collapsible { -background:url("../../images/menu_border.png") no-repeat top left; -} - -#content #left #menu li.collapsible a { -height:1%; -display:block; -background:transparent; -float:left; -font-weight:700; -margin:0 0 0 6px; -padding:8px 0; -} - -#content #left #menu li.collapsible a.plus { -height:10px; -width:10px; -display:block; -float:left; -background:url("../images/menu_plus.png") no-repeat 5px 10px; -border:none; -margin:0; -padding:8px 0 9px 24px; -} - -#content #left #menu li.collapsible a.minus { -height:10px; -width:10px; -display:block; -float:left; -background:url("../images/menu_minus.png") no-repeat 5px 10px; -border:none; -border-bottom:1px solid #326395; -margin:0; -padding:8px 0 9px 24px; -} - -#content #left #menu li ul { -border-left:18px solid #326395; -margin:0; -padding:0; -} - -#content #left #menu li ul li { -clear:both; -overflow:hidden; -list-style:none; -color:#fff; -background:url("../../images/menu_arrow.png") no-repeat 10px 9px; -border-top:1px solid #4377ab; -border-bottom:1px solid #326395; -margin:0; -padding:0; -} - -#content #left #menu li.collapsible ul li a { -font-weight:400; -} - -#content #left #menu li.last { -border-bottom:none; -} - -#content #left #date-picker { -clear:both; -overflow:hidden; -margin:10px 10px 0 60px; -padding:0; -} - -#content #left #date-picker .ui-datepicker { -width:auto; -clear:both; -overflow:hidden; -background:#FFF; -border:1px solid #d1d1d1; -padding:0; -} - -#content #left #date-picker .ui-datepicker .ui-datepicker-header { -padding:5px 0; -} - #content #right { margin:0 60px 10px 290px; } @@ -1036,10 +857,6 @@ padding:4px 8px; } -#content div.box div.form div.fields div.field div.input img.ui-datepicker-trigger { -margin:0 0 0 6px; -} - #content div.box div.form div.fields div.field div.input a.ui-input-file { width:28px; height:28px; @@ -1054,10 +871,6 @@ padding:0; } -#content div.box div.form div.fields div.field div.input a:hover.ui-input-file { -background:#e5e3e3 url("../images/button_browse_selected.png") no-repeat; -} - #content div.box div.form div.fields div.field div.textarea { border-top:1px solid #b3b3b3; border-left:1px solid #b3b3b3; @@ -1091,24 +904,6 @@ height:100px; } -#content div.box div.form div.fields div.field div.textarea textarea.error { -background-color:#FBE3E4; -background-image:url("../../../resources/images/icons/exclamation.png"); -background-repeat:no-repeat; -background-position:3px 3px; -border:1px solid #FBC2C4; -padding:3px 10px 10px 23px; -} - -#content div.box div.form div.fields div.field div.textarea textarea.success { -background-color:#E6EFC2; -background-image:url("../../../resources/images/icons/accept.png"); -background-repeat:no-repeat; -background-position:3px 3px; -border:1px solid #C6D880; -padding:3px 10px 10px 23px; -} - #content div.box div.form div.fields div.field div.textarea table { width:100%; border:none; @@ -1441,11 +1236,14 @@ padding:0 30px; } -#footer p { -background:none repeat scroll 0 0 #2F2F2F; +#footer div#footer-inner { +background:url("../images/header_inner.png") repeat-x scroll 0 0 #003367; +} + +#footer div#footer-inner p { +padding:15px 25px 15px 0; color:#FFF; font-weight:700; -padding:15px 25px 15px 0; } #login div.title { @@ -1458,13 +1256,6 @@ padding:0; } -#login div.title div.corner { -height:6px; -width:6px; -position:absolute; -background:url("../../images/login_corners.png") no-repeat; -} - #login div.inner { width:380px; background:#FFF url("../images/login.png") no-repeat top left; @@ -1522,13 +1313,6 @@ padding:0; } -#register div.title div.corner { -height:6px; -width:6px; -position:absolute; -background:url("../images/login_corners.png") no-repeat; -} - #register div.inner { width:380px; background:#FFF; @@ -1589,11 +1373,7 @@ } .trending_language { --moz-border-radius-bottomright:4px; --moz-border-radius-topright:4px; -border-bottom-right-radius:4px 4px; -border-top-right-radius:4px 4px; -background-color:#369; +background-color:#003367; color:#FFF; display:block; min-width:20px; @@ -1649,7 +1429,7 @@ } .cs_files .cs_added { -background:url("/images/icons/page_white_add.png") no-repeat scroll 3px; +background:url("../images/icons/page_white_add.png") no-repeat scroll 3px; height:16px; padding-left:20px; margin-top:7px; @@ -1657,7 +1437,7 @@ } .cs_files .cs_changed { -background:url("/images/icons/page_white_edit.png") no-repeat scroll 3px; +background:url("../images/icons/page_white_edit.png") no-repeat scroll 3px; height:16px; padding-left:20px; margin-top:7px; @@ -1665,7 +1445,7 @@ } .cs_files .cs_removed { -background:url("/images/icons/page_white_delete.png") no-repeat scroll 3px; +background:url("../images/icons/page_white_delete.png") no-repeat scroll 3px; height:16px; padding-left:20px; margin-top:7px; @@ -1816,14 +1596,14 @@ } table.code-browser .browser-file { -background:url("/images/icons/document_16.png") no-repeat scroll 3px; +background:url("../images/icons/document_16.png") no-repeat scroll 3px; height:16px; padding-left:20px; text-align:left; } table.code-browser .browser-dir { -background:url("/images/icons/folder_16.png") no-repeat scroll 3px; +background:url("../images/icons/folder_16.png") no-repeat scroll 3px; height:16px; padding-left:20px; text-align:left; @@ -1974,7 +1754,7 @@ } .add_icon { -background:url("/images/icons/add.png") no-repeat scroll 3px; +background:url("../images/icons/add.png") no-repeat scroll 3px; height:16px; padding-left:20px; padding-top:1px; @@ -1982,7 +1762,7 @@ } .edit_icon { -background:url("/images/icons/folder_edit.png") no-repeat scroll 3px; +background:url("../images/icons/folder_edit.png") no-repeat scroll 3px; height:16px; padding-left:20px; padding-top:1px; @@ -1990,7 +1770,7 @@ } .delete_icon { -background:url("/images/icons/delete.png") no-repeat scroll 3px; +background:url("../images/icons/delete.png") no-repeat scroll 3px; height:16px; padding-left:20px; padding-top:1px; @@ -1998,7 +1778,7 @@ } .rss_icon { -background:url("/images/icons/rss_16.png") no-repeat scroll 3px; +background:url("../images/icons/rss_16.png") no-repeat scroll 3px; height:16px; padding-left:20px; padding-top:1px; @@ -2006,7 +1786,7 @@ } .atom_icon { -background:url("/images/icons/atom.png") no-repeat scroll 3px; +background:url("../images/icons/atom.png") no-repeat scroll 3px; height:16px; padding-left:20px; padding-top:1px; @@ -2014,7 +1794,7 @@ } .archive_icon { -background:url("/images/icons/compress.png") no-repeat scroll 3px; +background:url("../images/icons/compress.png") no-repeat scroll 3px; height:16px; padding-left:20px; text-align:left; @@ -2153,7 +1933,7 @@ min-height:100%; clear:both; overflow:hidden; -padding:10px 30px; +padding:14px 30px; } #content div.box div.title div.search { @@ -2227,28 +2007,6 @@ display:block; } -#header #header-inner div.tl,#login div.title div.tl,#register div.title div.tl { -top:0; -left:0; -background-position:0 0; -} - -#header #header-inner div.tr,#login div.title div.tr,#register div.title div.tr { -top:0; -right:0; -background-position:-6px 0; -} - -#content #left #date-picker .ui-datepicker .ui-datepicker-prev,#content #left #date-picker .ui-datepicker .ui-datepicker-prev-hover { -top:5px; -left:4px; -} - -#content #left #date-picker .ui-datepicker .ui-datepicker-next,#content #left #date-picker .ui-datepicker .ui-datepicker-next-hover { -top:5px; -right:4px; -} - #content div.box div.title ul.links li a:hover,#content div.box div.title ul.links li.ui-tabs-selected a { background:url("../../images/title_tab_selected.png") no-repeat bottom center; color:#bfe3ff; @@ -2318,10 +2076,6 @@ border:1px solid #666; } -#content div.box div.form div.fields div.field div.select a.ui-selectmenu-focus span.ui-icon,#content div.box div.action a.ui-selectmenu-focus span.ui-icon { -background-image:url(../images/ui/ui-icons_222222_256x240.png); -} - #content div.box div.form div.fields div.field div.checkboxes div.checkbox,#content div.box div.form div.fields div.field div.radios div.radio { clear:both; overflow:hidden;
--- a/rhodecode/templates/base/base.html Tue Oct 12 16:49:28 2010 +0200 +++ b/rhodecode/templates/base/base.html Mon Oct 18 15:29:56 2010 +0200 @@ -28,17 +28,15 @@ <li class="last highlight">${h.link_to(u'Logout',h.url('logout_home'))}</li> </ul> <!-- end user --> - <div id="header-inner"> + <div id="header-inner" class="title top-left-rounded-corner top-right-rounded-corner"> <!-- logo --> <div id="logo"> <h1><a href="${h.url('hg_home')}">${c.rhodecode_name}</a></h1> </div> <!-- end logo --> - <!-- quick menu --> + <!-- menu --> ${self.page_nav()} - <!-- end quick --> - <div class="corner tl"></div> - <div class="corner tr"></div> + <!-- quick --> </div> </div> <!-- end header --> @@ -63,8 +61,10 @@ <!-- footer --> <div id="footer"> + <div id="footer-inner" class="title bottom-left-rounded-corner bottom-right-rounded-corner"> <p>RhodeCode ${c.rhodecode_version} © 2010 by Marcin Kuzminski</p> - <script type="text/javascript">${h.tooltip.activate()}</script> + </div> + <script type="text/javascript">${h.tooltip.activate()}</script> </div> <!-- end footer --> </body>
--- a/rhodecode/templates/login.html Tue Oct 12 16:49:28 2010 +0200 +++ b/rhodecode/templates/login.html Mon Oct 18 15:29:56 2010 +0200 @@ -8,20 +8,14 @@ <meta name="robots" content="index, nofollow"/> <!-- stylesheets --> - <link rel="stylesheet" type="text/css" href="/css/reset.css" /> <link rel="stylesheet" type="text/css" href="/css/style.css" media="screen" /> - <link id="color" rel="stylesheet" type="text/css" href="/css/colors/blue.css" /> - - <!-- scripts --> </head> <body> <div id="login"> <!-- login --> - <div class="title"> + <div class="title top-left-rounded-corner top-right-rounded-corner"> <h5>${_('Sign In to rhodecode')}</h5> - <div class="corner tl"></div> - <div class="corner tr"></div> </div> <div class="inner"> ${h.form(h.url.current(came_from=c.came_from))}
--- a/rhodecode/templates/password_reset.html Tue Oct 12 16:49:28 2010 +0200 +++ b/rhodecode/templates/password_reset.html Mon Oct 18 15:29:56 2010 +0200 @@ -8,20 +8,14 @@ <meta name="robots" content="index, nofollow"/> <!-- stylesheets --> - <link rel="stylesheet" type="text/css" href="/css/reset.css" /> <link rel="stylesheet" type="text/css" href="/css/style.css" media="screen" /> - <link id="color" rel="stylesheet" type="text/css" href="/css/colors/blue.css" /> - - <!-- scripts --> </head> <body> <div id="register"> - <div class="title"> + <div class="title top-left-rounded-corner top-right-rounded-corner"> <h5>${_('Reset You password to rhodecode')}</h5> - <div class="corner tl"></div> - <div class="corner tr"></div> </div> <div class="inner"> ${h.form(url('password_reset'))}
--- a/rhodecode/templates/register.html Tue Oct 12 16:49:28 2010 +0200 +++ b/rhodecode/templates/register.html Mon Oct 18 15:29:56 2010 +0200 @@ -8,20 +8,14 @@ <meta name="robots" content="index, nofollow"/> <!-- stylesheets --> - <link rel="stylesheet" type="text/css" href="/css/reset.css" /> <link rel="stylesheet" type="text/css" href="/css/style.css" media="screen" /> - <link id="color" rel="stylesheet" type="text/css" href="/css/colors/blue.css" /> - - <!-- scripts --> </head> <body> <div id="register"> - <div class="title"> + <div class="title top-left-rounded-corner top-right-rounded-corner"> <h5>${_('Sign Up to rhodecode')}</h5> - <div class="corner tl"></div> - <div class="corner tr"></div> </div> <div class="inner"> ${h.form(url('register'))}
--- a/rhodecode/templates/summary/summary.html Tue Oct 12 16:49:28 2010 +0200 +++ b/rhodecode/templates/summary/summary.html Mon Oct 18 15:29:56 2010 +0200 @@ -139,7 +139,7 @@ var trending_language = document.createElement('div'); trending_language.title = k; trending_language.innerHTML = "<b>"+percentage+"% "+value+" ${_('files')}</b>"; - trending_language.setAttribute("class", 'trending_language'); + trending_language.setAttribute("class", 'trending_language top-right-rounded-corner bottom-right-rounded-corner'); trending_language.style.width=percentage+"%"; td2.appendChild(trending_language);
--- a/setup.cfg Tue Oct 12 16:49:28 2010 +0200 +++ b/setup.cfg Mon Oct 18 15:29:56 2010 +0200 @@ -1,5 +1,5 @@ [egg_info] -tag_build = rc3 +tag_build = rc4 tag_svn_revision = true [easy_install] @@ -32,3 +32,11 @@ input_file = rhodecode/i18n/rhodecode.pot output_dir = rhodecode/i18n previous = true + +[build_sphinx] +source-dir = docs/ +build-dir = docs/_build +all_files = 1 + +[upload_sphinx] +upload-dir = docs/_build/html \ No newline at end of file