1 diff -urN gajim-0.8.orig/scripts/gajim-remote gajim-0.8/scripts/gajim-remote
2 --- gajim-0.8.orig/scripts/gajim-remote 2005-08-19 12:58:20.182083440 +0200
3 +++ gajim-0.8/scripts/gajim-remote 2005-08-19 12:59:44.453272272 +0200
5 echo "You must not launch gajim-remote as root, it is INSECURE"
8 -cd PREFIX/share/gajim/scripts
9 +cd PREFIX/share/gajim/src
10 export PYTHONPATH="$PYTHONPATH:PREFIXLIB/gajim"
11 python gajim-remote.py $@
12 diff -urN gajim-0.8.orig/src/gajim-remote.py gajim-0.8/src/gajim-remote.py
13 --- gajim-0.8.orig/src/gajim-remote.py 1970-01-01 01:00:00.000000000 +0100
14 +++ gajim-0.8/src/gajim-remote.py 2005-08-19 12:47:58.598578496 +0200
18 +exec python -OOt "$0" ${1+"$@"}
20 +## scripts/gajim-remote.py
23 +## - Yann Le Boulanger <asterix@lagaule.org>
24 +## - Vincent Hanquez <tab@snarc.org>
25 +## - Nikos Kouremenos <kourem@gmail.com>
26 +## - Dimitur Kirov <dkirov@gmail.com>
28 +## Copyright (C) 2003-2005 Gajim Team
30 +## This program is free software; you can redistribute it and/or modify
31 +## it under the terms of the GNU General Public License as published
32 +## by the Free Software Foundation; version 2 only.
34 +## This program is distributed in the hope that it will be useful,
35 +## but WITHOUT ANY WARRANTY; without even the implied warranty of
36 +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37 +## GNU General Public License for more details.
40 +# gajim-remote help will show you the DBUS API of Gajim
48 +signal.signal(signal.SIGINT, signal.SIG_DFL) # ^C exits the application
59 + send_error('Dbus is not supported.\n')
61 +_version = getattr(dbus, 'version', (0, 20, 0))
62 +if _version[1] >= 41:
66 +OBJ_PATH = '/org/gajim/dbus/RemoteObject'
67 +INTERFACE = 'org.gajim.dbus.RemoteInterface'
68 +SERVICE = 'org.gajim.dbus'
69 +BASENAME = 'gajim-remote'
74 + self.argv_len = len(sys.argv)
75 + # define commands dict. Prototype :
77 + # 'command': [comment, [list of arguments] ]
80 + # each argument is defined as a tuple:
81 + # (argument name, help on argument, is mandatory)
85 + _('show a help on specific command'),
87 + #parameter, named "on_command". User gets help for the command, specified by this parameter
89 + _('show help on command'), False)
92 + 'toggle_roster_appearance' : [
93 + _('Shows or hides the roster window'),
96 + 'show_next_unread': [
97 + _('Popup a window with the next unread message'),
101 + _('Print a list of all contacts in the roster. \
102 +Each contact appear on a separate line'),
104 + (_('account'), _('show only contacts of the \
105 +given account'), False)
110 + _('Print a list of registered accounts'),
114 + _('Change the status of account or accounts'),
116 + (_('status'), _('one of: offline, online, chat, away, \
117 +xa, dnd, invisible '), True),
118 + (_('message'), _('status message'), False),
119 + (_('account'), _('change status of account "account". \
120 +If not specified, try to change status of all accounts that \
121 +have "sync with global status" option set'), False)
125 + _('Show the chat dialog so that you can send message to a \
128 + #tell nkour that should be JID of the contact
129 + ('jid', _('jid of the contact that you want to chat \
132 + (_('account'), _('if specified, contact is taken from \
133 +the contact list of this account'), False)
137 + #OpenPGP key here too (tlel that to nkour)
138 + _('Send new message to a contact in the roster. Both OpenPGP \
139 +key and account are optional. If you want to set only \'account\', without \
140 +\'pgp key\', just set \'pgp key\' to \'\'.'),
142 + #tell nkour that should be JID of the contact
143 + ('jid', _('jid of the contact that will receive the \
145 + (_('message'), _('message contents'), True),
146 + #tell to nkour it should be OpenPGP key
147 + (_('pgp key'), _('if specified, the message will be \
148 +encrypted using this public key'), False),
149 + (_('account'), _('if specified, the message will be \
150 +sent using this account'), False),
154 + _('Get detailed info on a contact'),
156 + #JID of the contact (tell that to nkour)
157 + ('jid', _('jid of the contact'), True)
161 + if self.argv_len < 2 or \
162 + sys.argv[1] not in self.commands.keys(): # no args or bad args
163 + self.send_error(self.compose_help())
164 + self.command = sys.argv[1]
166 + if self.command == 'help':
167 + if self.argv_len == 3:
168 + print self.help_on_command(sys.argv[2])
170 + print self.compose_help()
173 + self.init_connection()
174 + self.check_arguments()
176 + if self.command == 'contact_info':
177 + if self.argv_len < 3:
178 + self.send_error(_('Missing argument "contact_jid"'))
180 + id = self.sbus.add_signal_receiver(self.show_vcard_info,
181 + 'VcardInfo', INTERFACE, SERVICE, OBJ_PATH)
183 + self.send_error(_('Service not available'))
185 + res = self.call_remote_method()
186 + self.print_result(res)
188 + if self.command == 'contact_info':
189 + gobject.timeout_add(10000, self.gtk_quit) # wait 10 sec for response
192 + def print_result(self, res):
193 + ''' Print retrieved result to the output '''
194 + if res is not None:
195 + if self.command in ['open_chat', 'send_message']:
196 + if self.command == 'send_message':
200 + if self.argv_len < 4:
201 + self.send_error(_('\'%s\' is not in your roster.\n\
202 +Please specify account for sending the message.') % sys.argv[2])
204 + self.send_error(_('You have no active account'))
205 + elif self.command == 'list_accounts':
206 + if type(res) == list:
207 + for account in res:
209 + elif self.command == 'list_contacts':
210 + for single_res in res:
211 + accounts = self.unrepr(single_res)
212 + for account_dict in accounts:
213 + print self.print_info(0, account_dict)
217 + def init_connection(self):
218 + ''' create the onnection to the session dbus,
219 + or exit if it is not possible '''
221 + self.sbus = dbus.SessionBus()
223 + self.send_error(_('Session bus is not available.'))
225 + if _version[1] >= 30 and _version[1] <= 42:
226 + obj = self.sbus.get_object(SERVICE, OBJ_PATH)
227 + interface = dbus.Interface(obj, INTERFACE)
228 + elif _version[1] < 30:
229 + self.service = self.sbus.get_service(SERVICE)
230 + interface = self.service.get_object(OBJ_PATH, INTERFACE)
232 + #say to nkour that this should be Unknown D-Bus version: %s (thanks nebulam)
233 + send_error(_('Unknown dbus version: %s') % _version)
235 + # get the function asked
236 + self.method = interface.__getattr__(self.command)
238 + def make_arguments_row(self, args):
239 + ''' return arguments list. Mandatory arguments are enclosed with:
240 + '<', '>', optional arguments - with '[', ']' '''
242 + for argument in args:
255 + def help_on_command(self, command):
256 + ''' return help message for a given command '''
257 + if command in self.commands:
258 + command_props = self.commands[command]
259 + arguments_str = self.make_arguments_row(command_props[1])
260 + str = _('Usage: %s %s %s \n\t') % (BASENAME, command,
262 + str += command_props[0] + '\n\n' + _('Arguments:') + '\n'
263 + for argument in command_props[1]:
264 + str += ' ' + argument[0] + ' - ' + argument[1] + '\n'
266 + self.send_error(_('%s not found') % command)
268 + def compose_help(self):
269 + ''' print usage, and list available commands '''
270 + str = _('Usage: %s command [arguments]\nCommand is one of:\n' ) % BASENAME
271 + for command in self.commands.keys():
272 + str += ' ' + command
273 + for argument in self.commands[command][1]:
287 + def print_info(self, level, prop_dict):
288 + ''' return formated string from serialized vcard data '''
289 + if prop_dict is None or type(prop_dict) \
290 + not in [dict, list, tuple]:
293 + if type(prop_dict) in [list, tuple]:
295 + spacing = ' ' * level * 4
296 + for val in prop_dict:
299 + elif type(val) == unicode or type(val) == int or \
301 + ret_str +='\t' + str(val)
302 + elif type(val) == list or type(val) == tuple:
305 + res += self.print_info(level+1, items)
307 + ret_str += '\t' + res
308 + ret_str = '%s(%s)\n' % (spacing, ret_str[1:])
309 + elif type(prop_dict) is dict:
310 + for key in prop_dict.keys():
311 + val = prop_dict[key]
312 + spacing = ' ' * level * 4
313 + if type(val) == unicode or type(val) == int or \
315 + if val is not None:
317 + ret_str += '%s%-10s: %s\n' % (spacing, key, val)
318 + elif type(val) == list or type(val) == tuple:
321 + res += self.print_info(level+1, items)
323 + ret_str += '%s%s: \n%s' % (spacing, key, res)
324 + elif type(val) == dict:
325 + res = self.print_info(level+1, val)
327 + ret_str += '%s%s: \n%s' % (spacing, key, res)
329 + self.send_warning(_('Unknown type %s ') % type(val))
332 + def unrepr(self, serialized_data):
333 + ''' works the same as eval, but only for structural values,
334 + not functions! e.g. dicts, lists, strings, tuples '''
335 + if not serialized_data:
337 + value = serialized_data.strip()
338 + first_char = value[0]
342 + if first_char == 'u':
345 + first_char = value[0]
346 + elif '0123456789.'.find(first_char) != -1:
349 + if first_char == '.':
353 + for i in range(len(value) - 1):
357 + elif '0123456789'.find(chr) == -1:
361 + return (float(_str), value[len(_str):])
363 + return (int(_str), value[len(_str):])
364 + elif first_char == 'N':
365 + if value[1:4] == 'one':
366 + return (None, value[4:])
369 + if first_char == "'" or first_char == '"': # handle strings and unicode
371 + return ('',value[1:])
373 + previous_slash = False
374 + for i in range(len(value) - 1):
377 + previous_slash = False
392 + elif chr == 'u' and is_unicode:
394 + elif chr == first_char:
397 + previous_slash = True
400 + substr_len = len(_str)+2
401 + if is_unicode and _str:
402 + _str = _str.decode('unicode-escape').encode('utf-8')
403 + return (_str, value[substr_len :])
404 + elif first_char == '{': # dict
407 + if value[1] == '}':
409 + key, next = self.unrepr(value[1:])
410 + if type(key) != str and type(key) != unicode:
411 + send_error('Wrong string: %s' % value)
412 + next = next.strip()
413 + if not next or next[0] != ':':
414 + send_error('Wrong string: %s' % (value))
415 + val, next = self.unrepr(next[1:])
417 + next = next.strip()
422 + elif next[0] == '}':
426 + return (_dict, next[1:])
427 + elif first_char in ['[', '(']: # return list
430 + if value[1] == ']':
432 + val, next = self.unrepr(value[1:])
433 + next = next.strip()
435 + send_error('Wrong string: %s' % val)
437 + next = next.strip()
442 + elif next[0] in [']', ')']:
444 + return (_tuple, next[1:])
446 + def show_vcard_info(self, *args, **keyword):
447 + ''' write user vcart in a formated output '''
449 + if _version[1] >= 30:
450 + props_dict = self.unrepr(args[0])
452 + if args and len(args) >= 5:
453 + props_dict = self.unrepr(args[4].get_args_list()[0])
456 + print self.print_info(0,props_dict[0])
457 + # remove_signal_receiver is broken in lower versions (< 0.35),
458 + # so we leave the leak - nothing can be done
459 + if _version[1] >= 41:
460 + self.sbus.remove_signal_receiver(show_vcard_info, 'VcardInfo',
461 + INTERFACE, SERVICE, OBJ_PATH)
465 + def check_arguments(self):
466 + ''' Make check if all necessary arguments are given '''
467 + argv_len = self.argv_len - 2
468 + args = self.commands[self.command][1]
469 + if len(args) > argv_len:
470 + if args[argv_len][2]:
471 + self.send_error(_('Argument "%s" is not specified. \n\
472 +Type "%s help %s" for more info') % (args[argv_len][0], BASENAME, self.command))
474 + def gtk_quit(self):
475 + if _version[1] >= 41:
476 + self.sbus.remove_signal_receiver(show_vcard_info, 'VcardInfo',
477 + INTERFACE, SERVICE, OBJ_PATH)
480 + # FIXME - didn't find more clever way for the below method.
481 + # method(sys.argv[2:]) doesn't work, cos sys.argv[2:] is a tuple
482 + def call_remote_method(self):
483 + ''' calls self.method with arguments from sys.argv[2:] '''
485 + if self.argv_len == 2:
486 + res = self.method()
487 + elif self.argv_len == 3:
488 + res = self.method(sys.argv[2])
489 + elif self.argv_len == 4:
490 + res = self.method(sys.argv[2], sys.argv[3])
491 + elif self.argv_len == 5:
492 + res = self.method(sys.argv[2], sys.argv[3], sys.argv[4])
493 + elif argv_len == 6:
494 + res = self.method(sys.argv[2], sys.argv[3], sys.argv[4],
498 + self.send_error(_('Service not available'))
501 + def send_error(self, error_message):
502 + ''' Writes error message to stderr and exits '''
503 + sys.stderr.write(error_message + '\n')
507 +if __name__ == '__main__':
509 diff -urN gajim-0.8.orig/src/i18n.py gajim-0.8/src/i18n.py
510 --- gajim-0.8.orig/src/i18n.py 1970-01-01 01:00:00.000000000 +0100
511 +++ gajim-0.8/src/i18n.py 2005-08-19 13:05:59.485258744 +0200
516 +## - Yann Le Boulanger <asterix@lagaule.org>
517 +## - Vincent Hanquez <tab@snarc.org>
518 +## - Nikos Kouremenos <kourem@gmail.com>
519 +## - Dimitur Kirov <dkirov@gmail.com>
521 +## Copyright (C) 2003-2005 Gajim Team
523 +## This program is free software; you can redistribute it and/or modify
524 +## it under the terms of the GNU General Public License as published
525 +## by the Free Software Foundation; version 2 only.
527 +## This program is distributed in the hope that it will be useful,
528 +## but WITHOUT ANY WARRANTY; without even the implied warranty of
529 +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
530 +## GNU General Public License for more details.
539 +locale.setlocale(locale.LC_ALL, '')
543 + global _translation
545 + _translation = gettext.translation(APP, DIR)
547 + _translation = gettext.NullTranslations()
553 + return _translation.gettext(s)