From 3198ae10d90cb93ff2b27ce4c6b09f2f5e2aa871 Mon Sep 17 00:00:00 2001 From: Goffi Date: Mon, 18 Apr 2016 18:30:55 +0200 Subject: [PATCH 01/14] added mutagen to recommended in README4PACKAGERS --- README4PACKAGERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README4PACKAGERS b/README4PACKAGERS index 51d553e5..90ba4260 100644 --- a/README4PACKAGERS +++ b/README4PACKAGERS @@ -28,7 +28,7 @@ Wokkel >= 0.7.1 XDG zope.interface -Recommended: markdown, html2text, netifaces, miniupnp +Recommended: Mutagen, markdown, html2text, netifaces, miniupnp -------------------------------- Dependencies for the Jp frontend From bf45c1d91cd1a98e113ff4a77db1c61d420988ce Mon Sep 17 00:00:00 2001 From: Goffi Date: Tue, 19 Apr 2016 20:09:02 +0200 Subject: [PATCH 02/14] jp: forgotten shebang fixes --- frontends/src/jp/base.py | 2 +- frontends/src/jp/jp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontends/src/jp/base.py b/frontends/src/jp/base.py index 24aae9b1..99678caa 100644 --- a/frontends/src/jp/base.py +++ b/frontends/src/jp/base.py @@ -1,4 +1,4 @@ -#! /usr/bin/python +#!/usr/bin/env python2 # -*- coding: utf-8 -*- # jp: a SAT command line tool diff --git a/frontends/src/jp/jp b/frontends/src/jp/jp index 814b113b..7e886c95 100755 --- a/frontends/src/jp/jp +++ b/frontends/src/jp/jp @@ -1,4 +1,4 @@ -#! /usr/bin/python +#!/usr/bin/env python2 # -*- coding: utf-8 -*- # jp: a SAT command line tool From 6dd58f0878a84fc051173dbb6843aeade52df123 Mon Sep 17 00:00:00 2001 From: Goffi Date: Thu, 21 Apr 2016 20:20:40 +0200 Subject: [PATCH 03/14] primitivus: paste is now detected, and put in edit bar, so use can check and validate it --- frontends/src/primitivus/primitivus | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/frontends/src/primitivus/primitivus b/frontends/src/primitivus/primitivus index 73801070..48a194bb 100755 --- a/frontends/src/primitivus/primitivus +++ b/frontends/src/primitivus/primitivus @@ -361,6 +361,23 @@ class PrimitivusApp(QuickApp, InputHistory): def inputFilter(self, input_, raw): if self.__saved_overlay and input_ != a_key['OVERLAY_HIDE']: return + + if len(input_) > 1: # XXX: it may be needed to increase this value if buffer + # or other things result in several chars at once + # (e.g. using Primitivus through ssh). Need some testing + # and experience to adjust value. + log.debug(u"Paste detected") + try: + edit_bar = self.editBar + except AttributeError: + log.warning(u"Paste discarded: there is no edit bar yet") + else: + # XXX: if a paste is detected, we append it directly to the edit bar text + # so the use can check it and press [enter] if it's OK + buf_paste = u''.join((unichr(k) for k in raw)) + edit_bar.set_edit_text(u'{}{}'.format(edit_bar.edit_text, buf_paste)) + return + for i in input_: if isinstance(i,tuple): if i[0] == 'mouse press': From 6c30009ef8cf8a57d03a0bf7238c94840dda543e Mon Sep 17 00:00:00 2001 From: Goffi Date: Fri, 22 Apr 2016 22:30:13 +0200 Subject: [PATCH 04/14] primitivus: fixed paste detection/handling: - mouse and window events are discarded - input_ is used to get text - cursor position is used to paste buffer in the good place, and updated once finished --- frontends/src/primitivus/primitivus | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/frontends/src/primitivus/primitivus b/frontends/src/primitivus/primitivus index 48a194bb..ab89da58 100755 --- a/frontends/src/primitivus/primitivus +++ b/frontends/src/primitivus/primitivus @@ -25,6 +25,7 @@ log_config.satConfigure(C.LOG_BACKEND_STANDARD, C) from sat.core import log as logging log = logging.getLogger(__name__) import urwid +from urwid.util import is_wide_char from urwid_satext import sat_widgets from urwid_satext.files_management import FileDialog from sat_frontends.bridge.DBus import DBusBridgeFrontend @@ -358,15 +359,25 @@ class PrimitivusApp(QuickApp, InputHistory): self.showPopUp(popup) super(PrimitivusApp, self).postInit(self.main_widget) + def keysToText(self, keys): + """Generator return normal text from urwid keys""" + for k in keys: + if k == 'tab': + yield u'\t' + elif k == 'enter': + yield u'\n' + elif is_wide_char(k,0) or (len(k)==1 and ord(k) >= 32): + yield k + def inputFilter(self, input_, raw): if self.__saved_overlay and input_ != a_key['OVERLAY_HIDE']: return - if len(input_) > 1: # XXX: it may be needed to increase this value if buffer - # or other things result in several chars at once - # (e.g. using Primitivus through ssh). Need some testing - # and experience to adjust value. - log.debug(u"Paste detected") + if (len(input_) > 1 and # XXX: it may be needed to increase this value if buffer + not isinstance(input_[0], tuple) and # or other things result in several chars at once + not 'window' in input_[0]): # (e.g. using Primitivus through ssh). Need some testing + # and experience to adjust value. + log.debug(u"Paste detected (len {})".format(len(input_))) try: edit_bar = self.editBar except AttributeError: @@ -374,8 +385,10 @@ class PrimitivusApp(QuickApp, InputHistory): else: # XXX: if a paste is detected, we append it directly to the edit bar text # so the use can check it and press [enter] if it's OK - buf_paste = u''.join((unichr(k) for k in raw)) - edit_bar.set_edit_text(u'{}{}'.format(edit_bar.edit_text, buf_paste)) + buf_paste = u''.join(self.keysToText(input_)) + pos = edit_bar.edit_pos + edit_bar.set_edit_text(u'{}{}{}'.format(edit_bar.edit_text[:pos], buf_paste, edit_bar.edit_text[pos:])) + edit_bar.edit_pos+=len(buf_paste) return for i in input_: From 0d3a96a8da33b93ab2989dab3507fede9c41f948 Mon Sep 17 00:00:00 2001 From: Goffi Date: Sat, 23 Apr 2016 00:31:59 +0200 Subject: [PATCH 05/14] primitivus: bracketed paste mode is now detected --- frontends/src/primitivus/primitivus | 30 +++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/frontends/src/primitivus/primitivus b/frontends/src/primitivus/primitivus index ab89da58..28afb4a9 100755 --- a/frontends/src/primitivus/primitivus +++ b/frontends/src/primitivus/primitivus @@ -301,6 +301,7 @@ class PrimitivusApp(QuickApp, InputHistory): # we already manage exit with a_key['APP_QUIT'], so we don't want C-c signal.signal(signal.SIGINT, signal.SIG_IGN) + self._bracketed_paste = False @property def visible_widgets(self): @@ -377,6 +378,33 @@ class PrimitivusApp(QuickApp, InputHistory): not isinstance(input_[0], tuple) and # or other things result in several chars at once not 'window' in input_[0]): # (e.g. using Primitivus through ssh). Need some testing # and experience to adjust value. + if input_[0] == 'begin paste' and not self._bracketed_paste: + log.info(u"Bracketed paste mode detected") + self._bracketed_paste = True + + if self._bracketed_paste: + # after this block, extra will contain non pasted keys + # and input_ will contain pasted keys + try: + begin_idx = input_.index('begin paste') + except ValueError: + # this is not a paste, maybe we have something buffering + # or bracketed mode is set in conf but not enabled in term + extra = input_ + input_ = [] + else: + try: + end_idx = input_.index('end paste') + except ValueError: + log.warning(u"missing end paste sequence, discarding paste") + extra = input_[:begin_idx] + del input_[begin_idx:] + else: + extra = input_[:begin_idx] + input_[end_idx+1:] + input_ = input_[begin_idx+1:end_idx] + else: + extra = None + log.debug(u"Paste detected (len {})".format(len(input_))) try: edit_bar = self.editBar @@ -389,7 +417,9 @@ class PrimitivusApp(QuickApp, InputHistory): pos = edit_bar.edit_pos edit_bar.set_edit_text(u'{}{}{}'.format(edit_bar.edit_text[:pos], buf_paste, edit_bar.edit_text[pos:])) edit_bar.edit_pos+=len(buf_paste) + if not extra: return + input_ = extra for i in input_: if isinstance(i,tuple): From 724fa7541a4d8a3455115ed785d9ca7b0db2de54 Mon Sep 17 00:00:00 2001 From: Goffi Date: Sat, 23 Apr 2016 01:28:35 +0200 Subject: [PATCH 06/14] primitivus: added bracketed_paste option in sat.conf (if set, the bracketed paste mode will be activated on Primitivus start) --- frontends/src/primitivus/constants.py | 1 + frontends/src/primitivus/primitivus | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/frontends/src/primitivus/constants.py b/frontends/src/primitivus/constants.py index e42fe758..d97a6c2f 100644 --- a/frontends/src/primitivus/constants.py +++ b/frontends/src/primitivus/constants.py @@ -23,6 +23,7 @@ from sat_frontends.quick_frontend import constants class Const(constants.Const): APP_NAME = "Primitivus" + SECTION_NAME = APP_NAME.lower() PALETTE = [ ('title', 'black', 'light gray', 'standout,underline'), ('title_focus', 'white,bold', 'light gray', 'standout,underline'), diff --git a/frontends/src/primitivus/primitivus b/frontends/src/primitivus/primitivus index 28afb4a9..d9043c88 100755 --- a/frontends/src/primitivus/primitivus +++ b/frontends/src/primitivus/primitivus @@ -24,6 +24,7 @@ from sat.core import log_config log_config.satConfigure(C.LOG_BACKEND_STANDARD, C) from sat.core import log as logging log = logging.getLogger(__name__) +from sat.tools import config as sat_config import urwid from urwid.util import is_wide_char from urwid_satext import sat_widgets @@ -44,6 +45,7 @@ from sat_frontends.tools.misc import InputHistory from sat_frontends.tools import jid from os.path import join import signal +import sys class EditBar(sat_widgets.ModalEdit): @@ -301,7 +303,12 @@ class PrimitivusApp(QuickApp, InputHistory): # we already manage exit with a_key['APP_QUIT'], so we don't want C-c signal.signal(signal.SIGINT, signal.SIG_IGN) - self._bracketed_paste = False + sat_conf = sat_config.parseMainConf() + self._bracketed_paste = C.bool(sat_config.getConfig(sat_conf, C.SECTION_NAME, 'bracketed_paste', 'false')) + if self._bracketed_paste: + log.debug("setting bracketed paste mode as requested") + sys.stdout.write("\033[?2004h") + self._bracketed_mode_set = True @property def visible_widgets(self): @@ -374,6 +381,7 @@ class PrimitivusApp(QuickApp, InputHistory): if self.__saved_overlay and input_ != a_key['OVERLAY_HIDE']: return + ## paste detection/handling if (len(input_) > 1 and # XXX: it may be needed to increase this value if buffer not isinstance(input_[0], tuple) and # or other things result in several chars at once not 'window' in input_[0]): # (e.g. using Primitivus through ssh). Need some testing @@ -420,6 +428,7 @@ class PrimitivusApp(QuickApp, InputHistory): if not extra: return input_ = extra + ## end of paste detection/handling for i in input_: if isinstance(i,tuple): @@ -822,6 +831,12 @@ class PrimitivusApp(QuickApp, InputHistory): def onExitRequest(self, menu): QuickApp.onExit(self) + try: + if self._bracketed_mode_set: # we don't unset if bracketed paste mode was detected automatically (i.e. not in conf) + log.debug("unsetting bracketed paste mode") + sys.stdout.write("\033[?2004l") + except AttributeError: + pass raise urwid.ExitMainLoop() def onJoinRoomRequest(self, menu): From b8e62dd69c9656486197225a66bfc877d5e315e4 Mon Sep 17 00:00:00 2001 From: Goffi Date: Sat, 23 Apr 2016 23:10:03 +0200 Subject: [PATCH 07/14] jp: --output option: - new --output option can be added wich use_output. use_output can be True (in which case it wild default to C.OUTPUT_TEXT), or any of C.OUTPUT_TYPES (currently text, list and dict) - output change the output format mainly to make command result parsing more easy, but it can also be use to add fancy effects (like coloration) - outputs are added with plugins in the same way as commands (import of both is done in the same method) - in the command class, output need to be declared with use_output=C.OUTPUT_xxx, then the data only need to be processed with self.output(data) - outputs can have description (not used yet) - use_xxx argument handling has been refactored (minor refactoring) to be more generic - first outputs are "default", "json" (pretty printed) and "json_raw" (compact json) - the first command to use them is "profile list" --- frontends/src/jp/base.py | 105 ++++++++++++++++++++++++-------- frontends/src/jp/cmd_profile.py | 5 +- frontends/src/jp/constants.py | 6 ++ frontends/src/jp/jp | 2 +- frontends/src/jp/output_std.py | 58 ++++++++++++++++++ 5 files changed, 147 insertions(+), 29 deletions(-) create mode 100644 frontends/src/jp/output_std.py diff --git a/frontends/src/jp/base.py b/frontends/src/jp/base.py index 99678caa..b901538d 100644 --- a/frontends/src/jp/base.py +++ b/frontends/src/jp/base.py @@ -39,6 +39,7 @@ import sat_frontends.jp from sat_frontends.jp.constants import Const as C import xml.etree.ElementTree as ET # FIXME: used temporarily to manage XMLUI import shlex +from collections import OrderedDict if sys.version_info < (2, 7, 3): # XXX: shlex.split only handle unicode since python 2.7.3 @@ -116,6 +117,11 @@ class Jp(object): self._progress_id = None # TODO: manage several progress ids self.quit_on_progress_end = True + # outputs + self._outputs = {} + for type_ in C.OUTPUT_TYPES: + self._outputs[type_] = OrderedDict() + @property def version(self): return self.bridge.getVersion() @@ -179,6 +185,9 @@ class Jp(object): else: print msg + def output(self, type_, name, data): + self._outputs[type_][name]['callback'](data) + def addOnQuitCallback(self, callback, *args, **kwargs): """Add a callback which will be called on quit command @@ -191,6 +200,14 @@ class Jp(object): finally: callbacks_list.append((callback, args, kwargs)) + def getOutputChoices(self, output_type): + """Return valid output filters for output_type + + @param output_type: True for default, + else can be any registered type + """ + return self._outputs[output_type].keys() + def _make_parents(self): self.parents = {} @@ -220,32 +237,45 @@ class Jp(object): def add_parser_options(self): self.parser.add_argument('--version', action='version', version=("%(name)s %(version)s %(copyleft)s" % {'name': PROG_NAME, 'version': self.version, 'copyleft': COPYLEFT})) - def import_commands(self): - """ Automaticaly import commands to jp - looks from modules names cmd_*.py in jp path and import them + def register_output(self, type_, name, callback, description=""): + if type_ not in C.OUTPUT_TYPES: + log.error(u"Invalid output type {}".format(type_)) + return + self._outputs[type_][name] = {'callback': callback, + 'description': description + } + def import_plugins(self): + """Automaticaly import commands and outputs in jp + + looks from modules names cmd_*.py in jp path and import them """ path = os.path.dirname(sat_frontends.jp.__file__) - modules = (os.path.splitext(module)[0] for module in map(os.path.basename, iglob(os.path.join(path, "cmd_*.py")))) - for module_name in modules: - module = import_module("sat_frontends.jp."+module_name) - try: - self.import_command_module(module) - except ImportError: - continue + # XXX: outputs must be imported before commands as they are used for arguments + for type_, pattern in ((C.PLUGIN_OUTPUT, 'output_*.py'), (C.PLUGIN_CMD, 'cmd_*.py')): + modules = (os.path.splitext(module)[0] for module in map(os.path.basename, iglob(os.path.join(path, pattern)))) + for module_name in modules: + module = import_module("sat_frontends.jp."+module_name) + try: + self.import_plugin_module(module, type_) + except ImportError: + continue - def import_command_module(self, module): - """ Add commands from a module to jp - @param module: module containing commands + def import_plugin_module(self, module, type_): + """add commands or outpus from a module to jp + @param module: module containing commands or outputs + @param type_(str): one of C_PLUGIN_* """ try: - for classname in module.__commands__: - cls = getattr(module, classname) + class_names = getattr(module, '__{}__'.format(type_)) except AttributeError: - log.warning(_("Invalid module %s") % module) + log.warning(_("Invalid plugin module [{type}] {module}").format(type=type_, module=module)) raise ImportError - cls(self) + else: + for class_name in class_names: + cls = getattr(module, class_name) + cls(self) def run(self, args=None): self.args = self.parser.parse_args(args) @@ -405,20 +435,23 @@ class Jp(object): class CommandBase(object): - def __init__(self, host, name, use_profile=True, use_progress=False, use_verbose=False, need_connect=None, help=None, **kwargs): + def __init__(self, host, name, use_profile=True, use_output=False, + need_connect=None, help=None, **kwargs): """ Initialise CommandBase @param host: Jp instance @param name(unicode): name of the new command @param use_profile(bool): if True, add profile selection/connection commands - @param use_progress(bool): if True, add progress bar activation commands - progress* signals will be handled - @param use_verbose(bool): if True, add verbosity command + @param use_output(bool, dict): if not False, add --output option @param need_connect(bool, None): True if profile connection is needed False else (profile session must still be started) None to set auto value (i.e. True if use_profile is set) Can't be set if use_profile is False @param help(unicode): help message to display @param **kwargs: args passed to ArgumentParser + use_* are handled directly, they can be: + - use_progress(bool): if True, add progress bar activation option + progress* signals will be handled + - use_verbose(bool): if True, add verbosity option @attribute need_loop(bool): to set by commands when loop is needed """ @@ -428,6 +461,7 @@ class CommandBase(object): except AttributeError: self.host = host + # --profile option parents = kwargs.setdefault('parents', set()) if use_profile: #self.host.parents['profile'] is an ArgumentParser with profile connection arguments @@ -440,11 +474,29 @@ class CommandBase(object): # from this point, self.need_connect is None if connection is not needed at all # False if session starting is needed, and True if full connection is needed - if use_progress: - parents.add(self.host.parents['progress']) + # --output option + if use_output: + if use_output == True: + use_output = C.OUTPUT_TEXT + assert use_output in C.OUTPUT_TYPES + self._output_type = use_output + output_parent = argparse.ArgumentParser(add_help=False) + choices = self.host.getOutputChoices(use_output) + if not choices: + raise exceptions.InternalError("No choice found for {} output type".format(use_output)) + default = 'default' if 'default' in choices else choices[0] + output_parent.add_argument('--output', '-O', choices=choices, default=default, help=_(u"Select output format")) + parents.add(output_parent) - if use_verbose: - parents.add(self.host.parents['verbose']) + # other common options + use_opts = {k:v for k,v in kwargs.iteritems() if k.startswith('use_')} + for param, do_use in use_opts.iteritems(): + opt=param[4:] # if param is use_verbose, opt is verbose + if opt not in self.host.parents: + raise exceptions.InternalError(u"Unknown parent option {}".format(opt)) + del kwargs[param] + if do_use: + parents.add(self.host.parents[opt]) self.parser = host.subparsers.add_parser(name, help=help, **kwargs) if hasattr(self, "subcommands"): @@ -572,6 +624,9 @@ class CommandBase(object): def disp(self, msg, verbosity=0, error=False): return self.host.disp(msg, verbosity, error) + def output(self, data): + return self.host.output(self._output_type, self.args.output, data) + def add_parser_options(self): try: subcommands = self.subcommands diff --git a/frontends/src/jp/cmd_profile.py b/frontends/src/jp/cmd_profile.py index 9f5461df..9ec10999 100644 --- a/frontends/src/jp/cmd_profile.py +++ b/frontends/src/jp/cmd_profile.py @@ -105,14 +105,13 @@ class ProfileInfo(base.CommandBase): class ProfileList(base.CommandBase): def __init__(self, host): - super(ProfileList, self).__init__(host, 'list', use_profile=False, help=_('list profiles')) + super(ProfileList, self).__init__(host, 'list', use_profile=False, use_output='list', help=_('list profiles')) def add_parser_options(self): pass def start(self): - for profile in self.host.bridge.getProfilesList(): - print profile + self.output(self.host.bridge.getProfilesList()) class ProfileCreate(base.CommandBase): diff --git a/frontends/src/jp/constants.py b/frontends/src/jp/constants.py index 76e95c87..6e285988 100644 --- a/frontends/src/jp/constants.py +++ b/frontends/src/jp/constants.py @@ -23,3 +23,9 @@ from sat_frontends.quick_frontend import constants class Const(constants.Const): APP_NAME = "jp" + PLUGIN_CMD = "commands" + PLUGIN_OUTPUT = "outputs" + OUTPUT_TEXT = 'text' # blob of unicode text + OUTPUT_DICT = 'dict' + OUTPUT_LIST = 'list' + OUTPUT_TYPES = (OUTPUT_TEXT, OUTPUT_DICT, OUTPUT_LIST) diff --git a/frontends/src/jp/jp b/frontends/src/jp/jp index 7e886c95..0d1d85f6 100755 --- a/frontends/src/jp/jp +++ b/frontends/src/jp/jp @@ -21,5 +21,5 @@ from sat_frontends.jp import base if __name__ == "__main__": jp = base.Jp() - jp.import_commands() + jp.import_plugins() jp.run() diff --git a/frontends/src/jp/output_std.py b/frontends/src/jp/output_std.py new file mode 100644 index 00000000..2dc1cd51 --- /dev/null +++ b/frontends/src/jp/output_std.py @@ -0,0 +1,58 @@ +#! /usr/bin/python +# -*- coding: utf-8 -*- + +# jp: a SàT command line tool +# Copyright (C) 2009-2016 Jérôme Poisson (goffi@goffi.org) + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# 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 Affero General Public License for more details. + +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +"""Standard outputs""" + + +from sat_frontends.jp.constants import Const as C +import json + +__outputs__ = ["Default", "Json"] +DEFAULT = u'default' +JSON = u'json' +JSON_RAW = u'json_raw' + + +class Default(object): + """Default outputs""" + + def __init__(self, jp): + jp.register_output(C.OUTPUT_TEXT, DEFAULT, self.text) + jp.register_output(C.OUTPUT_LIST, DEFAULT, self.list) + + def text(self, data): + print data + + def list(self, data): + print u'\n'.join(data) + + +class Json(object): + """outputs in json format""" + + def __init__(self, jp): + jp.register_output(C.OUTPUT_LIST, JSON, self.dump_pretty) + jp.register_output(C.OUTPUT_LIST, JSON_RAW, self.dump) + jp.register_output(C.OUTPUT_DICT, JSON, self.dump_pretty) + jp.register_output(C.OUTPUT_DICT, JSON_RAW, self.dump) + + def dump(self, data): + print json.dumps(data) + + def dump_pretty(self, data): + print json.dumps(data, indent=4) From 1fc8580831be3dbabd5b5916f605877b803607b2 Mon Sep 17 00:00:00 2001 From: Goffi Date: Sat, 23 Apr 2016 23:30:06 +0200 Subject: [PATCH 08/14] jp: added consts for exit codes, not used yet --- frontends/src/jp/constants.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/frontends/src/jp/constants.py b/frontends/src/jp/constants.py index 6e285988..673e70dc 100644 --- a/frontends/src/jp/constants.py +++ b/frontends/src/jp/constants.py @@ -29,3 +29,11 @@ class Const(constants.Const): OUTPUT_DICT = 'dict' OUTPUT_LIST = 'list' OUTPUT_TYPES = (OUTPUT_TEXT, OUTPUT_DICT, OUTPUT_LIST) + + # exit codes + EXIT_OK = 0 + EXIT_ERROR = 1 # generic error, when nothing else match + EXIT_BAD_ARG = 2 # arguments given by user are bad + EXIT_FILE_NOT_EXE = 126 # a file to be executed was found, but it was not an executable utility (cf. man 1 exit) + EXIT_CMD_NOT_FOUND = 127 # a utility to be executed was not found (cf. man 1 exit) + EXIT_SIGNAL_INT = 128 # a command was interrupted by a signal (cf. man 1 exit) From 645ade7e73756644a9b2ec97b66bd0cba7276604 Mon Sep 17 00:00:00 2001 From: Goffi Date: Sat, 23 Apr 2016 23:46:35 +0200 Subject: [PATCH 09/14] primitivus: fixed window resize (was blocked by paste detection) --- frontends/src/primitivus/primitivus | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/src/primitivus/primitivus b/frontends/src/primitivus/primitivus index d9043c88..ca65a227 100755 --- a/frontends/src/primitivus/primitivus +++ b/frontends/src/primitivus/primitivus @@ -384,7 +384,7 @@ class PrimitivusApp(QuickApp, InputHistory): ## paste detection/handling if (len(input_) > 1 and # XXX: it may be needed to increase this value if buffer not isinstance(input_[0], tuple) and # or other things result in several chars at once - not 'window' in input_[0]): # (e.g. using Primitivus through ssh). Need some testing + not 'window resize' in input_): # (e.g. using Primitivus through ssh). Need some testing # and experience to adjust value. if input_[0] == 'begin paste' and not self._bracketed_paste: log.info(u"Bracketed paste mode detected") From faef20576182dd5dcb086f9dcb567ae0f6effe57 Mon Sep 17 00:00:00 2001 From: Goffi Date: Tue, 26 Apr 2016 19:04:59 +0200 Subject: [PATCH 10/14] plugin misc ip: fixed exception when a web error happen while retrieving IP from external website --- src/plugins/plugin_misc_ip.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/plugins/plugin_misc_ip.py b/src/plugins/plugin_misc_ip.py index a5fa712b..dbf7d518 100644 --- a/src/plugins/plugin_misc_ip.py +++ b/src/plugins/plugin_misc_ip.py @@ -23,6 +23,7 @@ from sat.core.log import getLogger log = getLogger(__name__) from sat.tools import xml_tools from twisted.web import client as webclient +from twisted.web import error as web_error from twisted.internet import defer from twisted.internet import reactor from twisted.internet import protocol @@ -51,6 +52,7 @@ PLUGIN_INFO = { "description": _("""This plugin help to discover our external IP address.""") } +# TODO: GET_IP_PAGE should be configurable in sat.conf GET_IP_PAGE = "http://www.goffi.org/sat_tools/get_ip.php" # This page must only return external IP of the requester GET_IP_LABEL = D_(u"Allow external get IP") GET_IP_CATEGORY = "General" @@ -289,6 +291,9 @@ class IPPlugin(object): except (internet_error.DNSLookupError, internet_error.TimeoutError): log.warning(u"Can't access Domain Name System") ip = None + except web_error.Error as e: + log.warning(u"Error while retrieving IP on {url}: {message}".format(url=GET_IP_PAGE, message=e)) + ip = None else: self._external_ip_cache = ip defer.returnValue(ip) From 5857a69546f745c8091fec5a60538ce9f34e5ca7 Mon Sep 17 00:00:00 2001 From: Goffi Date: Tue, 26 Apr 2016 19:59:28 +0200 Subject: [PATCH 11/14] plugin misc ip: changed URL of GET_IP_PAGE for the new one on salut-a-toi.org --- src/plugins/plugin_misc_ip.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/plugin_misc_ip.py b/src/plugins/plugin_misc_ip.py index dbf7d518..a9d7bdcd 100644 --- a/src/plugins/plugin_misc_ip.py +++ b/src/plugins/plugin_misc_ip.py @@ -53,7 +53,7 @@ PLUGIN_INFO = { } # TODO: GET_IP_PAGE should be configurable in sat.conf -GET_IP_PAGE = "http://www.goffi.org/sat_tools/get_ip.php" # This page must only return external IP of the requester +GET_IP_PAGE = "http://salut-a-toi.org/whereami/" # This page must only return external IP of the requester GET_IP_LABEL = D_(u"Allow external get IP") GET_IP_CATEGORY = "General" GET_IP_NAME = "allow_get_ip" From 408b80a966ca9ece66b72ccada90d423d018b085 Mon Sep 17 00:00:00 2001 From: souliane Date: Thu, 10 Mar 2016 12:01:29 +0100 Subject: [PATCH 12/14] updated CHANGELOG for version 0.6.1 --- CHANGELOG | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 603a67f9..cf542f60 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,87 @@ All theses changelogs are not exhaustive, please check the mercurial repository for more details. +v 0.6.1 (14/03/2016): + - minimum Twisted version is now 15.2.0 + - removed pyfeed and xe dependencies + - added mutagen to recommended in README4PACKAGERS + - use of /usr/bin/env instead of /usr/bin/python in shebang + - core: + - connection and initialisation improvements + - leave the handling of delay elements to XEP-0203 + - memory: + - fixes handling of jids_list parameter type + - fixed exception when setting an empty password + - disco: better handling of response failures + - tools: + - improved repository version detection + - moved data methods from common to common.data_format + - added common.regex module + - new plugins: + - blog_import: generic plugin to import blogs to SàT + - blog_import_dotclear: import dotclear blog + - blog_import_dokuwiki: import dokuwiki blog + - extra_pep: display messages from extra PEP services + - syntax_wiki_dotclear: convert dotclear wiki syntax from and to XHTML + - directory_subscription: temporary plugin moved from XEP-0055 implementation + - already existing plugins: + - account: + - auto add some roster contacts at profile creation + - parameter "admin_email" is now "email_admin_lists" + - email sending improvements (new authentication options) + - email the admins when a profile is created from an existing XMPP account + - ip: changed URL of GET_IP_PAGE for the new one on salut-a-toi.org + - XEP-0045: fixes commands feedback + - XEP-0060: MAM (XEP-0313) integration + - XEP-0166, XEP-0260: better handling of proxy error + - XEP-0277: + - improve comments handling + - uses new "extra pep" plugin + - Atom feed retrieval is left to Libervia + - fixes XHTML content encapsulation and handling of new lines + - XEP-0313: cleaning and improvements + - text_syntaxes: various improvements + - tmp/wokkel: + - updated behaviour and namespace to new urn:xmpp:mam:1 + - several MAM and RSM improvements + - frontends: + - printing the history and notifications are left to quick_frontend + - restore printing the day change while displaying history + - fixes main item update and auto addition of a scheme to HTML links + - added ui_show_cb in actionManager (frontend can handle the XMLUI display) + - jp: + - new start method used by all commands + - new --output option to change the format of command output: + - possible outputs for now are "default", "json" and "json_raw" + - new commands: + - blog: import, edit, preview + - roster: get, stats, purge + - command "message" moved to "message send" + - command "profile list" uses the new --output option + - added constants for exit codes + - fixed traceback shown on a normal quit when a progression is finished + - primitivus: + - detect direct pasting in the message bar + - add bracketed paste mode + - libervia: + - browser and server sides: + - replaced isRegistered call by a more generic getSessionMetadata + - new option "allow_registration" + - browser side: + - improve the popup message banner + - replace old favicon and display favicon counter + - better handling of connection with external JID + - improve some regexps after Link Mauve's comments + - replace "re" module usage with pure javascript + - server: + - added mechanism for URL redirections + - renamed "ssl_certificate" to "tls_certificate" + - new options "tls_private_key", "tls_chain options", "base_url_ext" + - blog: + - several improvements + - implement tags/categories + - removed max_items as we use RSM + - fixed atom feed, add link and categories (tags) elements + v 0.6.0 (02/12/2015): - modification of the social contract according to the General Assembly of August, 19th 2014 - improved launching/stopping scripts: From 091f7b371720831ab53c32277fbc59a30623e956 Mon Sep 17 00:00:00 2001 From: Goffi Date: Sat, 28 May 2016 20:12:54 +0200 Subject: [PATCH 13/14] changelog: minor fixes in previous commit --- CHANGELOG | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index cf542f60..dafccc07 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,6 @@ All theses changelogs are not exhaustive, please check the mercurial repository for more details. -v 0.6.1 (14/03/2016): +v 0.6.1 (xx/xx/2016): - minimum Twisted version is now 15.2.0 - removed pyfeed and xe dependencies - added mutagen to recommended in README4PACKAGERS @@ -58,19 +58,18 @@ v 0.6.1 (14/03/2016): - command "message" moved to "message send" - command "profile list" uses the new --output option - added constants for exit codes - - fixed traceback shown on a normal quit when a progression is finished - primitivus: - detect direct pasting in the message bar - add bracketed paste mode - libervia: - browser and server sides: - replaced isRegistered call by a more generic getSessionMetadata - - new option "allow_registration" + - new option "allow_registration" to enable/disable new accounts registration - browser side: - - improve the popup message banner - - replace old favicon and display favicon counter - - better handling of connection with external JID - - improve some regexps after Link Mauve's comments + - improvee the popup message banner + - replaced old favicon and display favicon counter + - fixed handling of connection with external JID + - improved some regexps - replace "re" module usage with pure javascript - server: - added mechanism for URL redirections From fe8187a413a331e566d91bdd39d3d67c7e43afde Mon Sep 17 00:00:00 2001 From: Goffi Date: Fri, 24 Jun 2016 22:32:58 +0200 Subject: [PATCH 14/14] jp (blog): fixed syntax detection when extension is .txt --- frontends/src/jp/cmd_blog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontends/src/jp/cmd_blog.py b/frontends/src/jp/cmd_blog.py index 0fedf5c5..29fb7cfc 100644 --- a/frontends/src/jp/cmd_blog.py +++ b/frontends/src/jp/cmd_blog.py @@ -147,7 +147,7 @@ class BlogCommon(object): ext = os.path.splitext(path)[1][1:] # we get extension without the '.' if ext: for k,v in SYNTAX_EXT.iteritems(): - if ext == v: + if k and ext == v: return k # if not found, we use current syntax