changeset 1231:9f6560667743

fixes for stable
author Marcin Kuzminski <marcin@python-works.com>
date Sat, 09 Apr 2011 17:13:15 +0200
parents 73434499fa72
children 0dc8d578ff49
files docs/changelog.rst rhodecode/lib/dbmigrate/versions/002_version_1_1_0.py rhodecode/lib/helpers.py rhodecode/lib/hooks.py rhodecode/lib/indexers/__init__.py rhodecode/lib/middleware/simplehg.py rhodecode/lib/profiler.py rhodecode/lib/smtp_mailer.py rhodecode/lib/utils.py test.ini
diffstat 10 files changed, 119 insertions(+), 85 deletions(-) [+]
line wrap: on
line diff
--- a/docs/changelog.rst	Sat Apr 09 11:22:32 2011 +0200
+++ b/docs/changelog.rst	Sat Apr 09 17:13:15 2011 +0200
@@ -17,13 +17,17 @@
   incompatible
 - setup-app will check for write permission in given path
 - cleaned up license info issue #149
-- fixes for issues #137 and #116
+- fixes for issues #137,#116 and #116, problems with unicode and 
+  accented characters.
 - fixes crashes on gravatar, when passed in email as unicode
 - fixed tooltip flickering problems
 - fixed came_from redirection on windows
 - fixed logging modules,and sql formatters
-- windows fixes for os.kill and path spliting, issues #148 and #133
+- windows fixes for os.kill #133
+- fixes path splitting for windows issues #148
+- fixed issue #143 wrong import on migration to 1.1.X
 
+ 
 1.1.7 (**2011-03-23**)
 ======================
 
--- a/rhodecode/lib/dbmigrate/versions/002_version_1_1_0.py	Sat Apr 09 11:22:32 2011 +0200
+++ b/rhodecode/lib/dbmigrate/versions/002_version_1_1_0.py	Sat Apr 09 17:13:15 2011 +0200
@@ -6,14 +6,14 @@
 from sqlalchemy.orm import relation, backref, class_mapper
 from sqlalchemy.orm.session import Session
 from rhodecode.model.meta import Base
-from rhodecode.model.db import BaseModel
 
 from rhodecode.lib.dbmigrate.migrate import *
+from rhodecode.lib.dbmigrate.migrate.changeset import *
 
 log = logging.getLogger(__name__)
 
 def upgrade(migrate_engine):
-    """ Upgrade operations go here. 
+    """ Upgrade operations go here.
     Don't create your own engine; bind migrate_engine to your metadata
     """
 
@@ -32,7 +32,7 @@
 
     #==========================================================================
     # Upgrade of `user_logs` table
-    #==========================================================================    
+    #==========================================================================
 
     tblname = 'users'
     tbl = Table(tblname, MetaData(bind=migrate_engine), autoload=True,
@@ -48,7 +48,7 @@
 
     #==========================================================================
     # Upgrade of `repositories` table
-    #==========================================================================    
+    #==========================================================================
     tblname = 'repositories'
     tbl = Table(tblname, MetaData(bind=migrate_engine), autoload=True,
                     autoload_with=migrate_engine)
@@ -69,8 +69,6 @@
     #==========================================================================
     # Add table `user_followings`
     #==========================================================================
-    tblname = 'user_followings'
-
     class UserFollowing(Base, BaseModel):
         __tablename__ = 'user_followings'
         __table_args__ = (UniqueConstraint('user_id', 'follows_repository_id'),
@@ -87,13 +85,11 @@
         follows_user = relation('User', primaryjoin='User.user_id==UserFollowing.follows_user_id')
         follows_repository = relation('Repository')
 
-    Base.metadata.tables[tblname].create(migrate_engine)
+    UserFollowing().__table__.create()
 
     #==========================================================================
     # Add table `cache_invalidation`
     #==========================================================================
-    tblname = 'cache_invalidation'
-
     class CacheInvalidation(Base, BaseModel):
         __tablename__ = 'cache_invalidation'
         __table_args__ = (UniqueConstraint('cache_key'), {'useexisting':True})
@@ -110,18 +106,10 @@
 
         def __repr__(self):
             return "<CacheInvalidation('%s:%s')>" % (self.cache_id, self.cache_key)
-
-    Base.metadata.tables[tblname].create(migrate_engine)
+    CacheInvalidation().__table__.create()
 
     return
 
-
-
-
-
-
 def downgrade(migrate_engine):
     meta = MetaData()
     meta.bind = migrate_engine
-
-
--- a/rhodecode/lib/helpers.py	Sat Apr 09 11:22:32 2011 +0200
+++ b/rhodecode/lib/helpers.py	Sat Apr 09 17:13:15 2011 +0200
@@ -402,8 +402,6 @@
 #==============================================================================
 # GRAVATAR URL
 #==============================================================================
-import hashlib
-import urllib
 from pylons import request
 
 def gravatar_url(email_address, size=30):
--- a/rhodecode/lib/hooks.py	Sat Apr 09 11:22:32 2011 +0200
+++ b/rhodecode/lib/hooks.py	Sat Apr 09 17:13:15 2011 +0200
@@ -4,10 +4,10 @@
     ~~~~~~~~~~~~~~~~~~~
 
     Hooks runned by rhodecode
-    
+
     :created_on: Aug 6, 2010
     :author: marcink
-    :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>    
+    :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
@@ -34,7 +34,7 @@
 
 def repo_size(ui, repo, hooktype=None, **kwargs):
     """Presents size of repository after push
