changeset 1228:73434499fa72

merges for stable
author Marcin Kuzminski <marcin@python-works.com>
date Sat, 09 Apr 2011 11:22:32 +0200
parents 2182a2005278
children 9f6560667743
files docs/changelog.rst rhodecode/__init__.py rhodecode/lib/__init__.py rhodecode/lib/auth.py rhodecode/lib/colored_formatter.py rhodecode/lib/exceptions.py rhodecode/lib/pidlock.py rhodecode/lib/timerproxy.py
diffstat 8 files changed, 150 insertions(+), 97 deletions(-) [+]
line wrap: on
line diff
--- a/docs/changelog.rst	Fri Apr 08 00:47:20 2011 +0200
+++ b/docs/changelog.rst	Sat Apr 09 11:22:32 2011 +0200
@@ -20,6 +20,9 @@
 - fixes for issues #137 and #116
 - 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
 
 1.1.7 (**2011-03-23**)
 ======================
--- a/rhodecode/__init__.py	Fri Apr 08 00:47:20 2011 +0200
+++ b/rhodecode/__init__.py	Sat Apr 09 11:22:32 2011 +0200
@@ -31,8 +31,8 @@
 __platform__ = platform.system()
 __license__ = 'GPLv3'
 
-PLATFORM_WIN = ('Windows',)
-PLATFORM_OTHERS = ('Linux', 'Darwin', 'FreeBSD',)
+PLATFORM_WIN = ('Windows')
+PLATFORM_OTHERS = ('Linux', 'Darwin', 'FreeBSD', 'OpenBSD')
 
 try:
     from rhodecode.lib.utils import get_current_revision
@@ -52,5 +52,5 @@
 
 BACKENDS = {
     'hg': 'Mercurial repository',
-   #'git': 'Git repository',
+    #'git': 'Git repository',
 }
--- a/rhodecode/lib/__init__.py	Fri Apr 08 00:47:20 2011 +0200
+++ b/rhodecode/lib/__init__.py	Sat Apr 09 11:22:32 2011 +0200
@@ -23,20 +23,33 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-def str2bool(s):
-    if s is None:
+
+def str2bool(_str):
+    """
+    returs True/False value from given string, it tries to translate the
+    string into boolean
+
+    :param _str: string value to translate into boolean
+    :rtype: boolean
+    :returns: boolean from given string
+    """
+    if _str is None:
         return False
-    if s in (True, False):
-        return s
-    s = str(s).strip().lower()
-    return s in ('t', 'true', 'y', 'yes', 'on', '1')
+    if _str in (True, False):
+        return _str
+    _str = str(_str).strip().lower()
+    return _str in ('t', 'true', 'y', 'yes', 'on', '1')
+
 
 def generate_api_key(username, salt=None):
     """
-    Generates uniq API key for given username
+    Generates unique API key for given username,if salt is not given
+    it'll be generated from some random string
 
     :param username: username as string
     :param salt: salt to hash generate KEY
+    :rtype: str
+    :returns: sha1 hash from username+salt
     """
     from tempfile import _RandomNameSequence
     import hashlib
@@ -46,23 +59,23 @@
 
     return hashlib.sha1(username + salt).hexdigest()
 
-def safe_unicode(_str):
+
+def safe_unicode(_str, from_encoding='utf8'):
     """
     safe unicode function. In case of UnicodeDecode error we try to return
-    unicode with errors replace, if this fails we return unicode with
-    string_escape decoding
+    unicode with errors replace
+
+    :param _str: string to decode
+    :rtype: unicode
+    :returns: unicode object
     """
 
     if isinstance(_str, unicode):
         return _str
 
     try:
-        u_str = unicode(_str)
+        u_str = unicode(_str, from_encoding)
     except UnicodeDecodeError:
-        try:
-            u_str = _str.decode('utf-8', 'replace')
-        except UnicodeDecodeError:
-            #incase we have a decode error just represent as byte string
-            u_str = unicode(_str.encode('string_escape'))
+        u_str = unicode(_str, from_encoding, 'replace')
 
-    return u_str
\ No newline at end of file
+    return u_str
--- a/rhodecode/lib/auth.py	Fri Apr 08 00:47:20 2011 +0200
+++ b/rhodecode/lib/auth.py	Sat Apr 09 11:22:32 2011 +0200
@@ -354,14 +354,7 @@
             return func(*fargs, **fkwargs)
         else:
             log.warn('user %s not authenticated', user.username)
-
-            p = ''
-            if request.environ.get('SCRIPT_NAME') != '/':
-                p += request.environ.get('SCRIPT_NAME')
-
-            p += request.environ.get('PATH_INFO')
-            if request.environ.get('QUERY_STRING'):
-                p += '?' + request.environ.get('QUERY_STRING')
+            p = url.current()
 
             log.debug('redirecting to login page with %s', p)
             return redirect(url('login_home', came_from=p))
