diff --git a/docs/changelog.rst b/docs/changelog.rst
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -20,6 +20,9 @@ fixes
- 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**)
======================
diff --git a/rhodecode/__init__.py b/rhodecode/__init__.py
--- a/rhodecode/__init__.py
+++ b/rhodecode/__init__.py
@@ -31,8 +31,8 @@ VERSION = (1, 1, 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 @@ def get_version():
BACKENDS = {
'hg': 'Mercurial repository',
- #'git': 'Git repository',
+ #'git': 'Git repository',
}
diff --git a/rhodecode/lib/__init__.py b/rhodecode/lib/__init__.py
--- a/rhodecode/lib/__init__.py
+++ b/rhodecode/lib/__init__.py
@@ -23,20 +23,33 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
-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 @@ def generate_api_key(username, salt=None
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
diff --git a/rhodecode/lib/auth.py b/rhodecode/lib/auth.py
--- a/rhodecode/lib/auth.py
+++ b/rhodecode/lib/auth.py
@@ -354,14 +354,7 @@ class LoginRequired(object):
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))
diff --git a/rhodecode/lib/colored_formatter.py b/rhodecode/lib/colored_formatter.py
--- a/rhodecode/lib/colored_formatter.py
+++ b/rhodecode/lib/colored_formatter.py
@@ -3,7 +3,7 @@ import logging
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 @@ COLORS = {
'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 @@ class ColorFormatter(logging.Formatter):
"""
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
diff --git a/rhodecode/lib/exceptions.py b/rhodecode/lib/exceptions.py
--- a/rhodecode/lib/exceptions.py
+++ b/rhodecode/lib/exceptions.py
@@ -1,8 +1,15 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Custom Exceptions modules
-# Copyright (C) 2009-2010 Marcin Kuzminski
-#
+# -*- coding: utf-8 -*-
+"""
+ rhodecode.lib.exceptions
+ ~~~~~~~~~~~~~~~~~~~~~~~~
+
+ Custom Exceptions modules
+
+ :created_on: Apr 10, 2010
+ :author: marcink
+ :copyright: (C) 2009-2011 Marcin Kuzminski
+ :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 .
-"""
-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
diff --git a/rhodecode/lib/pidlock.py b/rhodecode/lib/pidlock.py
--- a/rhodecode/lib/pidlock.py
+++ b/rhodecode/lib/pidlock.py
@@ -4,6 +4,19 @@ from warnings import warn
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 @@ class DaemonLock(object):
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 @@ class DaemonLock(object):
# 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 @@ class DaemonLock(object):
"""
if self.debug:
print 'trying to release the pidlock'
-
+
if self.callbackfn:
#execute callback function on release
if self.debug:
diff --git a/rhodecode/lib/timerproxy.py b/rhodecode/lib/timerproxy.py
--- a/rhodecode/lib/timerproxy.py
+++ b/rhodecode/lib/timerproxy.py
@@ -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))