-    
+
     :param ui:
     :param repo:
     :param hooktype:
@@ -65,7 +65,7 @@
 
 def log_pull_action(ui, repo, **kwargs):
     """Logs user last pull action
-    
+
     :param ui:
     :param repo:
     """
@@ -81,7 +81,7 @@
 
 def log_push_action(ui, repo, **kwargs):
     """Maps user last push action to new changeset id, from mercurial
-    
+
     :param ui:
     :param repo:
     """
@@ -111,4 +111,3 @@
     action_logger(username, action, repository, extra_params['ip'])
 
     return 0
-
--- a/rhodecode/lib/indexers/__init__.py	Sat Apr 09 11:22:32 2011 +0200
+++ b/rhodecode/lib/indexers/__init__.py	Sat Apr 09 17:13:15 2011 +0200
@@ -1,3 +1,27 @@
+# -*- coding: utf-8 -*-
+"""
+    rhodecode.lib.indexers.__init__
+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    Whoosh indexing module for RhodeCode
+
+    :created_on: Aug 17, 2010
+    :author: marcink
+    :copyright: (C) 2009-2010 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 sys
 import traceback
@@ -6,6 +30,8 @@
 #to get the rhodecode import
 sys.path.append(dn(dn(dn(os.path.realpath(__file__)))))
 
+from string import strip
+
 from rhodecode.model import init_model
 from rhodecode.model.scm import ScmModel
 from rhodecode.config.environment import load_environment
@@ -135,10 +161,12 @@
         for docid in self.doc_ids:
             yield self.get_full_content(docid)
 
-    def __getslice__(self, i, j):
+    def __getitem__(self, key):
         """
         Slicing of resultWrapper
         """
+        i, j = key.start, key.stop
+
         slice = []
         for docid in self.doc_ids[i:j]:
             slice.append(self.get_full_content(docid))
--- a/rhodecode/lib/middleware/simplehg.py	Sat Apr 09 11:22:32 2011 +0200
+++ b/rhodecode/lib/middleware/simplehg.py	Sat Apr 09 17:13:15 2011 +0200
@@ -1,8 +1,16 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# middleware to handle mercurial api calls
-# Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
-#
+# -*- coding: utf-8 -*-
+"""
+    rhodecode.lib.middleware.simplehg
+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    SimpleHG middleware for handling mercurial protocol request
+    (push/clone etc.). It's implemented with basic auth function
+
+    :created_on: Apr 28, 2010
+    :author: marcink
+    :copyright: (C) 2009-2010 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
@@ -15,13 +23,11 @@
 #
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
-"""
-Created on 2010-04-28
 
-@author: marcink
-SimpleHG middleware for handling mercurial protocol request (push/clone etc.)
-It's implemented with basic auth function
-"""
+import os
+import logging
+import traceback
+
 from mercurial.error import RepoError
 from mercurial.hgweb import hgweb
 from mercurial.hgweb.request import wsgiapplication