--- a/rhodecode/lib/colored_formatter.py	Fri Apr 08 00:47:20 2011 +0200
+++ b/rhodecode/lib/colored_formatter.py	Sat Apr 09 11:22:32 2011 +0200
@@ -3,7 +3,7 @@
 
 BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = xrange(30, 38)
 
-# Sequences 
+# Sequences
 RESET_SEQ = "\033[0m"
 COLOR_SEQ = "\033[1;%dm"
 BOLD_SEQ = "\033[1m"
@@ -14,8 +14,35 @@
     'WARNING': CYAN, # level 30
     'INFO': GREEN, # level 20
     'DEBUG': BLUE, # level 10
+    'SQL' : YELLOW
 }
 
+def one_space_trim(s):
+    if s.find("  ") == -1:
+        return s
+    else:
+        s = s.replace('  ', ' ')
+        return one_space_trim(s)
+
+def format_sql(sql):
+    sql = sql.replace('\n', '')
+    sql = one_space_trim(sql)
+    sql = sql\
+        .replace(',', ',\n\t')\
+        .replace('SELECT', '\n\tSELECT \n\t')\
+        .replace('UPDATE', '\n\tUPDATE \n\t')\
+        .replace('DELETE', '\n\tDELETE \n\t')\
+        .replace('FROM', '\n\tFROM')\
+        .replace('ORDER BY', '\n\tORDER BY')\
+        .replace('LIMIT', '\n\tLIMIT')\
+        .replace('WHERE', '\n\tWHERE')\
+        .replace('AND', '\n\tAND')\
+        .replace('LEFT', '\n\tLEFT')\
+        .replace('INNER', '\n\tINNER')\
+        .replace('INSERT', '\n\tINSERT')\
+        .replace('DELETE', '\n\tDELETE')
+    return sql
+
 class ColorFormatter(logging.Formatter):
 
     def __init__(self, *args, **kwargs):
@@ -26,13 +53,30 @@
         """
         Changes record's levelname to use with COLORS enum
         """
-        
+
         levelname = record.levelname
         start = COLOR_SEQ % (COLORS[levelname])
         def_record = logging.Formatter.format(self, record)
         end = RESET_SEQ
-        
+
         colored_record = start + def_record + end
         return colored_record
 
-logging.ColorFormatter = ColorFormatter
+
+class ColorFormatterSql(logging.Formatter):
+
+    def __init__(self, *args, **kwargs):
+        # can't do super(...) here because Formatter is an old school class
+        logging.Formatter.__init__(self, *args, **kwargs)
+
+    def format(self, record):
+        """
+        Changes record's levelname to use with COLORS enum
+        """
+
+        start = COLOR_SEQ % (COLORS['SQL'])
+        def_record = format_sql(logging.Formatter.format(self, record))
+        end = RESET_SEQ
+
+        colored_record = start + def_record + end
+        return colored_record
--- a/rhodecode/lib/exceptions.py	Fri Apr 08 00:47:20 2011 +0200
+++ b/rhodecode/lib/exceptions.py	Sat Apr 09 11:22:32 2011 +0200
@@ -1,8 +1,15 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Custom Exceptions modules
-# Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
-#
+# -*- coding: utf-8 -*-
+"""
+    rhodecode.lib.exceptions
+    ~~~~~~~~~~~~~~~~~~~~~~~~
+
+    Custom Exceptions modules
+
+    :created_on: Apr 10, 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
@@ -15,16 +22,27 @@
 #
 # 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 Nov 17, 2010
-Custom Exceptions modules
-@author: marcink
-"""
+
+
+class LdapUsernameError(Exception):
+    pass
+
+
+class LdapPasswordError(Exception):
+    pass
+
 
-class LdapUsernameError(Exception):pass
-class LdapPasswordError(Exception):pass
-class LdapConnectionError(Exception):pass
-class LdapImportError(Exception):pass
+class LdapConnectionError(Exception):
+    pass
+
+
+class LdapImportError(Exception):
+    pass
 
-class DefaultUserException(Exception):pass
-class UserOwnsReposException(Exception):pass
+
+class DefaultUserException(Exception):
+    pass
+
+
+class UserOwnsReposException(Exception):
+    pass
--- a/rhodecode/lib/pidlock.py	Fri Apr 08 00:47:20 2011 +0200
+++ b/rhodecode/lib/pidlock.py	Sat Apr 09 11:22:32 2011 +0200
@@ -4,6 +4,19 @@
 from multiprocessing.util import Finalize
 import errno
 
