Philipp Hörist pushed to branch master at gajim / python-nbxmpp
Commits:
f9532825 by Philipp Hörist at 2019-06-28T21:36:55Z
DataForms: Detect <reported> element
- - - - -
1 changed file:
- nbxmpp/modules/dataforms.py
Changes:
=====================================
nbxmpp/modules/dataforms.py
=====================================
@@ -667,6 +667,10 @@ class DataForm(ExtendedNode):
for value in self.getTags('instructions'):
self.delChild(value)
+ @property
+ def is_reported(self):
+ return self.getTag('reported') is not None
+
class SimpleDataForm(DataForm, DataRecord):
def __init__(self, type_=None, title=None, instructions=None, fields=None,
View it on GitLab: https://dev.gajim.org/gajim/python-nbxmpp/commit/f9532825b89abf55d6d41a0b7a…
--
View it on GitLab: https://dev.gajim.org/gajim/python-nbxmpp/commit/f9532825b89abf55d6d41a0b7a…
You're receiving this email because of your account on dev.gajim.org.
Philipp Hörist pushed to branch master at gajim / gajim
Commits:
c5a8cbc3 by Daniel Brötzmann at 2019-06-25T22:13:26Z
Fix iPython View
- - - - -
d5276eae by Daniel Brötzmann at 2019-06-25T22:13:26Z
IPython: Abort if not installed
- - - - -
d0a7bc3d by Daniel Brötzmann at 2019-06-25T22:13:26Z
IPython: Fix some linting errors
- - - - -
5d812cbe by Daniel Brötzmann at 2019-06-25T22:13:26Z
IPython: Add window title
- - - - -
181027dd by Philipp Hörist at 2019-06-25T22:13:26Z
IPython: Simplify stream code
- - - - -
4757fd95 by Philipp Hörist at 2019-06-25T22:13:26Z
IPython: Support only IPython 5.0.0+
- - - - -
2 changed files:
- gajim/dev/ipython_view.py
- gajim/gui_interface.py
Changes:
=====================================
gajim/dev/ipython_view.py
=====================================
@@ -19,13 +19,29 @@
# Copyright (c) 2007, IBM Corporation
# All rights reserved.
-## Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
-
-## * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
-## * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
-## * Neither the name of the IBM Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
-
-## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+
+# * Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# * Neither the name of the IBM Corporation nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
"""
Provides IPython console widget
@@ -45,6 +61,7 @@ import sys
import os
from io import StringIO
from functools import reduce
+from pkg_resources import parse_version
from gi.repository import Gtk
from gi.repository import Gdk
@@ -52,30 +69,25 @@ from gi.repository import GObject
from gi.repository import GLib
from gi.repository import Pango
-try:
- import IPython
-except ImportError:
- IPython = None
-
-HAS_IPYTHON5 = True
-try:
- from pygments.token import Token
- # pylint: disable=ungrouped-imports
- from IPython.core.displayhook import DisplayHook
- from IPython.core.display_trap import DisplayTrap
- # pylint: enable=ungrouped-imports
-
- class MyPromptDisplayHook(DisplayHook):
- def __init__(self, shell, view):
- DisplayHook.__init__(self, shell=shell)
- self.view = view
-
- def write_output_prompt(self):
- tokens = self.shell.prompts.out_prompt_tokens()
- self.view.write('\n')
- self.view.write(tokens)
-except Exception:
- HAS_IPYTHON5 = False
+import IPython
+
+from pygments.token import Token
+# pylint: disable=ungrouped-imports
+from IPython.core.displayhook import DisplayHook
+from IPython.core.display_trap import DisplayTrap
+# pylint: enable=ungrouped-imports
+
+
+class MyPromptDisplayHook(DisplayHook):
+ def __init__(self, shell, view):
+ DisplayHook.__init__(self, shell=shell)
+ self.view = view
+
+ def write_output_prompt(self):
+ tokens = self.shell.prompts.out_prompt_tokens()
+ self.view.write('\n')
+ self.view.write(tokens)
+
class IterableIPShell:
"""
@@ -117,16 +129,8 @@ class IterableIPShell:
io = IPython.utils.io
if input_func:
- if IPython.version_info[0] >= 1:
- IPython.terminal.interactiveshell.raw_input_original = input_func
- else:
- IPython.frontend.terminal.interactiveshell.raw_input_original = input_func
- if cin:
- io.stdin = io.IOStream(cin)
- if cout:
- io.stdout = io.IOStream(cout)
- if cerr:
- io.stderr = io.IOStream(cerr)
+ IPython.terminal.interactiveshell.raw_input_original = input_func
+
# This is to get rid of the blockage that accurs during
# IPython.Shell.InteractiveShell.user_setup()
@@ -135,52 +139,53 @@ class IterableIPShell:
os.environ['TERM'] = 'dumb'
excepthook = sys.excepthook
- if IPython.version_info[0] >= 5:
- from traitlets.config.loader import Config
- else:
- from IPython.config.loader import Config
+ from traitlets.config.loader import Config
cfg = Config()
cfg.InteractiveShell.colors = "Linux"
- # InteractiveShell's __init__ overwrites io.stdout,io.stderr with
- # sys.stdout, sys.stderr, this makes sure they are right
+ # InteractiveShell's __init__ gets a reference of stdout and stderr
+ # so we save the standard here to revert it after init
old_stdout, old_stderr = sys.stdout, sys.stderr
- sys.stdout, sys.stderr = io.stdout.stream, io.stderr.stream
+ sys.stdout, sys.stderr = cout, cerr
# InteractiveShell inherits from SingletonConfigurable so use instance()
- if IPython.version_info[0] >= 1:
- self.IP = IPython.terminal.embed.InteractiveShellEmbed.instance(config=cfg, user_ns=user_ns, user_module=user_global_ns)
- else:
- self.IP = IPython.frontend.terminal.embed.InteractiveShellEmbed.instance(config=cfg, user_ns=user_ns)
+ self.IP = IPython.terminal.embed.InteractiveShellEmbed.instance(
+ config=cfg, user_ns=user_ns, user_module=user_global_ns)
+ # Set back stdout and stderr to what it was before
sys.stdout, sys.stderr = old_stdout, old_stderr
self.IP.system = lambda cmd: self.shell(self.IP.var_expand(cmd),
header='IPython system call: ',
local_ns=user_ns)
- #global_ns=user_global_ns)
- #verbose=self.IP.rc.system_verbose)
self.IP.raw_input = input_func
sys.excepthook = excepthook
self.iter_more = 0
self.history_level = 0
self.complete_sep = re.compile(r'[\s\{\}\[\]\(\)]')
- self.updateNamespace({'exit':lambda: None})
- self.updateNamespace({'quit':lambda: None})
- #self.IP.readline_startup_hook(self.IP.pre_readline)
+ self.updateNamespace({'exit': lambda: None})
+ self.updateNamespace({'quit': lambda: None})
+
# Workaround for updating namespace with sys.modules
#
self.__update_namespace()
+ # Avoid using input splitter when not really needed.
+ # Perhaps it could work even before 5.8.0
+ # But it definitely does not work any more with >= 7.0.0
+ self.no_input_splitter = parse_version(IPython.release.version) >= \
+ parse_version('5.8.0')
+ self.lines = []
+
def __update_namespace(self):
'''
Update self.IP namespace for autocompletion with sys.modules
'''
for k, v in sys.modules.items():
- if not '.' in k:
- self.IP.user_ns.update({k:v})
+ if '.' not in k:
+ self.IP.user_ns.update({k: v})
def execute(self):
"""
@@ -211,14 +216,22 @@ class IterableIPShell:
except Exception:
self.IP.showtraceback()
else:
- self.IP.input_splitter.push(line)
- self.iter_more = self.IP.input_splitter.push_accepts_more()
+ if self.no_input_splitter:
+ self.lines.append(self.IP.raw_input(self.prompt))
+ self.iter_more = self.IP.check_complete(
+ '\n'.join(self.lines))[0] == 'incomplete'
+ else:
+ self.IP.input_splitter.push(line)
+ self.iter_more = self.IP.input_splitter.push_accepts_more()
+
self.prompt = self.generatePrompt(self.iter_more)
if not self.iter_more:
- if IPython.version_info[0] >= 2:
- source_raw = self.IP.input_splitter.raw_reset()
+ if self.no_input_splitter:
+ source_raw = '\n'.join(self.lines)
+ self.lines = []
else:
- source_raw = self.IP.input_splitter.source_raw_reset()[1]
+ source_raw = self.IP.input_splitter.raw_reset()
+
self.IP.run_cell(source_raw, store_history=True)
self.IP.rl_do_indent = False
else:
@@ -240,24 +253,8 @@ class IterableIPShell:
@rtype: string
'''
- # Backwards compatibility with ipyton-0.11
- #
- ver = IPython.__version__
- if '0.11' in ver:
- prompt = self.IP.hooks.generate_prompt(is_continuation)
- else:
- # Prompt for IPython >=5.0:
- if hasattr(self.IP, 'prompts'):
- if is_continuation:
- prompt = self.IP.prompts.continuation_prompt_tokens(self.IP.prompts)
- else:
- prompt = self.IP.prompts.in_prompt_tokens(self.IP.prompts)
- # Prompt for IPython < 5.0
- elif hasattr(self.IP, 'prompt_manager'):
- if is_continuation:
- prompt = self.IP.prompt_manager.render('in2')
- else:
- prompt = self.IP.prompt_manager.render('in')
+ # TODO: Update to IPython 5.x and later
+ prompt = "In [%d]: " % self.IP.execution_count
return prompt
@@ -335,13 +332,14 @@ class IterableIPShell:
@rtype: string
'''
for i in range(len(str1)):
- if not str2.startswith(str1[:i+1]):
+ if not str2.startswith(str1[:i + 1]):
return str1[:i]
return str1
if possibilities[1]:
- common_prefix = reduce(_commonPrefix, possibilities[1]) or line[-1]
- completed = line[:-len(split_line[-1])]+common_prefix
+ common_prefix = \
+ reduce(_commonPrefix, possibilities[1]) or line[-1]
+ completed = line[:-len(split_line[-1])] + common_prefix
else:
completed = line
else:
@@ -383,9 +381,10 @@ class ConsoleView(Gtk.TextView):
self.override_font(Pango.FontDescription('Mono'))
self.set_cursor_visible(True)
self.text_buffer = self.get_buffer()
- self.mark = self.text_buffer.create_mark('scroll_mark',
- self.text_buffer.get_end_iter(),
- False)
+ self.mark = self.text_buffer.create_mark(
+ 'scroll_mark',
+ self.text_buffer.get_end_iter(),
+ False)
for code in self.ANSI_COLORS:
self.text_buffer.create_tag(code,
foreground=self.ANSI_COLORS[code],
@@ -393,22 +392,24 @@ class ConsoleView(Gtk.TextView):
self.text_buffer.create_tag('0')
self.text_buffer.create_tag('notouch', editable=False)
self.color_pat = re.compile(r'\x01?\x1b\[(.*?)m\x02?')
- if HAS_IPYTHON5:
- self.style_dict = {
- Token.Prompt: '0;32',
- Token.PromptNum: '1;32',
- Token.OutPrompt: '0;31',
- Token.OutPromptNum: '1;31',
- }
+
+ self.style_dict = {
+ Token.Prompt: '0;32',
+ Token.PromptNum: '1;32',
+ Token.OutPrompt: '0;31',
+ Token.OutPromptNum: '1;31',
+ }
+
self.line_start = \
self.text_buffer.create_mark('line_start',
- self.text_buffer.get_end_iter(), True)
+ self.text_buffer.get_end_iter(),
+ True)
self.connect('key-press-event', self.onKeyPress)
def write(self, text, editable=False):
if isinstance(text, str):
GLib.idle_add(self._write, text, editable)
- elif IPython.version_info[0] >= 5:
+ else:
GLib.idle_add(self._write5, text, editable)
def _write5(self, text, editable=False):
@@ -420,18 +421,18 @@ class ConsoleView(Gtk.TextView):
@param editable: If true, added text is editable.
@type editable: boolean
"""
- start_mark = self.text_buffer.create_mark(None,
- self.text_buffer.get_end_iter(),
- True)
+ start_mark = self.text_buffer.create_mark(
+ None, self.text_buffer.get_end_iter(), True)
for token, segment in text:
tag = self.style_dict[token]
- self.text_buffer.insert_with_tags_by_name(self.text_buffer.get_end_iter(),
- segment, tag)
+ self.text_buffer.insert_with_tags_by_name(
+ self.text_buffer.get_end_iter(), segment, tag)
if not editable:
- self.text_buffer.apply_tag_by_name('notouch',
- self.text_buffer.get_iter_at_mark(start_mark),
- self.text_buffer.get_end_iter())
+ self.text_buffer.apply_tag_by_name(
+ 'notouch',
+ self.text_buffer.get_iter_at_mark(start_mark),
+ self.text_buffer.get_end_iter())
self.text_buffer.delete_mark(start_mark)
self.scroll_mark_onscreen(self.mark)
@@ -444,31 +445,31 @@ class ConsoleView(Gtk.TextView):
@param editable: If true, added text is editable.
@type editable: boolean
"""
- if isinstance(text, list) and IPython.version_info[0] >= 5:
+ if isinstance(text, list):
self._write5(text, editable)
return
segments = self.color_pat.split(text)
segment = segments.pop(0)
- start_mark = self.text_buffer.create_mark(None,
- self.text_buffer.get_end_iter(),
- True)
+ start_mark = self.text_buffer.create_mark(
+ None, self.text_buffer.get_end_iter(), True)
self.text_buffer.insert(self.text_buffer.get_end_iter(), segment)
if segments:
ansi_tags = self.color_pat.findall(text)
for tag in ansi_tags:
i = segments.index(tag)
- self.text_buffer.insert_with_tags_by_name(self.text_buffer.get_end_iter(),
- segments[i+1], str(tag))
+ self.text_buffer.insert_with_tags_by_name(
+ self.text_buffer.get_end_iter(), segments[i + 1], str(tag))
segments.pop(i)
if not editable:
- self.text_buffer.apply_tag_by_name('notouch',
- self.text_buffer.get_iter_at_mark(start_mark),
- self.text_buffer.get_end_iter())
+ self.text_buffer.apply_tag_by_name(
+ 'notouch',
+ self.text_buffer.get_iter_at_mark(start_mark),
+ self.text_buffer.get_end_iter())
+
self.text_buffer.delete_mark(start_mark)
self.scroll_mark_onscreen(self.mark)
-
def showPrompt(self, prompt):
GLib.idle_add(self._showPrompt, prompt)
@@ -495,7 +496,8 @@ class ConsoleView(Gtk.TextView):
"""
iter_ = self.text_buffer.get_iter_at_mark(self.line_start)
iter_.forward_to_line_end()
- self.text_buffer.delete(self.text_buffer.get_iter_at_mark(self.line_start), iter_)
+ self.text_buffer.delete(
+ self.text_buffer.get_iter_at_mark(self.line_start), iter_)
self._write(text, True)
def getCurrentLine(self):
@@ -526,11 +528,12 @@ class ConsoleView(Gtk.TextView):
'notouch',
self.text_buffer.get_iter_at_mark(self.line_start),
iter_)
- self._write('\n'+text)
+ self._write('\n' + text)
if text:
self._write('\n')
self._showPrompt(self.prompt)
- self.text_buffer.move_mark(self.line_start, self.text_buffer.get_end_iter())
+ self.text_buffer.move_mark(
+ self.line_start, self.text_buffer.get_end_iter())
self.text_buffer.place_cursor(self.text_buffer.get_end_iter())
if self.IP.rl_do_indent:
@@ -570,11 +573,11 @@ class ConsoleView(Gtk.TextView):
return True
elif not event.string:
pass
- elif start_iter.compare(insert_iter) <= 0 and \
- start_iter.compare(selection_iter) <= 0:
+ elif (start_iter.compare(insert_iter) <= 0 and
+ start_iter.compare(selection_iter) <= 0):
pass
- elif start_iter.compare(insert_iter) > 0 and \
- start_iter.compare(selection_iter) > 0:
+ elif (start_iter.compare(insert_iter) > 0 and
+ start_iter.compare(selection_iter) > 0):
self.text_buffer.place_cursor(start_iter)
elif insert_iter.compare(selection_iter) < 0:
self.text_buffer.move_mark(insert_mark, start_iter)
@@ -588,6 +591,7 @@ class ConsoleView(Gtk.TextView):
For some reason we can't extend onKeyPress directly (bug #500900)
"""
+
class IPythonView(ConsoleView, IterableIPShell):
'''
Sub-class of both modified IPython shell and L{ConsoleView} this makes
@@ -601,11 +605,11 @@ class IPythonView(ConsoleView, IterableIPShell):
self.cout = StringIO()
IterableIPShell.__init__(self, cout=self.cout, cerr=self.cout,
input_func=self.raw_input)
- if HAS_IPYTHON5:
- displayhook = MyPromptDisplayHook(shell=self.IP, view=self)
- self.IP.displayhook = displayhook
- self.IP.display_trap = DisplayTrap(hook=displayhook)
-# self.connect('key_press_event', self.keyPress)
+
+ displayhook = MyPromptDisplayHook(shell=self.IP, view=self)
+ self.IP.displayhook = displayhook
+ self.IP.display_trap = DisplayTrap(hook=displayhook)
+
self.interrupt = False
self.execute()
self.prompt = self.generatePrompt(False)
@@ -644,7 +648,8 @@ class IPythonView(ConsoleView, IterableIPShell):
@return: True if event should not trickle.
@rtype: boolean
"""
- if event.get_state() & Gdk.ModifierType.CONTROL_MASK and event.keyval == 99:
+ if (event.get_state() & Gdk.ModifierType.CONTROL_MASK and
+ event.keyval == 99):
self.interrupt = True
self._processLine()
return True
@@ -665,7 +670,7 @@ class IPythonView(ConsoleView, IterableIPShell):
slice_ = self.getCurrentLine()
self.write('\n')
for symbol in possibilities:
- self.write(symbol+'\n')
+ self.write(symbol + '\n')
self.showPrompt(self.prompt)
self.changeLine(completed or slice_)
return True
=====================================
gajim/gui_interface.py
=====================================
@@ -38,6 +38,7 @@ import time
import logging
from functools import partial
from threading import Thread
+from importlib.util import find_spec
from gi.repository import Gtk
from gi.repository import GLib
@@ -2074,6 +2075,13 @@ class Interface:
@staticmethod
def create_ipython_window():
+ # Check if IPython is installed
+ ipython = find_spec('IPython')
+ is_installed = ipython is not None
+ if not is_installed:
+ # Abort early to avoid tracebacks
+ print('IPython is not installed')
+ return
try:
from gajim.dev.ipython_view import IPythonView
except ImportError:
@@ -2087,6 +2095,7 @@ class Interface:
font = 'Luxi Mono 10'
window = Gtk.Window()
+ window.set_title(_('Gajim: IPython Console'))
window.set_size_request(750, 550)
window.set_resizable(True)
sw = Gtk.ScrolledWindow()
View it on GitLab: https://dev.gajim.org/gajim/gajim/compare/3ded70a5fdf6a816df47e087fccf49ce5…
--
View it on GitLab: https://dev.gajim.org/gajim/gajim/compare/3ded70a5fdf6a816df47e087fccf49ce5…
You're receiving this email because of your account on dev.gajim.org.
Philipp Hörist pushed to branch master at gajim / gajim
Commits:
a3754216 by Daniel Brötzmann at 2019-06-24T20:12:08Z
GroupchatControl: Remove correcting state when minimizing
Minimizing a GroupChatControl should remove the self.correcting state to
avoid being in this state when restoring. Fixes #9580
- - - - -
1 changed file:
- gajim/groupchat_control.py
Changes:
=====================================
gajim/groupchat_control.py
=====================================
@@ -2197,6 +2197,14 @@ class GroupchatControl(ChatControlBase):
win.notebook.remove_page(ctrl_page)
control.unparent()
ctrl.parent_win = None
+
+ # Stop correcting message when we minimize
+ if self.correcting:
+ self.correcting = False
+ gtkgui_helpers.remove_css_class(
+ self.msg_textview, 'gajim-msg-correcting')
+ self.msg_textview.get_buffer().set_text('')
+
con = app.connections[self.account]
con.get_module('Chatstate').set_chatstate(self.contact, Chatstate.INACTIVE)
View it on GitLab: https://dev.gajim.org/gajim/gajim/commit/a3754216528c7e68217d4f58aeacbb85f1…
--
View it on GitLab: https://dev.gajim.org/gajim/gajim/commit/a3754216528c7e68217d4f58aeacbb85f1…
You're receiving this email because of your account on dev.gajim.org.