2007-08-09 Inaki Larranaga Murgoitio
[straw.git] / straw / utils.py
blobac3c043435d62a5c367d56a74547cfbf69557520
1 """ utils.py
3 Module for utility methods.
4 """
5 __copyright__ = "Copyright (c) 2002-2005 Free Software Foundation, Inc."
6 __license__ = """GNU General Public License
8 This program is free software; you can redistribute it and/or modify it under the
9 terms of the GNU General Public License as published by the Free Software
10 Foundation; either version 2 of the License, or (at your option) any later
11 version.
13 This program is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License along with
18 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19 Place - Suite 330, Boston, MA 02111-1307, USA. """
21 import re, string, htmlentitydefs
22 from htmlentitydefs import codepoint2name
23 import urllib, urlparse, locale
24 import time, calendar
25 import os
26 import os.path
27 import subprocess
28 import sys
29 import gtk
30 import string
31 import gnomevfs
33 from straw import Config
34 from straw import dialogs
35 from straw import error
36 from straw import constants
38 entity = re.compile(r'\&.\w*?\;')
39 def convert_entities(text):
40 def conv(ents):
41 entities = htmlentitydefs.entitydefs
42 ents = ents.group(0)
43 ent_code = entities.get(ents[1:-1], None)
44 if ent_code is not None:
45 try:
46 ents = unicode(ent_code, get_locale_encoding())
47 except UnicodeDecodeError:
48 ents = unicode(ent_code, 'latin-1')
49 except Exception, ex:
50 error.log("error occurred while converting entity %s: %s" % (ents, ex))
52 # check if it still needs conversion
53 if entity.search(ents) is None:
54 return ents
56 if ents[1] == '#':
57 code = ents[2:-1]
58 base = 10
59 if code[0] == 'x':
60 code = code[1:]
61 base = 16
62 return unichr(int(code, base))
63 else:
64 return
66 in_entity = entity.search(text)
67 if in_entity is None:
68 return text
69 else:
70 ctext = in_entity.re.sub(conv, text)
71 return ctext
73 def complete_url(url, feed_location):
74 url = urllib.quote(url, safe=string.punctuation)
75 if urlparse.urlparse(url)[0] == '':
76 return urlparse.urljoin(feed_location, url)
77 else:
78 return url
80 def get_url_location(url):
81 url = urllib.quote(url, safe=string.punctuation)
82 parsed_url = urlparse.urlsplit(url)
83 return urlparse.urlunsplit((parsed_url[0], parsed_url[1], '','',''))
85 def get_locale_encoding():
86 try:
87 encoding = locale.getpreferredencoding()
88 except locale.Error:
89 encoding = sys.getdefaultencoding()
90 return encoding
92 def format_date(date, format=None, encoding=None):
93 if format is None:
94 format = get_date_format()
95 if encoding is None:
96 encoding = get_locale_encoding()
97 timestr = time.strftime(format, time.localtime(calendar.timegm(date)))
98 return unicode(timestr, encoding)
100 def get_date_format():
101 # this is here just to make xgettext happy: it should be defined in
102 # only one place, and a good one would be MainWindow.py module level.
103 # however, we can't access _ there.
104 # The format: %A is the full weekday name
105 # %B is the full month name
106 # %e is the day of the month as a decimal number,
107 # without leading zero
108 # This should be translated to be suitable for the locale in
109 # question, feel free to alter the order and the parameters (they
110 # are strftime(3) parameters, the whole string is passed to the
111 # function, Straw does no additional interpretation) if you feel
112 # it's necessary in the translation file.
113 return _('%A %B %e %H:%M')
116 def get_location(location_type):
117 """ returns the absolute path of location
119 location can be 'data' or 'locale'
121 data = 'straw'
122 locale = 'locale'
123 location = None
124 if os.environ.has_key('STRAW_IN_SOURCE_DIR'):
125 data = 'data'
126 locale = 'po'
127 if location_type == 'data':
128 location = os.path.join(constants.dataroot, data)
129 elif location_type == 'locale':
130 location = os.path.join(constants.dataroot, locale)
131 return os.path.abspath(location)
133 def find_data_dir():
134 return get_location('data')
136 def find_locale_dir():
137 return get_location('locale')
139 def find_glade_file(libdir=None):
140 return os.path.normpath(os.path.join(find_data_dir(), "straw.glade"))
142 def find_image_dir():
143 return find_data_dir()
145 def listdiff(l1, l2, test=None):
146 if test is not None:
147 return _listdifftest(l1, l2, test)
148 common = []
149 inl1 = []
150 inl2 = []
151 for e in l1:
152 if e in l2:
153 common.append(e)
154 else:
155 inl1.append(e)
156 for e in l2:
157 if e in l1:
158 if e not in common:
159 common.append(e)
160 else:
161 inl2.append(e)
162 return (common, inl1, inl2)
164 def url_show(url):
165 config = Config.get_instance()
166 if config.browser_cmd:
167 try:
168 cmdbin, args = string.splitfields(str(config.browser_cmd), maxsplit=1)
169 link = args % url
170 pid = subprocess.Popen([cmdbin, link]).pid
171 return pid
172 except ValueError, ve:
173 dialogs.report_error(_("An error occurred while trying to open link"),
174 _("There was a problem opening '%s'\n\nError thrown is '%s'") % (url,str(ve)))
175 else:
176 return gnomevfs.url_show(url)
179 def set_clipboard_text(text):
180 clipboard = gtk.clipboard_get(selection="CLIPBOARD")
181 clipboard.set_text(text)
183 def html_replace(exc):
184 """ Python Cookbook 2ed, Section 1.23
186 if isinstance(exc, (UnicodeDecodeError, UnicodeTranslateError)):
187 s = [ u'&%s;' % codepoint2name[ord(c)] for c in exc.object[exc.start:exc.end]]
188 return ''.join(s), exc.end
189 else:
190 raise TypeError("can't handle %s" % exc.__name__)
192 import codecs
193 codecs.register_error('html_replace', html_replace)