merged main branch
This commit is contained in:
commit
a28bb7be8f
11 changed files with 323 additions and 35 deletions
81
CHANGELOG
81
CHANGELOG
|
|
@ -1,5 +1,86 @@
|
|||
All theses changelogs are not exhaustive, please check the mercurial repository for more details.
|
||||
|
||||
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
|
||||
- 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
|
||||
- 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" to enable/disable new accounts registration
|
||||
- browser side:
|
||||
- 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
|
||||
- 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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -23,3 +23,17 @@ 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)
|
||||
|
||||
# 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)
|
||||
|
|
|
|||
|
|
@ -21,5 +21,5 @@ from sat_frontends.jp import base
|
|||
|
||||
if __name__ == "__main__":
|
||||
jp = base.Jp()
|
||||
jp.import_commands()
|
||||
jp.import_plugins()
|
||||
jp.run()
|
||||
|
|
|
|||
58
frontends/src/jp/output_std.py
Normal file
58
frontends/src/jp/output_std.py
Normal file
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
"""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)
|
||||
|
|
@ -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'),
|
||||
|
|
|
|||
|
|
@ -24,7 +24,9 @@ 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
|
||||
from urwid_satext.files_management import FileDialog
|
||||
from sat_frontends.bridge.DBus import DBusBridgeFrontend
|
||||
|
|
@ -43,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):
|
||||
|
|
@ -304,6 +307,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)
|
||||
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):
|
||||
|
|
@ -362,9 +371,69 @@ 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
|
||||
|
||||
## 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 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")
|
||||
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
|
||||
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(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)
|
||||
if not extra:
|
||||
return
|
||||
input_ = extra
|
||||
## end of paste detection/handling
|
||||
|
||||
for i in input_:
|
||||
if isinstance(i,tuple):
|
||||
if i[0] == 'mouse press':
|
||||
|
|
@ -776,6 +845,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):
|
||||
|
|
|
|||
|
|
@ -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,7 +52,8 @@ PLUGIN_INFO = {
|
|||
"description": _("""This plugin help to discover our external IP address.""")
|
||||
}
|
||||
|
||||
GET_IP_PAGE = "http://www.goffi.org/sat_tools/get_ip.php" # This page must only return external IP of the requester
|
||||
# TODO: GET_IP_PAGE should be configurable in sat.conf
|
||||
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"
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in a new issue