--- a/rhodecode/lib/profiler.py	Sat Apr 09 11:22:32 2011 +0200
+++ b/rhodecode/lib/profiler.py	Sat Apr 09 17:13:15 2011 +0200
@@ -12,8 +12,8 @@
     def __init__(self, app):
         self.lock = threading.Lock()
         self.app = app
-    
-    
+
+
     def __call__(self, environ, start_response):
         with self.lock:
             profiler = cProfile.Profile()
@@ -41,13 +41,11 @@
                 ##  Browsers don't mind this.
                 resp += '<pre style="text-align:left; border-top: 4px dashed red; padding: 1em;">'
                 resp += cgi.escape(out.getvalue(), True)
-                
+
                 output = StringIO()
                 pprint.pprint(environ, output, depth=3)
-                
+
                 resp += cgi.escape(output.getvalue(), True)
                 resp += '</pre>'
-                
+
             return resp
-    
-
--- a/rhodecode/lib/smtp_mailer.py	Sat Apr 09 11:22:32 2011 +0200
+++ b/rhodecode/lib/smtp_mailer.py	Sat Apr 09 17:13:15 2011 +0200
@@ -2,9 +2,9 @@
 """
     rhodecode.lib.smtp_mailer
     ~~~~~~~~~~~~~~~~~~~~~~~~~
-    
+
     Simple smtp mailer used in RhodeCode
-    
+
     :created_on: Sep 13, 2010
     :copyright: (c) 2011 by marcink.
     :license: LICENSE_NAME, see LICENSE_FILE for more details.
@@ -25,18 +25,18 @@
 
 class SmtpMailer(object):
     """SMTP mailer class
-    
+
     mailer = SmtpMailer(mail_from, user, passwd, mail_server, mail_port, ssl, tls)
-    mailer.send(recipients, subject, body, attachment_files)    
-    
+    mailer.send(recipients, subject, body, attachment_files)
+
     :param recipients might be a list of string or single string
-    :param attachment_files is a dict of {filename:location} 
-        it tries to guess the mimetype and attach the file 
-    
+    :param attachment_files is a dict of {filename:location}
+        it tries to guess the mimetype and attach the file
+
     """
 
     def __init__(self, mail_from, user, passwd, mail_server,
-                    mail_port=None, ssl=False, tls=False):
+                    mail_port=None, ssl=False, tls=False, debug=False):
 
         self.mail_from = mail_from
         self.mail_server = mail_server
@@ -45,7 +45,7 @@
         self.passwd = passwd
         self.ssl = ssl
         self.tls = tls
-        self.debug = False
+        self.debug = debug
 
     def send(self, recipients=[], subject='', body='', attachment_files=None):
 
@@ -132,7 +132,7 @@
     def get_content(self, msg_file):
         """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:
         """
         if isinstance(msg_file, str):
--- a/rhodecode/lib/utils.py	Sat Apr 09 11:22:32 2011 +0200
+++ b/rhodecode/lib/utils.py	Sat Apr 09 17:13:15 2011 +0200
@@ -50,6 +50,7 @@
 
 log = logging.getLogger(__name__)
 
+
 def recursive_replace(str, replace=' '):
     """Recursive replace of given sign to just one instance
 
@@ -67,6 +68,7 @@
         str = str.replace(replace * 2, replace)
         return recursive_replace(str, replace)
 