+from rhodecode import __platform__, PLATFORM_WIN
+
+if __platform__ in PLATFORM_WIN:
+    import ctypes
+    def kill(pid):
+        """kill function for Win32"""
+        kernel32 = ctypes.windll.kernel32
+        handle = kernel32.OpenProcess(1, 0, pid)
+        return (0 != kernel32.TerminateProcess(handle, 0))
+
+else:
+    kill = os.kill
+
 class LockHeld(Exception):pass
 
 
@@ -58,9 +71,9 @@
             pidfile = open(self.pidfile, "r")
             pidfile.seek(0)
             running_pid = int(pidfile.readline())
-            
+
             pidfile.close()
-            
+
             if self.debug:
                 print 'lock file present running_pid: %s, checking for execution'\
                 % running_pid
@@ -68,19 +81,19 @@
             # process PID
             if running_pid:
                 try:
-                    os.kill(running_pid, 0)
+                    kill(running_pid, 0)
                 except OSError, exc:
                     if exc.errno in (errno.ESRCH, errno.EPERM):
                         print "Lock File is there but the program is not running"
-                        print "Removing lock file for the: %s" % running_pid                        
+                        print "Removing lock file for the: %s" % running_pid
                         self.release()
                     else:
                         raise
                 else:
                     print "You already have an instance of the program running"
-                    print "It is running as process %s" % running_pid                    
+                    print "It is running as process %s" % running_pid
                     raise LockHeld()
-                         
+
         except IOError, e:
             if e.errno != 2:
                 raise
@@ -90,7 +103,7 @@
         """
         if self.debug:
             print 'trying to release the pidlock'
-            
+
         if self.callbackfn:
             #execute callback function on release
             if self.debug:
--- a/rhodecode/lib/timerproxy.py	Fri Apr 08 00:47:20 2011 +0200
+++ b/rhodecode/lib/timerproxy.py	Sat Apr 09 11:22:32 2011 +0200
@@ -1,59 +1,28 @@
 from sqlalchemy.interfaces import ConnectionProxy
 import time
-from sqlalchemy import log
+import logging
+log = logging.getLogger('timerproxy')
+
 BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = xrange(30, 38)
 
 def color_sql(sql):
     COLOR_SEQ = "\033[1;%dm"
     COLOR_SQL = YELLOW
     normal = '\x1b[0m'
-    return COLOR_SEQ % COLOR_SQL + sql + normal 
-
-def one_space_trim(s):
-    if s.find("  ") == -1:
-        return s
-    else:
-        s = s.replace('  ', ' ')
-        return one_space_trim(s)
-    
-def format_sql(sql):
-    sql = color_sql(sql)
-    sql = sql.replace('\n', '')
-    sql = one_space_trim(sql)
-    sql = sql\
-        .replace(',', ',\n\t')\
-        .replace('SELECT', '\n\tSELECT \n\t')\
-        .replace('UPDATE', '\n\tUPDATE \n\t')\
-        .replace('DELETE', '\n\tDELETE \n\t')\
-        .replace('FROM', '\n\tFROM')\
-        .replace('ORDER BY', '\n\tORDER BY')\
-        .replace('LIMIT', '\n\tLIMIT')\
-        .replace('WHERE', '\n\tWHERE')\
-        .replace('AND', '\n\tAND')\
-        .replace('LEFT', '\n\tLEFT')\
-        .replace('INNER', '\n\tINNER')\
-        .replace('INSERT', '\n\tINSERT')\
-        .replace('DELETE', '\n\tDELETE')
-    return sql
-
+    return COLOR_SEQ % COLOR_SQL + sql + normal
 
 class TimerProxy(ConnectionProxy):
-    
+
     def __init__(self):
         super(TimerProxy, self).__init__()
-        self.logging_name = 'timerProxy'
-        self.log = log.instance_logger(self, True)
-        
-    def cursor_execute(self, execute, cursor, statement, parameters, context, executemany):
-        
+
+    def cursor_execute(self, execute, cursor, statement, parameters,
+                       context, executemany):
+
         now = time.time()
         try:
-            self.log.info(">>>>> STARTING QUERY >>>>>")
+            log.info(color_sql(">>>>> STARTING QUERY >>>>>"))
             return execute(cursor, statement, parameters, context)
         finally:
             total = time.time() - now
-            try:
-                self.log.info(format_sql("Query: %s" % statement % parameters))
-            except TypeError:
-                self.log.info(format_sql("Query: %s %s" % (statement, parameters)))
-            self.log.info("<<<<< TOTAL TIME: %f <<<<<" % total)
+            log.info(color_sql("<<<<< TOTAL TIME: %f <<<<<" % total))