# -*- coding: iso8859-1 -*- # # Copyright (C) 2003, 2004 Edgewall Software # Copyright (C) 2003, 2004 Jonas Borgström # # Trac 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 2 of the # License, or (at your option) any later version. # # Trac 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, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # # Author: Jonas Borgström import tempfile import os import sys import time import StringIO from types import * TRUE = ['yes', '1', 1, 'true', 'on', 'aye'] FALSE = ['no', '0', 0, 'false', 'off', 'nay'] def svn_date_to_string(date, pool): from svn import util date_seconds = util.svn_time_from_cstring(date, pool) / 1000000 return time.strftime('%x %X', time.localtime(date_seconds)) def enum_selector (db, sql, name, selected=None,default_empty=0): out = StringIO.StringIO() out.write ('') return out.getvalue() def escape(text): """Escapes &, <, > and \"""" if not text: return '' if type(text) is StringType: text = text.replace('&', '&') \ .replace('<', '<') \ .replace('>', '>') \ .replace('"', '"') return text def get_first_line(text, maxlen): """ returns the first line of text. If the line is longer then maxlen characters it is truncated. The line is also html escaped. """ lines = text.splitlines() line = lines[0] if len(lines) > 1: return escape(line[:maxlen] + '...') elif len(line) > maxlen-3: return escape(line[:maxlen] + '...') else: return escape(line) def lstrip(text, skip): """Python2.1 doesn't support custom skip characters""" while text: if text[0] in skip: text = text[1:] else: break return text def rstrip(text, skip): """Python2.1 doesn't support custom skip characters""" while text: if text[-1] in skip: text = text[:-1] else: break return text def to_utf8(text): """Convert a string to utf-8, assume the encoding is either utf-8 or latin1""" try: u = unicode(text, 'utf-8') return text except UnicodeError: u = unicode(text, 'iso-8859-15') return u.encode('utf-8') def href_join(u1, *tail): """Join a list of url components and removes redundant '/' characters""" for u2 in tail: u1 = rstrip(u1, '/') + '/' + lstrip(u2, '/') return u1 def add_dictlist_to_hdf(list, hdf, prefix): idx = 0 for item in list: for key in item.keys(): hdf.setValue('%s.%d.%s' % (prefix, idx, key), str(item[key])) idx = idx + 1 def add_dict_to_hdf(dict, hdf, prefix): for key in dict.keys(): hdf.setValue('%s.%s' % (prefix, key), str(dict[key])) def sql_to_hdf (db, sql, hdf, prefix): """ executes a sql query and insert the first result column into the hdf at the given prefix """ cursor = db.cursor () cursor.execute (sql) idx = 0 while 1: row = cursor.fetchone() if not row: break hdf.setValue('%s.%d.name' % (prefix, idx), row[0]) idx = idx + 1 def hdf_add_if_missing(hdf, prefix, value): """Loop through the hdf values and add @value if id doesn't exist""" node = hdf.getObj(prefix + '.0') i = 0 while node: child = node.child() if child and child.value() == value: return node = node.next() i += 1 hdf.setValue(prefix + '.%d.name' % i, value) def shorten_line(text): if not text: return text maxlen = 75 if len(text) < maxlen: shortline = text else: i = text[:maxlen].rfind(' ') if i == -1: i = maxlen shortline = text[:i]+' ...' return shortline def hex_entropy(bytes=32): import md5 import random return md5.md5(str(random.random() + time.time())).hexdigest()[:bytes] def pretty_size(size): if size < 1024: return '%d bytes' % size elif size < 1024 * 1024: return '%d kB' % (size / 1024) else: return '%d MB' % (size / 1024 / 1024) def create_unique_file(path): """Create a new file. An index is added if the path exists""" parts = os.path.splitext(path) idx = 1 while 1: try: flags = os.O_CREAT + os.O_WRONLY + os.O_EXCL if hasattr(os, 'O_BINARY'): flags += os.O_BINARY return path, os.fdopen(os.open(path, flags), 'w') except OSError: idx += 1 # A sanity check if idx > 100: raise Exception('Failed to create unique name: ' + path) path = '%s.%d%s' % (parts[0], idx, parts[1]) class TracError(Exception): def __init__(self, message, title=None, show_traceback=0): Exception.__init__(self, message) self.message = message self.title = title self.show_traceback = show_traceback class NaivePopen: """ This is a deadlock-safe version of popen that returns an object with errorlevel, out (a string) and err (a string). (capturestderr may not work under windows.) Example: print Popen3('grep spam','\n\nhere spam\n\n').out """ def __init__(self,command,input=None,capturestderr=None): outfile=tempfile.mktemp() command="( %s ) > %s" % (command,outfile) if input: infile=tempfile.mktemp() open(infile,"w").write(input) command=command+" <"+infile if capturestderr: errfile=tempfile.mktemp() command=command+" 2>"+errfile self.errorlevel=os.system(command) >> 8 self.out=open(outfile,"r").read() os.remove(outfile) if input: os.remove(infile) if capturestderr: self.err=open(errfile,"r").read() os.remove(errfile)