+
 def repo_name_slug(value):
     """Return slug of name of repository
     This function is called on each creation/modification
@@ -86,10 +88,11 @@
 def get_repo_slug(request):
     return request.environ['pylons.routes_dict'].get('repo_name')
 
+
 def action_logger(user, action, repo, ipaddr='', sa=None):
     """
     Action logger for various actions made by users
-    
+
     :param user: user that made this action, can be a unique username string or
         object containing user_id attribute
     :param action: action to log, should be on of predefined unique actions for
@@ -98,7 +101,7 @@
         that action was made on
     :param ipaddr: optional ip address from what the action was made
     :param sa: optional sqlalchemy session
-    
+
     """
 
     if not sa:
@@ -113,7 +116,6 @@
         else:
             raise Exception('You have to provide user object or username')
 
-
         rm = RepoModel()
         if hasattr(repo, 'repo_id'):
             repo_obj = rm.get(repo.repo_id, cache=False)
@@ -124,7 +126,6 @@
         else:
             raise Exception('You have to provide repository to action logger')
 
-
         user_log = UserLog()
         user_log.user_id = user_obj.user_id
         user_log.action = action
@@ -142,6 +143,7 @@
         log.error(traceback.format_exc())
         sa.rollback()
 
+
 def get_repos(path, recursive=False, initial=False):
     """
     Scans given path for repos and return (name,(type,path)) tuple 
@@ -173,12 +175,14 @@
     Check given path for existence of directory
     :param repo_name:
     :param base_path:
-    
+
     :return False: if this directory is present
     """
-    if os.path.isdir(os.path.join(base_path, repo_name)):return False
+    if os.path.isdir(os.path.join(base_path, repo_name)):
+        return False
     return True
 
+
 def check_repo(repo_name, base_path, verify=True):
 
     repo_path = os.path.join(base_path, repo_name)
@@ -197,13 +201,17 @@
         log.info('%s repo is free for creation', repo_name)
         return True
 
+
 def ask_ok(prompt, retries=4, complaint='Yes or no, please!'):
     while True:
         ok = raw_input(prompt)
-        if ok in ('y', 'ye', 'yes'): return True
-        if ok in ('n', 'no', 'nop', 'nope'): return False
+        if ok in ('y', 'ye', 'yes'):
+            return True
+        if ok in ('n', 'no', 'nop', 'nope'):
+            return False
         retries = retries - 1
-        if retries < 0: raise IOError
+        if retries < 0:
+            raise IOError
         print complaint
 
 #propagated from mercurial documentation
@@ -218,11 +226,11 @@
                 'server', 'trusted',
                 'ui', 'web', ]
 
+
 def make_ui(read_from='file', path=None, checkpaths=True):
-    """
-    A function that will read python rc files or database
+    """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'
@@ -247,7 +255,6 @@
                 log.debug('settings ui from file[%s]%s:%s', section, k, v)
                 baseui.setconfig(section, k, v)
 
-
     elif read_from == 'db':
         sa = meta.Session()
         ret = sa.query(RhodeCodeUi)\
@@ -276,6 +283,7 @@
     for k, v in hgsettings.items():
         config[k] = v
 
+
 def invalidate_cache(cache_key, *args):
     """Puts cache invalidation task into db for
     further global cache invalidation
@@ -287,18 +295,20 @@
         name = cache_key.split('get_repo_cached_')[-1]
         ScmModel().mark_for_invalidation(name)
 
+
 class EmptyChangeset(BaseChangeset):
     """
     An dummy empty changeset. It's possible to pass hash when creating
     an EmptyChangeset
     """
 
-    def __init__(self, cs='0' * 40):
+    def __init__(self, cs='0' * 40, repo=None):
         self._empty_cs = cs
         self.revision = -1
         self.message = ''
         self.author = ''
         self.date = ''
+        self.repository = repo
 
     @LazyProperty
     def raw_id(self):
@@ -350,6 +360,7 @@
                 sa.delete(repo)
                 sa.commit()
 
+
 class OrderedDict(dict, DictMixin):
 
     def __init__(self, *args, **kwds):
