2005-05-20 17:58:23 +02:00
|
|
|
## common/helpers.py
|
|
|
|
##
|
|
|
|
## Gajim Team:
|
|
|
|
## - Yann Le Boulanger <asterix@lagaule.org>
|
|
|
|
## - Vincent Hanquez <tab@snarc.org>
|
|
|
|
## - Nikos Kouremenos <kourem@gmail.com>
|
|
|
|
##
|
|
|
|
## 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.
|
|
|
|
##
|
|
|
|
|
2005-08-09 13:33:56 +02:00
|
|
|
import sre
|
|
|
|
import os
|
2005-08-14 21:08:56 +02:00
|
|
|
import urllib
|
2005-08-09 13:33:56 +02:00
|
|
|
|
2005-08-09 19:27:27 +02:00
|
|
|
import gajim
|
2005-05-21 15:19:42 +02:00
|
|
|
from common import i18n
|
2005-08-09 19:27:27 +02:00
|
|
|
|
2005-05-21 15:19:42 +02:00
|
|
|
_ = i18n._
|
2005-08-13 00:32:35 +02:00
|
|
|
Q_ = i18n.Q_
|
2005-05-21 15:19:42 +02:00
|
|
|
|
2005-08-09 19:27:27 +02:00
|
|
|
def convert_bytes(string):
|
|
|
|
suffix = ''
|
|
|
|
# IEC standard says KiB = 1024 bytes KB = 1000 bytes
|
2005-09-08 23:01:15 +02:00
|
|
|
# but do we use the standard?
|
2005-08-09 19:27:27 +02:00
|
|
|
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')
|
2005-08-26 02:52:44 +02:00
|
|
|
return suffix % unicode(bytes)
|
2005-08-09 19:27:27 +02:00
|
|
|
|
2005-05-20 18:31:52 +02:00
|
|
|
def get_uf_show(show):
|
2005-05-20 17:58:23 +02:00
|
|
|
'''returns a userfriendly string for dnd/xa/chat
|
2005-08-05 00:08:33 +02:00
|
|
|
and makes all strings translatable'''
|
2005-05-20 18:31:52 +02:00
|
|
|
if show == 'dnd':
|
2005-05-21 15:19:42 +02:00
|
|
|
uf_show = _('Busy')
|
2005-05-20 18:31:52 +02:00
|
|
|
elif show == 'xa':
|
2005-05-21 15:19:42 +02:00
|
|
|
uf_show = _('Not Available')
|
2005-05-20 18:31:52 +02:00
|
|
|
elif show == 'chat':
|
2005-05-21 15:19:42 +02:00
|
|
|
uf_show = _('Free for Chat')
|
|
|
|
elif show == 'online':
|
2005-05-26 21:56:04 +02:00
|
|
|
uf_show = _('Available')
|
2005-05-21 15:19:42 +02:00
|
|
|
elif show == 'connecting':
|
|
|
|
uf_show = _('Connecting')
|
|
|
|
elif show == 'away':
|
|
|
|
uf_show = _('Away')
|
2005-05-21 15:44:50 +02:00
|
|
|
elif show == 'offline':
|
|
|
|
uf_show = _('Offline')
|
|
|
|
elif show == 'invisible':
|
|
|
|
uf_show = _('Invisible')
|
2005-05-22 01:37:11 +02:00
|
|
|
elif show == 'not in the roster':
|
2005-05-22 01:34:51 +02:00
|
|
|
uf_show = _('Not in the roster')
|
2005-08-04 21:47:01 +02:00
|
|
|
elif show == 'requested':
|
2005-08-13 13:17:49 +02:00
|
|
|
uf_show = Q_('?contact has status:Unknown')
|
2005-05-23 18:57:35 +02:00
|
|
|
else:
|
2005-08-14 15:46:15 +02:00
|
|
|
uf_show = Q_('?contact has status:Has errors')
|
2005-06-01 23:40:33 +02:00
|
|
|
return unicode(uf_show)
|
2005-08-05 00:08:33 +02:00
|
|
|
|
|
|
|
def get_uf_sub(sub):
|
|
|
|
if sub == 'none':
|
2005-08-13 00:32:35 +02:00
|
|
|
uf_sub = Q_('?Subscription we already have:None')
|
2005-08-05 00:08:33 +02:00
|
|
|
elif sub == 'to':
|
|
|
|
uf_sub = _('To')
|
|
|
|
elif sub == 'from':
|
|
|
|
uf_sub = _('From')
|
|
|
|
elif sub == 'both':
|
|
|
|
uf_sub = _('Both')
|
|
|
|
else:
|
|
|
|
uf_sub = sub
|
|
|
|
|
2005-08-05 00:09:33 +02:00
|
|
|
return unicode(uf_sub)
|
|
|
|
|
2005-08-05 00:08:33 +02:00
|
|
|
def get_uf_ask(ask):
|
|
|
|
if ask is None:
|
2005-08-13 00:32:35 +02:00
|
|
|
uf_ask = Q_('?Ask (for Subscription):None')
|
2005-08-05 00:08:33 +02:00
|
|
|
elif ask == 'subscribe':
|
|
|
|
uf_ask = _('Subscribe')
|
|
|
|
else:
|
|
|
|
uf_ask = ask
|
|
|
|
|
2005-08-05 00:09:33 +02:00
|
|
|
return unicode(uf_ask)
|
2005-06-06 13:53:07 +02:00
|
|
|
|
2005-08-24 16:09:03 +02:00
|
|
|
def get_uf_role(role, plural = False):
|
2005-08-24 16:08:35 +02:00
|
|
|
''' 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
|
|
|
|
|
2005-06-06 13:53:07 +02:00
|
|
|
def get_sorted_keys(adict):
|
|
|
|
keys = adict.keys()
|
|
|
|
keys.sort()
|
|
|
|
return keys
|
2005-07-02 14:36:21 +02:00
|
|
|
|
|
|
|
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):
|
|
|
|
# (?<!\\) is a lookbehind assertion which asks anything but '\'
|
|
|
|
# to match the regexp that follows it
|
|
|
|
|
|
|
|
# So here match '\\n' but not if you have a '\' before that
|
|
|
|
re = sre.compile(r'(?<!\\)\\n')
|
|
|
|
msg = re.sub('\n', msg)
|
|
|
|
msg = msg.replace('\\\\', '\\')
|
|
|
|
# s12 = 'test\\ntest\\\\ntest'
|
|
|
|
# s13 = re.sub('\n', s12)
|
|
|
|
# s14 s13.replace('\\\\', '\\')
|
|
|
|
# s14
|
|
|
|
# 'test\ntest\\ntest'
|
|
|
|
return msg
|
2005-07-22 16:30:35 +02:00
|
|
|
|
|
|
|
def get_uf_chatstate(chatstate):
|
|
|
|
'''removes chatstate jargon and returns user friendly messages'''
|
|
|
|
if chatstate == 'active':
|
|
|
|
return _('is paying attention to the conversation')
|
|
|
|
elif chatstate == 'inactive':
|
|
|
|
return _('is doing something else')
|
|
|
|
elif chatstate == 'composing':
|
|
|
|
return _('is composing a message...')
|
|
|
|
elif chatstate == 'paused':
|
2005-08-09 13:33:56 +02:00
|
|
|
#paused means he was compoing but has stopped for a while
|
|
|
|
return _('paused composing a message')
|
2005-07-22 16:30:35 +02:00
|
|
|
elif chatstate == 'gone':
|
2005-07-22 16:35:34 +02:00
|
|
|
return _('has closed the chat window or tab')
|
2005-08-09 13:33:56 +02:00
|
|
|
|
|
|
|
def is_in_path(name_of_command, return_abs_path = False):
|
|
|
|
# if return_abs_path is True absolute path will be returned
|
|
|
|
# for name_of_command
|
|
|
|
# on failures False is returned
|
|
|
|
is_in_dir = False
|
|
|
|
found_in_which_dir = None
|
|
|
|
path = os.getenv('PATH').split(':')
|
|
|
|
for path_to_directory in path:
|
|
|
|
try:
|
|
|
|
contents = os.listdir(path_to_directory)
|
|
|
|
except OSError: # user can have something in PATH that is not a dir
|
|
|
|
pass
|
2005-08-10 02:10:43 +02:00
|
|
|
else:
|
|
|
|
is_in_dir = name_of_command in contents
|
2005-08-09 13:33:56 +02:00
|
|
|
if is_in_dir:
|
|
|
|
if return_abs_path:
|
|
|
|
found_in_which_dir = path_to_directory
|
|
|
|
break
|
|
|
|
|
|
|
|
if found_in_which_dir:
|
|
|
|
abs_path = os.path.join(path_to_directory, name_of_command)
|
|
|
|
return abs_path
|
|
|
|
else:
|
|
|
|
return is_in_dir
|
2005-08-10 00:46:13 +02:00
|
|
|
|
2005-08-10 00:55:52 +02:00
|
|
|
def launch_browser_mailer(kind, uri):
|
2005-08-10 00:46:13 +02:00
|
|
|
#kind = 'url' or 'mail'
|
|
|
|
if os.name == 'nt':
|
|
|
|
try:
|
|
|
|
os.startfile(uri) # if pywin32 is installed we open
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
|
|
|
|
else:
|
|
|
|
if kind == 'url' and not\
|
|
|
|
(uri.startswith('http://') or uri.startswith('https://')):
|
|
|
|
uri = 'http://' + uri
|
|
|
|
elif kind == 'mail' and not uri.startswith('mailto:'):
|
|
|
|
uri = 'mailto:' + uri
|
|
|
|
|
|
|
|
if gajim.config.get('openwith') == 'gnome-open':
|
|
|
|
command = 'gnome-open'
|
|
|
|
elif gajim.config.get('openwith') == 'kfmclient exec':
|
|
|
|
command = 'kfmclient exec'
|
|
|
|
elif gajim.config.get('openwith') == 'custom':
|
|
|
|
if kind == 'url':
|
|
|
|
command = gajim.config.get('custombrowser')
|
|
|
|
if kind == 'mail':
|
|
|
|
command = gajim.config.get('custommailapp')
|
|
|
|
if command == '': # if no app is configured
|
|
|
|
return
|
|
|
|
# we add the uri in "" so we have good parsing from shell
|
2005-08-11 14:40:47 +02:00
|
|
|
uri = uri.replace('"', '\\"') # escape "
|
2005-08-10 00:46:13 +02:00
|
|
|
command = command + ' "' + uri + '" &'
|
2005-08-10 00:55:52 +02:00
|
|
|
try: #FIXME: when we require python2.4+ use subprocess module
|
2005-08-10 00:46:13 +02:00
|
|
|
os.system(command)
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
|
2005-08-10 00:55:52 +02:00
|
|
|
def launch_file_manager(path_to_open):
|
2005-08-11 13:44:14 +02:00
|
|
|
if os.name == 'nt':
|
|
|
|
try:
|
|
|
|
os.startfile(path_to_open) # if pywin32 is installed we open
|
|
|
|
except:
|
|
|
|
pass
|
2005-08-11 14:36:32 +02:00
|
|
|
else:
|
|
|
|
if gajim.config.get('openwith') == 'gnome-open':
|
|
|
|
command = 'gnome-open'
|
|
|
|
elif gajim.config.get('openwith') == 'kfmclient exec':
|
|
|
|
command = 'kfmclient exec'
|
|
|
|
elif gajim.config.get('openwith') == 'custom':
|
|
|
|
command = gajim.config.get('custom_file_manager')
|
|
|
|
if command == '': # if no app is configured
|
|
|
|
return
|
|
|
|
# we add the path in "" so we have good parsing from shell
|
2005-08-11 14:40:47 +02:00
|
|
|
path_to_open = path_to_open.replace('"', '\\"') # escape "
|
2005-08-11 14:36:32 +02:00
|
|
|
command = command + ' "' + path_to_open + '" &'
|
|
|
|
try: #FIXME: when we require python2.4+ use subprocess module
|
|
|
|
os.system(command)
|
|
|
|
except:
|
|
|
|
pass
|
2005-08-10 00:55:52 +02:00
|
|
|
|
|
|
|
def play_sound(event):
|
2005-08-10 00:46:13 +02:00
|
|
|
if not gajim.config.get('sounds_on'):
|
|
|
|
return
|
|
|
|
path_to_soundfile = gajim.config.get_per('soundevents', event, 'path')
|
2005-09-11 22:33:10 +02:00
|
|
|
if path_to_soundfile == 'beep':
|
|
|
|
print '\a' # make a speaker beep
|
|
|
|
return
|
2005-08-10 00:46:13 +02:00
|
|
|
if not os.path.exists(path_to_soundfile):
|
|
|
|
return
|
|
|
|
if os.name == 'nt':
|
|
|
|
try:
|
|
|
|
winsound.PlaySound(path_to_soundfile,
|
|
|
|
winsound.SND_FILENAME|winsound.SND_ASYNC)
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
elif os.name == 'posix':
|
|
|
|
if gajim.config.get('soundplayer') == '':
|
|
|
|
return
|
|
|
|
player = gajim.config.get('soundplayer')
|
|
|
|
# we add the path in "" so we have good parsing from shell
|
2005-08-14 21:27:58 +02:00
|
|
|
path_to_soundfile = path_to_soundfile.replace('"', '\\"') # escape "
|
2005-08-10 00:46:13 +02:00
|
|
|
command = player + ' "' + path_to_soundfile + '" &'
|
|
|
|
#FIXME: when we require 2.4+ use subprocess module
|
|
|
|
os.system(command)
|
2005-08-14 21:08:56 +02:00
|
|
|
|
|
|
|
def get_file_path_from_dnd_dropped_uri(uri):
|
|
|
|
path = urllib.url2pathname(uri) # escape special chars
|
|
|
|
path = path.strip('\r\n\x00') # remove \r\n and NULL
|
|
|
|
# get the path to file
|
2005-08-17 00:38:21 +02:00
|
|
|
if path.startswith('file:\\\\\\'): # windows
|
|
|
|
path = path[8:] # 8 is len('file:///')
|
|
|
|
elif path.startswith('file://'): # nautilus, rox
|
2005-08-14 21:08:56 +02:00
|
|
|
path = path[7:] # 7 is len('file://')
|
|
|
|
elif path.startswith('file:'): # xffm
|
|
|
|
path = path[5:] # 5 is len('file:')
|
|
|
|
return path
|
2005-08-18 21:06:24 +02:00
|
|
|
|
|
|
|
def from_xs_boolean_to_python_boolean(value):
|
|
|
|
# this is xs:boolean so 'true','false','1','0'
|
|
|
|
# convert those to True/False (python booleans)
|
2005-08-18 21:25:12 +02:00
|
|
|
if value in ('1', 'true'):
|
2005-08-18 21:06:24 +02:00
|
|
|
val = True
|
|
|
|
else: # '0', 'false' or anything else
|
|
|
|
val = False
|
|
|
|
|
|
|
|
return val
|
|
|
|
|
2005-08-26 14:08:14 +02:00
|
|
|
def ensure_unicode_string(s):
|
|
|
|
# py23 u'abc'.decode('utf-8') raises
|
|
|
|
# python24 does not. is python23 is ooold we can remove this func
|
2005-08-26 14:14:08 +02:00
|
|
|
if isinstance(s, str):
|
2005-08-26 14:08:14 +02:00
|
|
|
s = s.decode('utf-8')
|
|
|
|
return s
|
2005-09-05 15:28:09 +02:00
|
|
|
|
|
|
|
def get_xmpp_show(show):
|
|
|
|
if show in ['online', 'offline']:
|
|
|
|
return None
|
|
|
|
return show
|
2005-08-26 14:08:14 +02:00
|
|
|
|