## common/helpers.py ## ## Gajim Team: ## - Yann Le Boulanger ## - Vincent Hanquez ## - Nikos Kouremenos ## ## Copyright (C) 2003-2005 Gajim Team ## ## 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; version 2 only. ## ## This program 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. ## import sre import os import urllib import errno import sys import stat import gajim from common import i18n from common.xmpp_stringprep import nodeprep, resourceprep, nameprep try: import winsound # windows-only built-in module for playing wav except: pass _ = i18n._ Q_ = i18n.Q_ class InvalidFormat(Exception): pass def parse_jid(jidstring): '''Perform stringprep on all JID fragments from a string and return the full jid''' # This function comes from http://svn.twistedmatrix.com/cvs/trunk/twisted/words/protocols/jabber/jid.py user = None server = None resource = None # Search for delimiters user_sep = jidstring.find("@") res_sep = jidstring.find("/") if user_sep == -1: if res_sep == -1: # host server = jidstring else: # host/resource server = jidstring[0:res_sep] resource = jidstring[res_sep + 1:] or None else: if res_sep == -1: # user@host user = jidstring[0:user_sep] or None server = jidstring[user_sep + 1:] else: if user_sep < res_sep: # user@host/resource user = jidstring[0:user_sep] or None server = jidstring[user_sep + 1:user_sep + (res_sep - user_sep)] resource = jidstring[res_sep + 1:] or None else: # server/resource (with an @ in resource) server = jidstring[0:res_sep] resource = jidstring[res_sep + 1:] or None return prep(user, server, resource) def parse_resource(resource): '''Perform stringprep on resource and return it''' if resource: try: return resourceprep.prepare(unicode(resource)) except UnicodeError: raise InvalidFormat, 'Invalid character in resource.' def prep(user, server, resource): '''Perform stringprep on all JID fragments and return the full jid''' # This function comes from #http://svn.twistedmatrix.com/cvs/trunk/twisted/words/protocols/jabber/jid.py if user: try: user = nodeprep.prepare(unicode(user)) except UnicodeError: raise InvalidFormat, 'Invalid character in username.' else: user = None if not server: raise InvalidFormat, 'Server address required.' else: try: server = nameprep.prepare(unicode(server)) except UnicodeError: raise InvalidFormat, 'Invalid character in hostname' if resource: try: resource = resourceprep.prepare(unicode(resource)) except UnicodeError: raise InvalidFormat, 'Invalid character in resource.' else: resource = None if user: if resource: return '%s@%s/%s' % (user, server, resource) else: return '%s@%s' % (user, server) else: if resource: return '%s/%s' % (server, resource) else: return server def temp_failure_retry(func, *args, **kwargs): while True: try: return func(*args, **kwargs) except (os.error, IOError), ex: if ex.errno == errno.EINTR: continue else: raise def check_paths(): LOGPATH = gajim.LOGPATH VCARDPATH = gajim.VCARDPATH dot_gajim = os.path.dirname(LOGPATH) if os.path.isfile(dot_gajim): print _('%s is file but it should be a directory') % dot_gajim print _('Gajim will now exit') sys.exit() elif os.path.isdir(dot_gajim): s = os.stat(dot_gajim) if s.st_mode & stat.S_IROTH: # others have read permission! os.chmod(dot_gajim, 0700) # rwx------ if not os.path.exists(LOGPATH): print _('creating %s directory') % LOGPATH os.mkdir(LOGPATH, 0700) elif os.path.isfile(LOGPATH): print _('%s is file but it should be a directory') % LOGPATH print _('Gajim will now exit') sys.exit() elif os.path.isdir(LOGPATH): s = os.stat(LOGPATH) if s.st_mode & stat.S_IROTH: # others have read permission! os.chmod(LOGPATH, 0700) # rwx------ if not os.path.exists(VCARDPATH): print _('creating %s directory') % VCARDPATH os.mkdir(VCARDPATH, 0700) elif os.path.isfile(VCARDPATH): print _('%s is file but it should be a directory') % VCARDPATH print _('Gajim will now exit') sys.exit() elif os.path.isdir(VCARDPATH): s = os.stat(VCARDPATH) if s.st_mode & stat.S_IROTH: # others have read permission! os.chmod(VCARDPATH, 0700) # rwx------ else: # dot_gajim doesn't exist if dot_gajim: # is '' on win9x so avoid that print _('creating %s directory') % dot_gajim os.mkdir(dot_gajim, 0700) if not os.path.isdir(LOGPATH): print _('creating %s directory') % LOGPATH os.mkdir(LOGPATH, 0700) if not os.path.isdir(VCARDPATH): print _('creating %s directory') % VCARDPATH os.mkdir(VCARDPATH, 0700) def convert_bytes(string): suffix = '' # IEC standard says KiB = 1024 bytes KB = 1000 bytes # but do we use the standard? use_kib_mib = gajim.config.get('use_kib_mib') align = 1024. bytes = float(string) if bytes >= align: bytes = round(bytes/align, 1) if bytes >= align: bytes = round(bytes/align, 1) if bytes >= align: bytes = round(bytes/align, 1) if use_kib_mib: #GiB means gibibyte suffix = _('%s GiB') else: #GB means gigabyte suffix = _('%s GB') else: if use_kib_mib: #MiB means mibibyte suffix = _('%s MiB') else: #MB means megabyte suffix = _('%s MB') else: if use_kib_mib: #KiB means kibibyte suffix = _('%s KiB') else: #KB means kilo bytes suffix = _('%s KB') else: #B means bytes suffix = _('%s B') return suffix % unicode(bytes) def get_uf_show(show, use_mnemonic = False): '''returns a userfriendly string for dnd/xa/chat and makes all strings translatable if use_mnemonic is True, it adds _ so GUI should call with True for accessibility issues''' if show == 'dnd': if use_mnemonic: uf_show = _('_Busy') else: uf_show = _('Busy') elif show == 'xa': if use_mnemonic: uf_show = _('_Not Available') else: uf_show = _('Not Available') elif show == 'chat': if use_mnemonic: uf_show = _('_Free for Chat') else: uf_show = _('Free for Chat') elif show == 'online': if use_mnemonic: uf_show = _('_Available') else: uf_show = _('Available') elif show == 'connecting': uf_show = _('Connecting') elif show == 'away': if use_mnemonic: uf_show = _('A_way') else: uf_show = _('Away') elif show == 'offline': if use_mnemonic: uf_show = _('_Offline') else: uf_show = _('Offline') elif show == 'invisible': if use_mnemonic: uf_show = _('_Invisible') else: uf_show = _('Invisible') elif show == 'not in the roster': uf_show = _('Not in the roster') elif show == 'requested': uf_show = Q_('?contact has status:Unknown') else: uf_show = Q_('?contact has status:Has errors') return unicode(uf_show) def get_uf_sub(sub): if sub == 'none': uf_sub = Q_('?Subscription we already have:None') elif sub == 'to': uf_sub = _('To') elif sub == 'from': uf_sub = _('From') elif sub == 'both': uf_sub = _('Both') else: uf_sub = sub return unicode(uf_sub) def get_uf_ask(ask): if ask is None: uf_ask = Q_('?Ask (for Subscription):None') elif ask == 'subscribe': uf_ask = _('Subscribe') else: uf_ask = ask return unicode(uf_ask) def get_uf_role(role, plural = False): ''' plural determines if you get Moderators or Moderator''' if role == 'none': role_name = Q_('?Group Chat Contact Role:None') elif role == 'moderator': if plural: role_name = _('Moderators') else: role_name = _('Moderator') elif role == 'participant': if plural: role_name = _('Participants') else: role_name = _('Participant') elif role == 'visitor': if plural: role_name = _('Visitors') else: role_name = _('Visitor') return role_name def get_sorted_keys(adict): keys = adict.keys() keys.sort() return keys def to_one_line(msg): msg = msg.replace('\\', '\\\\') msg = msg.replace('\n', '\\n') # s1 = 'test\ntest\\ntest' # s11 = s1.replace('\\', '\\\\') # s12 = s11.replace('\n', '\\n') # s12 # 'test\\ntest\\\\ntest' return msg def from_one_line(msg): # (? 1: one_connected = True break return one_connected def get_output_of_command(command): try: child_stdin, child_stdout = os.popen2(command) except ValueError: return None output = child_stdout.readlines() child_stdout.close() child_stdin.close() return output def get_global_show(): maxi = 0 for account in gajim.connections: connected = gajim.connections[account].connected if connected > maxi: maxi = connected return gajim.SHOW_LIST[maxi] def get_icon_name_to_show(contact, account = None): '''Get the icon name to show in online, away, requested, ...''' if account and gajim.awaiting_events[account].has_key(contact.jid): #FIXME: change icon for FT return 'message' if contact.jid.find('@') <= 0: # if not '@' or '@' starts the jid ==> agent return contact.show if contact.sub in ('both', 'to'): return contact.show if contact.ask == 'subscribe': return 'requested' transport = gajim.get_transport_name_from_jid(contact.jid) if transport: return contact.show return 'not in the roster'