##// END OF EJS Templates
merges for stable
marcink -
r1228:73434499 default
parent child Browse files
Show More
@@ -20,6 +20,9 b' fixes'
20 - fixes for issues #137 and #116
20 - fixes for issues #137 and #116
21 - fixes crashes on gravatar, when passed in email as unicode
21 - fixes crashes on gravatar, when passed in email as unicode
22 - fixed tooltip flickering problems
22 - fixed tooltip flickering problems
23 - fixed came_from redirection on windows
24 - fixed logging modules,and sql formatters
25 - windows fixes for os.kill and path spliting, issues #148 and #133
23
26
24 1.1.7 (**2011-03-23**)
27 1.1.7 (**2011-03-23**)
25 ======================
28 ======================
@@ -31,8 +31,8 b' VERSION = (1, 1, 8)'
31 __platform__ = platform.system()
31 __platform__ = platform.system()
32 __license__ = 'GPLv3'
32 __license__ = 'GPLv3'
33
33
34 PLATFORM_WIN = ('Windows',)
34 PLATFORM_WIN = ('Windows')
35 PLATFORM_OTHERS = ('Linux', 'Darwin', 'FreeBSD',)
35 PLATFORM_OTHERS = ('Linux', 'Darwin', 'FreeBSD', 'OpenBSD')
36
36
37 try:
37 try:
38 from rhodecode.lib.utils import get_current_revision
38 from rhodecode.lib.utils import get_current_revision
@@ -52,5 +52,5 b' def get_version():'
52
52
53 BACKENDS = {
53 BACKENDS = {
54 'hg': 'Mercurial repository',
54 'hg': 'Mercurial repository',
55 #'git': 'Git repository',
55 #'git': 'Git repository',
56 }
56 }
@@ -23,20 +23,33 b''
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
25
26 def str2bool(s):
26
27 if s is None:
27 def str2bool(_str):
28 """
29 returs True/False value from given string, it tries to translate the
30 string into boolean
31
32 :param _str: string value to translate into boolean
33 :rtype: boolean
34 :returns: boolean from given string
35 """
36 if _str is None:
28 return False
37 return False
29 if s in (True, False):
38 if _str in (True, False):
30 return s
39 return _str
31 s = str(s).strip().lower()
40 _str = str(_str).strip().lower()
32 return s in ('t', 'true', 'y', 'yes', 'on', '1')
41 return _str in ('t', 'true', 'y', 'yes', 'on', '1')
42
33
43
34 def generate_api_key(username, salt=None):
44 def generate_api_key(username, salt=None):
35 """
45 """
36 Generates uniq API key for given username
46 Generates unique API key for given username,if salt is not given
47 it'll be generated from some random string
37
48
38 :param username: username as string
49 :param username: username as string
39 :param salt: salt to hash generate KEY
50 :param salt: salt to hash generate KEY
51 :rtype: str
52 :returns: sha1 hash from username+salt
40 """
53 """
41 from tempfile import _RandomNameSequence
54 from tempfile import _RandomNameSequence
42 import hashlib
55 import hashlib
@@ -46,23 +59,23 b' def generate_api_key(username, salt=None'
46
59
47 return hashlib.sha1(username + salt).hexdigest()
60 return hashlib.sha1(username + salt).hexdigest()
48
61
49 def safe_unicode(_str):
62
63 def safe_unicode(_str, from_encoding='utf8'):
50 """
64 """
51 safe unicode function. In case of UnicodeDecode error we try to return
65 safe unicode function. In case of UnicodeDecode error we try to return
52 unicode with errors replace, if this fails we return unicode with
66 unicode with errors replace
53 string_escape decoding
67
68 :param _str: string to decode
69 :rtype: unicode
70 :returns: unicode object
54 """
71 """
55
72
56 if isinstance(_str, unicode):
73 if isinstance(_str, unicode):
57 return _str
74 return _str
58
75
59 try:
76 try:
60 u_str = unicode(_str)
77 u_str = unicode(_str, from_encoding)
61 except UnicodeDecodeError:
78 except UnicodeDecodeError:
62 try:
79 u_str = unicode(_str, from_encoding, 'replace')
63 u_str = _str.decode('utf-8', 'replace')
64 except UnicodeDecodeError:
65 #incase we have a decode error just represent as byte string
66 u_str = unicode(_str.encode('string_escape'))
67
80
68 return u_str No newline at end of file
81 return u_str
@@ -354,14 +354,7 b' class LoginRequired(object):'
354 return func(*fargs, **fkwargs)
354 return func(*fargs, **fkwargs)
355 else:
355 else:
356 log.warn('user %s not authenticated', user.username)
356 log.warn('user %s not authenticated', user.username)
357
357 p = url.current()
358 p = ''
359 if request.environ.get('SCRIPT_NAME') != '/':
360 p += request.environ.get('SCRIPT_NAME')
361
362 p += request.environ.get('PATH_INFO')
363 if request.environ.get('QUERY_STRING'):
364 p += '?' + request.environ.get('QUERY_STRING')
365
358
366 log.debug('redirecting to login page with %s', p)
359 log.debug('redirecting to login page with %s', p)
367 return redirect(url('login_home', came_from=p))
360 return redirect(url('login_home', came_from=p))
@@ -3,7 +3,7 b' import logging'
3
3
4 BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = xrange(30, 38)
4 BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = xrange(30, 38)
5
5
6 # Sequences
6 # Sequences
7 RESET_SEQ = "\033[0m"
7 RESET_SEQ = "\033[0m"
8 COLOR_SEQ = "\033[1;%dm"
8 COLOR_SEQ = "\033[1;%dm"
9 BOLD_SEQ = "\033[1m"
9 BOLD_SEQ = "\033[1m"
@@ -14,8 +14,35 b' COLORS = {'
14 'WARNING': CYAN, # level 30
14 'WARNING': CYAN, # level 30
15 'INFO': GREEN, # level 20
15 'INFO': GREEN, # level 20
16 'DEBUG': BLUE, # level 10
16 'DEBUG': BLUE, # level 10
17 'SQL' : YELLOW
17 }
18 }
18
19
20 def one_space_trim(s):
21 if s.find(" ") == -1:
22 return s
23 else:
24 s = s.replace(' ', ' ')
25 return one_space_trim(s)
26
27 def format_sql(sql):
28 sql = sql.replace('\n', '')
29 sql = one_space_trim(sql)
30 sql = sql\
31 .replace(',', ',\n\t')\
32 .replace('SELECT', '\n\tSELECT \n\t')\
33 .replace('UPDATE', '\n\tUPDATE \n\t')\
34 .replace('DELETE', '\n\tDELETE \n\t')\
35 .replace('FROM', '\n\tFROM')\
36 .replace('ORDER BY', '\n\tORDER BY')\
37 .replace('LIMIT', '\n\tLIMIT')\
38 .replace('WHERE', '\n\tWHERE')\
39 .replace('AND', '\n\tAND')\
40 .replace('LEFT', '\n\tLEFT')\
41 .replace('INNER', '\n\tINNER')\
42 .replace('INSERT', '\n\tINSERT')\
43 .replace('DELETE', '\n\tDELETE')
44 return sql
45
19 class ColorFormatter(logging.Formatter):
46 class ColorFormatter(logging.Formatter):
20
47
21 def __init__(self, *args, **kwargs):
48 def __init__(self, *args, **kwargs):
@@ -26,13 +53,30 b' class ColorFormatter(logging.Formatter):'
26 """
53 """
27 Changes record's levelname to use with COLORS enum
54 Changes record's levelname to use with COLORS enum
28 """
55 """
29
56
30 levelname = record.levelname
57 levelname = record.levelname
31 start = COLOR_SEQ % (COLORS[levelname])
58 start = COLOR_SEQ % (COLORS[levelname])
32 def_record = logging.Formatter.format(self, record)
59 def_record = logging.Formatter.format(self, record)
33 end = RESET_SEQ
60 end = RESET_SEQ
34
61
35 colored_record = start + def_record + end
62 colored_record = start + def_record + end
36 return colored_record
63 return colored_record
37
64
38 logging.ColorFormatter = ColorFormatter
65
66 class ColorFormatterSql(logging.Formatter):
67
68 def __init__(self, *args, **kwargs):
69 # can't do super(...) here because Formatter is an old school class
70 logging.Formatter.__init__(self, *args, **kwargs)
71
72 def format(self, record):
73 """
74 Changes record's levelname to use with COLORS enum
75 """
76
77 start = COLOR_SEQ % (COLORS['SQL'])
78 def_record = format_sql(logging.Formatter.format(self, record))
79 end = RESET_SEQ
80
81 colored_record = start + def_record + end
82 return colored_record
@@ -1,8 +1,15 b''
1 #!/usr/bin/env python
1 # -*- coding: utf-8 -*-
2 # encoding: utf-8
2 """
3 # Custom Exceptions modules
3 rhodecode.lib.exceptions
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
4 ~~~~~~~~~~~~~~~~~~~~~~~~
5 #
5
6 Custom Exceptions modules
7
8 :created_on: Apr 10, 2010
9 :author: marcink
10 :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
12 """
6 # This program is free software: you can redistribute it and/or modify
13 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
@@ -15,16 +22,27 b''
15 #
22 #
16 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 """
25
19 Created on Nov 17, 2010
26
20 Custom Exceptions modules
27 class LdapUsernameError(Exception):
21 @author: marcink
28 pass
22 """
29
30
31 class LdapPasswordError(Exception):
32 pass
33
23
34
24 class LdapUsernameError(Exception):pass
35 class LdapConnectionError(Exception):
25 class LdapPasswordError(Exception):pass
36 pass
26 class LdapConnectionError(Exception):pass
37
27 class LdapImportError(Exception):pass
38
39 class LdapImportError(Exception):
40 pass
28
41
29 class DefaultUserException(Exception):pass
42
30 class UserOwnsReposException(Exception):pass
43 class DefaultUserException(Exception):
44 pass
45
46
47 class UserOwnsReposException(Exception):
48 pass
@@ -4,6 +4,19 b' from warnings import warn'
4 from multiprocessing.util import Finalize
4 from multiprocessing.util import Finalize
5 import errno
5 import errno
6
6
7 from rhodecode import __platform__, PLATFORM_WIN
8
9 if __platform__ in PLATFORM_WIN:
10 import ctypes
11 def kill(pid):
12 """kill function for Win32"""
13 kernel32 = ctypes.windll.kernel32
14 handle = kernel32.OpenProcess(1, 0, pid)
15 return (0 != kernel32.TerminateProcess(handle, 0))
16
17 else:
18 kill = os.kill
19
7 class LockHeld(Exception):pass
20 class LockHeld(Exception):pass
8
21
9
22
@@ -58,9 +71,9 b' class DaemonLock(object):'
58 pidfile = open(self.pidfile, "r")
71 pidfile = open(self.pidfile, "r")
59 pidfile.seek(0)
72 pidfile.seek(0)
60 running_pid = int(pidfile.readline())
73 running_pid = int(pidfile.readline())
61
74
62 pidfile.close()
75 pidfile.close()
63
76
64 if self.debug:
77 if self.debug:
65 print 'lock file present running_pid: %s, checking for execution'\
78 print 'lock file present running_pid: %s, checking for execution'\
66 % running_pid
79 % running_pid
@@ -68,19 +81,19 b' class DaemonLock(object):'
68 # process PID
81 # process PID
69 if running_pid:
82 if running_pid:
70 try:
83 try:
71 os.kill(running_pid, 0)
84 kill(running_pid, 0)
72 except OSError, exc:
85 except OSError, exc:
73 if exc.errno in (errno.ESRCH, errno.EPERM):
86 if exc.errno in (errno.ESRCH, errno.EPERM):
74 print "Lock File is there but the program is not running"
87 print "Lock File is there but the program is not running"
75 print "Removing lock file for the: %s" % running_pid
88 print "Removing lock file for the: %s" % running_pid
76 self.release()
89 self.release()
77 else:
90 else:
78 raise
91 raise
79 else:
92 else:
80 print "You already have an instance of the program running"
93 print "You already have an instance of the program running"
81 print "It is running as process %s" % running_pid
94 print "It is running as process %s" % running_pid
82 raise LockHeld()
95 raise LockHeld()
83
96
84 except IOError, e:
97 except IOError, e:
85 if e.errno != 2:
98 if e.errno != 2:
86 raise
99 raise
@@ -90,7 +103,7 b' class DaemonLock(object):'
90 """
103 """
91 if self.debug:
104 if self.debug:
92 print 'trying to release the pidlock'
105 print 'trying to release the pidlock'
93
106
94 if self.callbackfn:
107 if self.callbackfn:
95 #execute callback function on release
108 #execute callback function on release
96 if self.debug:
109 if self.debug:
@@ -1,59 +1,28 b''
1 from sqlalchemy.interfaces import ConnectionProxy
1 from sqlalchemy.interfaces import ConnectionProxy
2 import time
2 import time
3 from sqlalchemy import log
3 import logging
4 log = logging.getLogger('timerproxy')
5
4 BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = xrange(30, 38)
6 BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = xrange(30, 38)
5
7
6 def color_sql(sql):
8 def color_sql(sql):
7 COLOR_SEQ = "\033[1;%dm"
9 COLOR_SEQ = "\033[1;%dm"
8 COLOR_SQL = YELLOW
10 COLOR_SQL = YELLOW
9 normal = '\x1b[0m'
11 normal = '\x1b[0m'
10 return COLOR_SEQ % COLOR_SQL + sql + normal
12 return COLOR_SEQ % COLOR_SQL + sql + normal
11
12 def one_space_trim(s):
13 if s.find(" ") == -1:
14 return s
15 else:
16 s = s.replace(' ', ' ')
17 return one_space_trim(s)
18
19 def format_sql(sql):
20 sql = color_sql(sql)
21 sql = sql.replace('\n', '')
22 sql = one_space_trim(sql)
23 sql = sql\
24 .replace(',', ',\n\t')\
25 .replace('SELECT', '\n\tSELECT \n\t')\
26 .replace('UPDATE', '\n\tUPDATE \n\t')\
27 .replace('DELETE', '\n\tDELETE \n\t')\
28 .replace('FROM', '\n\tFROM')\
29 .replace('ORDER BY', '\n\tORDER BY')\
30 .replace('LIMIT', '\n\tLIMIT')\
31 .replace('WHERE', '\n\tWHERE')\
32 .replace('AND', '\n\tAND')\
33 .replace('LEFT', '\n\tLEFT')\
34 .replace('INNER', '\n\tINNER')\
35 .replace('INSERT', '\n\tINSERT')\
36 .replace('DELETE', '\n\tDELETE')
37 return sql
38
39
13
40 class TimerProxy(ConnectionProxy):
14 class TimerProxy(ConnectionProxy):
41
15
42 def __init__(self):
16 def __init__(self):
43 super(TimerProxy, self).__init__()
17 super(TimerProxy, self).__init__()
44 self.logging_name = 'timerProxy'
18
45 self.log = log.instance_logger(self, True)
19 def cursor_execute(self, execute, cursor, statement, parameters,
46
20 context, executemany):
47 def cursor_execute(self, execute, cursor, statement, parameters, context, executemany):
21
48
49 now = time.time()
22 now = time.time()
50 try:
23 try:
51 self.log.info(">>>>> STARTING QUERY >>>>>")
24 log.info(color_sql(">>>>> STARTING QUERY >>>>>"))
52 return execute(cursor, statement, parameters, context)
25 return execute(cursor, statement, parameters, context)
53 finally:
26 finally:
54 total = time.time() - now
27 total = time.time() - now
55 try:
28 log.info(color_sql("<<<<< TOTAL TIME: %f <<<<<" % total))
56 self.log.info(format_sql("Query: %s" % statement % parameters))
57 except TypeError:
58 self.log.info(format_sql("Query: %s %s" % (statement, parameters)))
59 self.log.info("<<<<< TOTAL TIME: %f <<<<<" % total)
General Comments 0
You need to be logged in to leave comments. Login now