@@ -452,7 +463,7 @@
 
 #set cache regions for beaker so celery can utilise it
 def add_cache(settings):
-    cache_settings = {'regions':None}
+    cache_settings = {'regions': None}
     for key in settings.keys():
         for prefix in ['beaker.cache.', 'cache.']:
             if key.startswith(prefix):
@@ -477,6 +488,7 @@
                                                              'memory')
             beaker.cache.cache_regions[region] = region_settings
 
+
 def get_current_revision():
     """Returns tuple of (number, id) from repository containing this package
     or None if repository could not be found.
@@ -496,9 +508,10 @@
                       "was: %s" % err)
         return None
 
-#===============================================================================
+
+#==============================================================================
 # TEST FUNCTIONS AND CREATORS
-#===============================================================================
+#==============================================================================
 def create_test_index(repo_location, full_index):
     """Makes default test index
     :param repo_location:
@@ -521,6 +534,7 @@
     except LockHeld:
         pass
 
+
 def create_test_env(repos_test_path, config):
     """Makes a fresh database and
     install test repository into tmp dir
@@ -541,7 +555,8 @@
     ch.setLevel(logging.DEBUG)
 
     # create formatter
-    formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
+    formatter = logging.Formatter("%(asctime)s - %(name)s -"
+                                  " %(levelname)s - %(message)s")
 
     # add formatter to ch
     ch.setFormatter(formatter)
@@ -582,7 +597,6 @@
 #==============================================================================
 # PASTER COMMANDS
 #==============================================================================
-
 class BasePasterCommand(Command):
     """
     Abstract Base Class for paster commands.
@@ -609,7 +623,6 @@
         if log and isinstance(log, logging):
             log(msg)
 
-
     def run(self, args):
         """
         Overrides Command.run
--- a/test.ini	Sat Apr 09 11:22:32 2011 +0200
+++ b/test.ini	Sat Apr 09 17:13:15 2011 +0200
@@ -1,6 +1,6 @@
 ################################################################################
 ################################################################################
-# rhodecode - Pylons environment configuration                                 #
+# RhodeCode - Pylons environment configuration                                 #
 #                                                                              # 
 # The %(here)s variable will be replaced with the parent directory of this file#
 ################################################################################
@@ -10,7 +10,7 @@
 ################################################################################
 ## Uncomment and replace with the address which should receive                ## 
 ## any error reports after application crash                                  ##
-## Additionally those settings will be used by rhodecode mailing system       ##
+## Additionally those settings will be used by RhodeCode mailing system       ##
 ################################################################################
 #email_to = admin@localhost
 #error_email_from = paste_error@localhost
@@ -42,7 +42,7 @@
 full_stack = true
 static_files = true
 lang=en
-cache_dir = %(here)s/data
+cache_dir = /tmp/data
 index_dir = /tmp/index
 cut_off_limit = 256000
 force_https = false
@@ -69,7 +69,7 @@
 celeryd.concurrency = 2
 #celeryd.log.file = celeryd.log
 celeryd.log.level = debug
-celeryd.max.tasks.per.child = 3
+celeryd.max.tasks.per.child = 1
 
 #tasks will never be sent to the queue, but executed locally instead.
 celery.always.eager = false
@@ -77,8 +77,8 @@
 ####################################
 ###         BEAKER CACHE        ####
 ####################################
-beaker.cache.data_dir=/%(here)s/data/cache/data
-beaker.cache.lock_dir=/%(here)s/data/cache/lock
+beaker.cache.data_dir=/tmp/data/cache/data
+beaker.cache.lock_dir=/tmp/data/cache/lock
 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
 
 beaker.cache.super_short_term.type=memory
@@ -147,7 +147,7 @@
 ### LOGGING CONFIGURATION   ####
 ################################
 [loggers]
-keys = root, routes, rhodecode, sqlalchemy
+keys = root, routes, rhodecode, sqlalchemy,beaker,templates
 
 [handlers]
 keys = console