Add typing information and reformat stuff
This commit is contained in:
parent
6ccf7ea71d
commit
b4d3b93da2
11 changed files with 109 additions and 104 deletions
|
@ -30,7 +30,7 @@ Adding a remote bookmark:
|
||||||
|
|
||||||
import functools
|
import functools
|
||||||
import logging
|
import logging
|
||||||
from typing import Optional, List
|
from typing import Optional, List, Union
|
||||||
|
|
||||||
from slixmpp import JID
|
from slixmpp import JID
|
||||||
from slixmpp.plugins.xep_0048 import Bookmarks, Conference, URL
|
from slixmpp.plugins.xep_0048 import Bookmarks, Conference, URL
|
||||||
|
@ -130,7 +130,7 @@ class Bookmark:
|
||||||
|
|
||||||
class BookmarkList:
|
class BookmarkList:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.bookmarks = []
|
self.bookmarks = [] # type: List[Bookmark]
|
||||||
preferred = config.get('use_bookmarks_method').lower()
|
preferred = config.get('use_bookmarks_method').lower()
|
||||||
if preferred not in ('pep', 'privatexml'):
|
if preferred not in ('pep', 'privatexml'):
|
||||||
preferred = 'privatexml'
|
preferred = 'privatexml'
|
||||||
|
@ -140,15 +140,16 @@ class BookmarkList:
|
||||||
'pep': False,
|
'pep': False,
|
||||||
}
|
}
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key: Union[str, JID, int]) -> Optional[Bookmark]:
|
||||||
if isinstance(key, (str, JID)):
|
if isinstance(key, (str, JID)):
|
||||||
for i in self.bookmarks:
|
for i in self.bookmarks:
|
||||||
if key == i.jid:
|
if key == i.jid:
|
||||||
return i
|
return i
|
||||||
else:
|
elif isinstance(key, int):
|
||||||
return self.bookmarks[key]
|
return self.bookmarks[key]
|
||||||
|
return None
|
||||||
|
|
||||||
def __in__(self, key):
|
def __in__(self, key) -> bool:
|
||||||
if isinstance(key, (str, JID)):
|
if isinstance(key, (str, JID)):
|
||||||
for bookmark in self.bookmarks:
|
for bookmark in self.bookmarks:
|
||||||
if bookmark.jid == key:
|
if bookmark.jid == key:
|
||||||
|
@ -168,16 +169,16 @@ class BookmarkList:
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
return iter(self.bookmarks)
|
return iter(self.bookmarks)
|
||||||
|
|
||||||
def local(self):
|
def local(self) -> List[Bookmark]:
|
||||||
return [bm for bm in self.bookmarks if bm.method == 'local']
|
return [bm for bm in self.bookmarks if bm.method == 'local']
|
||||||
|
|
||||||
def remote(self):
|
def remote(self) -> List[Bookmark]:
|
||||||
return [bm for bm in self.bookmarks if bm.method == 'remote']
|
return [bm for bm in self.bookmarks if bm.method == 'remote']
|
||||||
|
|
||||||
def set(self, new):
|
def set(self, new: List[Bookmark]):
|
||||||
self.bookmarks = new
|
self.bookmarks = new
|
||||||
|
|
||||||
def append(self, bookmark):
|
def append(self, bookmark: Bookmark):
|
||||||
bookmark_exists = self[bookmark.jid]
|
bookmark_exists = self[bookmark.jid]
|
||||||
if not bookmark_exists:
|
if not bookmark_exists:
|
||||||
self.bookmarks.append(bookmark)
|
self.bookmarks.append(bookmark)
|
||||||
|
@ -185,7 +186,7 @@ class BookmarkList:
|
||||||
self.bookmarks.remove(bookmark_exists)
|
self.bookmarks.remove(bookmark_exists)
|
||||||
self.bookmarks.append(bookmark)
|
self.bookmarks.append(bookmark)
|
||||||
|
|
||||||
def set_bookmarks_method(self, value):
|
def set_bookmarks_method(self, value: str):
|
||||||
if self.available_storage.get(value):
|
if self.available_storage.get(value):
|
||||||
self.preferred = value
|
self.preferred = value
|
||||||
config.set_and_save('use_bookmarks_method', value)
|
config.set_and_save('use_bookmarks_method', value)
|
||||||
|
@ -306,7 +307,7 @@ class BookmarkList:
|
||||||
self.append(b)
|
self.append(b)
|
||||||
|
|
||||||
|
|
||||||
def stanza_storage(bookmarks):
|
def stanza_storage(bookmarks: BookmarkList) -> Bookmarks:
|
||||||
"""Generate a <storage/> stanza with the conference elements."""
|
"""Generate a <storage/> stanza with the conference elements."""
|
||||||
storage = Bookmarks()
|
storage = Bookmarks()
|
||||||
for b in (b for b in bookmarks if b.method == 'remote'):
|
for b in (b for b in bookmarks if b.method == 'remote'):
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
|
from typing import Tuple, Dict, List
|
||||||
import curses
|
import curses
|
||||||
import hashlib
|
import hashlib
|
||||||
import math
|
import math
|
||||||
|
|
||||||
|
Palette = Dict[float, int]
|
||||||
|
|
||||||
# BT.601 (YCbCr) constants, see XEP-0392
|
# BT.601 (YCbCr) constants, see XEP-0392
|
||||||
K_R = 0.299
|
K_R = 0.299
|
||||||
K_G = 0.587
|
K_G = 0.587
|
||||||
K_B = 1 - K_R - K_G
|
K_B = 1 - K_R - K_G
|
||||||
|
|
||||||
|
|
||||||
def ncurses_color_to_rgb(color):
|
def ncurses_color_to_rgb(color: int) -> Tuple[float, float, float]:
|
||||||
if color <= 15:
|
if color <= 15:
|
||||||
try:
|
try:
|
||||||
(r, g, b) = curses.color_content(color)
|
(r, g, b) = curses.color_content(color)
|
||||||
|
@ -30,15 +33,16 @@ def ncurses_color_to_rgb(color):
|
||||||
return r / 5, g / 5, b / 5
|
return r / 5, g / 5, b / 5
|
||||||
|
|
||||||
|
|
||||||
def rgb_to_ycbcr(r, g, b):
|
def rgb_to_ycbcr(r: float, g: float, b: float) -> Tuple[float, float, float]:
|
||||||
y = K_R * r + K_G * g + K_B * b
|
y = K_R * r + K_G * g + K_B * b
|
||||||
cr = (r - y) / (1 - K_R) / 2
|
cr = (r - y) / (1 - K_R) / 2
|
||||||
cb = (b - y) / (1 - K_B) / 2
|
cb = (b - y) / (1 - K_B) / 2
|
||||||
return y, cb, cr
|
return y, cb, cr
|
||||||
|
|
||||||
|
|
||||||
def generate_ccg_palette(curses_palette, reference_y):
|
def generate_ccg_palette(curses_palette: List[int],
|
||||||
cbcr_palette = {}
|
reference_y: float) -> Palette:
|
||||||
|
cbcr_palette = {} # type: Dict[float, Tuple[float, int]]
|
||||||
for curses_color in curses_palette:
|
for curses_color in curses_palette:
|
||||||
r, g, b = ncurses_color_to_rgb(curses_color)
|
r, g, b = ncurses_color_to_rgb(curses_color)
|
||||||
# drop grayscale
|
# drop grayscale
|
||||||
|
@ -60,14 +64,14 @@ def generate_ccg_palette(curses_palette, reference_y):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def text_to_angle(text):
|
def text_to_angle(text: str) -> float:
|
||||||
hf = hashlib.sha1()
|
hf = hashlib.sha1()
|
||||||
hf.update(text.encode("utf-8"))
|
hf.update(text.encode("utf-8"))
|
||||||
hue = int.from_bytes(hf.digest()[:2], "little")
|
hue = int.from_bytes(hf.digest()[:2], "little")
|
||||||
return hue / 65535 * math.pi * 2
|
return hue / 65535 * math.pi * 2
|
||||||
|
|
||||||
|
|
||||||
def angle_to_cbcr_edge(angle):
|
def angle_to_cbcr_edge(angle: float) -> Tuple[float, float]:
|
||||||
cr = math.sin(angle)
|
cr = math.sin(angle)
|
||||||
cb = math.cos(angle)
|
cb = math.cos(angle)
|
||||||
if abs(cr) > abs(cb):
|
if abs(cr) > abs(cb):
|
||||||
|
@ -77,7 +81,7 @@ def angle_to_cbcr_edge(angle):
|
||||||
return cb * factor, cr * factor
|
return cb * factor, cr * factor
|
||||||
|
|
||||||
|
|
||||||
def cbcr_to_angle(cb, cr):
|
def cbcr_to_angle(cb: float, cr: float) -> float:
|
||||||
magn = math.sqrt(cb**2 + cr**2)
|
magn = math.sqrt(cb**2 + cr**2)
|
||||||
if magn > 0:
|
if magn > 0:
|
||||||
cr /= magn
|
cr /= magn
|
||||||
|
@ -85,7 +89,7 @@ def cbcr_to_angle(cb, cr):
|
||||||
return math.atan2(cr, cb) % (2 * math.pi)
|
return math.atan2(cr, cb) % (2 * math.pi)
|
||||||
|
|
||||||
|
|
||||||
def ccg_palette_lookup(palette, angle):
|
def ccg_palette_lookup(palette: Palette, angle: float) -> int:
|
||||||
# try quick lookup first
|
# try quick lookup first
|
||||||
try:
|
try:
|
||||||
color = palette[round(angle, 2)]
|
color = palette[round(angle, 2)]
|
||||||
|
@ -105,6 +109,6 @@ def ccg_palette_lookup(palette, angle):
|
||||||
return best
|
return best
|
||||||
|
|
||||||
|
|
||||||
def ccg_text_to_color(palette, text):
|
def ccg_text_to_color(palette, text: str) -> int:
|
||||||
angle = text_to_angle(text)
|
angle = text_to_angle(text)
|
||||||
return ccg_palette_lookup(palette, angle)
|
return ccg_palette_lookup(palette, angle)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
"""
|
"""
|
||||||
Module containing various decorators
|
Module containing various decorators
|
||||||
"""
|
"""
|
||||||
|
from typing import Any, Callable, List, Optional
|
||||||
|
|
||||||
from poezio import common
|
from poezio import common
|
||||||
|
|
||||||
|
@ -9,7 +10,7 @@ class RefreshWrapper:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.core = None
|
self.core = None
|
||||||
|
|
||||||
def conditional(self, func):
|
def conditional(self, func: Callable) -> Callable:
|
||||||
"""
|
"""
|
||||||
Decorator to refresh the UI if the wrapped function
|
Decorator to refresh the UI if the wrapped function
|
||||||
returns True
|
returns True
|
||||||
|
@ -23,7 +24,7 @@ class RefreshWrapper:
|
||||||
|
|
||||||
return wrap
|
return wrap
|
||||||
|
|
||||||
def always(self, func):
|
def always(self, func: Callable) -> Callable:
|
||||||
"""
|
"""
|
||||||
Decorator that refreshs the UI no matter what after the function
|
Decorator that refreshs the UI no matter what after the function
|
||||||
"""
|
"""
|
||||||
|
@ -36,7 +37,7 @@ class RefreshWrapper:
|
||||||
|
|
||||||
return wrap
|
return wrap
|
||||||
|
|
||||||
def update(self, func):
|
def update(self, func: Callable) -> Callable:
|
||||||
"""
|
"""
|
||||||
Decorator that only updates the screen
|
Decorator that only updates the screen
|
||||||
"""
|
"""
|
||||||
|
@ -60,7 +61,7 @@ class CommandArgParser:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def raw(func):
|
def raw(func: Callable) -> Callable:
|
||||||
"""Just call the function with a single string, which is the original string
|
"""Just call the function with a single string, which is the original string
|
||||||
untouched
|
untouched
|
||||||
"""
|
"""
|
||||||
|
@ -71,7 +72,7 @@ class CommandArgParser:
|
||||||
return wrap
|
return wrap
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def ignored(func):
|
def ignored(func: Callable) -> Callable:
|
||||||
"""
|
"""
|
||||||
Call the function without any argument
|
Call the function without any argument
|
||||||
"""
|
"""
|
||||||
|
@ -82,9 +83,9 @@ class CommandArgParser:
|
||||||
return wrap
|
return wrap
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def quoted(mandatory,
|
def quoted(mandatory: int,
|
||||||
optional=0,
|
optional=0,
|
||||||
defaults=None,
|
defaults: Optional[List[Any]] = None,
|
||||||
ignore_trailing_arguments=False):
|
ignore_trailing_arguments=False):
|
||||||
"""The function receives a list with a number of arguments that is between
|
"""The function receives a list with a number of arguments that is between
|
||||||
the numbers `mandatory` and `optional`.
|
the numbers `mandatory` and `optional`.
|
||||||
|
@ -128,31 +129,31 @@ class CommandArgParser:
|
||||||
['un et demi', 'deux', 'trois quatre cinq six']
|
['un et demi', 'deux', 'trois quatre cinq six']
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if defaults is None:
|
default_args_outer = defaults or []
|
||||||
defaults = []
|
|
||||||
|
|
||||||
def first(func):
|
def first(func: Callable):
|
||||||
def second(self, args, *a, **kw):
|
def second(self, args: str, *a, **kw):
|
||||||
default_args = defaults
|
default_args = default_args_outer
|
||||||
if args and args.strip():
|
if args and args.strip():
|
||||||
args = common.shell_split(args)
|
split_args = common.shell_split(args)
|
||||||
else:
|
else:
|
||||||
args = []
|
split_args = []
|
||||||
if len(args) < mandatory:
|
if len(split_args) < mandatory:
|
||||||
return func(self, None, *a, **kw)
|
return func(self, None, *a, **kw)
|
||||||
res, args = args[:mandatory], args[mandatory:]
|
res, split_args = split_args[:mandatory], split_args[
|
||||||
|
mandatory:]
|
||||||
if optional == -1:
|
if optional == -1:
|
||||||
opt_args = args[:]
|
opt_args = split_args[:]
|
||||||
else:
|
else:
|
||||||
opt_args = args[:optional]
|
opt_args = split_args[:optional]
|
||||||
|
|
||||||
if opt_args:
|
if opt_args:
|
||||||
res += opt_args
|
res += opt_args
|
||||||
args = args[len(opt_args):]
|
split_args = split_args[len(opt_args):]
|
||||||
default_args = default_args[len(opt_args):]
|
default_args = default_args[len(opt_args):]
|
||||||
res += default_args
|
res += default_args
|
||||||
if args and res and not ignore_trailing_arguments:
|
if split_args and res and not ignore_trailing_arguments:
|
||||||
res[-1] += " " + " ".join(args)
|
res[-1] += " " + " ".join(split_args)
|
||||||
return func(self, res, *a, **kw)
|
return func(self, res, *a, **kw)
|
||||||
|
|
||||||
return second
|
return second
|
||||||
|
|
|
@ -99,10 +99,8 @@ class ConfirmTab(Tab):
|
||||||
|
|
||||||
def on_input(self, key, raw):
|
def on_input(self, key, raw):
|
||||||
res = self.input.do_command(key, raw=raw)
|
res = self.input.do_command(key, raw=raw)
|
||||||
if res and not isinstance(self.input, windows.Input):
|
if res:
|
||||||
return True
|
return not isinstance(self.input, windows.Input)
|
||||||
elif res:
|
|
||||||
return False
|
|
||||||
if not raw and key in self.key_func:
|
if not raw and key in self.key_func:
|
||||||
return self.key_func[key]()
|
return self.key_func[key]()
|
||||||
|
|
||||||
|
|
|
@ -161,10 +161,8 @@ class ListTab(Tab):
|
||||||
|
|
||||||
def on_input(self, key, raw):
|
def on_input(self, key, raw):
|
||||||
res = self.input.do_command(key, raw=raw)
|
res = self.input.do_command(key, raw=raw)
|
||||||
if res and not isinstance(self.input, windows.Input):
|
if res:
|
||||||
return True
|
return not isinstance(self.input, windows.Input)
|
||||||
elif res:
|
|
||||||
return False
|
|
||||||
if not raw and key in self.key_func:
|
if not raw and key in self.key_func:
|
||||||
return self.key_func[key]()
|
return self.key_func[key]()
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,9 @@ import os
|
||||||
import random
|
import random
|
||||||
import re
|
import re
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Dict, Callable
|
from typing import Dict, Callable, List, Optional, Union, Set
|
||||||
|
|
||||||
|
from slixmpp import JID
|
||||||
from poezio.tabs import ChatTab, Tab, SHOW_NAME
|
from poezio.tabs import ChatTab, Tab, SHOW_NAME
|
||||||
|
|
||||||
from poezio import common
|
from poezio import common
|
||||||
|
@ -56,15 +57,15 @@ class MucTab(ChatTab):
|
||||||
# our nick in the MUC
|
# our nick in the MUC
|
||||||
self.own_nick = nick
|
self.own_nick = nick
|
||||||
# self User object
|
# self User object
|
||||||
self.own_user = None
|
self.own_user = None # type: Optional[User]
|
||||||
self.name = jid
|
self.name = jid
|
||||||
self.password = password
|
self.password = password
|
||||||
# buffered presences
|
# buffered presences
|
||||||
self.presence_buffer = []
|
self.presence_buffer = []
|
||||||
# userlist
|
# userlist
|
||||||
self.users = []
|
self.users = [] # type: List[User]
|
||||||
# private conversations
|
# private conversations
|
||||||
self.privates = []
|
self.privates = [] # type: List[Tab]
|
||||||
self.topic = ''
|
self.topic = ''
|
||||||
self.topic_from = ''
|
self.topic_from = ''
|
||||||
# Self ping event, so we can cancel it when we leave the room
|
# Self ping event, so we can cancel it when we leave the room
|
||||||
|
@ -78,7 +79,7 @@ class MucTab(ChatTab):
|
||||||
self.info_header = windows.MucInfoWin()
|
self.info_header = windows.MucInfoWin()
|
||||||
self.input = windows.MessageInput()
|
self.input = windows.MessageInput()
|
||||||
# List of ignored users
|
# List of ignored users
|
||||||
self.ignores = []
|
self.ignores = [] # type: List[User]
|
||||||
# keys
|
# keys
|
||||||
self.register_keys()
|
self.register_keys()
|
||||||
self.update_keys()
|
self.update_keys()
|
||||||
|
@ -91,12 +92,12 @@ class MucTab(ChatTab):
|
||||||
def general_jid(self):
|
def general_jid(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
def check_send_chat_state(self):
|
def check_send_chat_state(self) -> bool:
|
||||||
"If we should send a chat state"
|
"If we should send a chat state"
|
||||||
return self.joined
|
return self.joined
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def last_connection(self):
|
def last_connection(self) -> Optional[datetime]:
|
||||||
last_message = self._text_buffer.last_message
|
last_message = self._text_buffer.last_message
|
||||||
if last_message:
|
if last_message:
|
||||||
return last_message.time
|
return last_message.time
|
||||||
|
@ -135,7 +136,7 @@ class MucTab(ChatTab):
|
||||||
show=status.show,
|
show=status.show,
|
||||||
seconds=seconds)
|
seconds=seconds)
|
||||||
|
|
||||||
def leave_room(self, message):
|
def leave_room(self, message: str):
|
||||||
if self.joined:
|
if self.joined:
|
||||||
info_col = dump_tuple(get_theme().COLOR_INFORMATION_TEXT)
|
info_col = dump_tuple(get_theme().COLOR_INFORMATION_TEXT)
|
||||||
char_quit = get_theme().CHAR_QUIT
|
char_quit = get_theme().CHAR_QUIT
|
||||||
|
@ -145,7 +146,7 @@ class MucTab(ChatTab):
|
||||||
self.general_jid):
|
self.general_jid):
|
||||||
color = dump_tuple(get_theme().COLOR_OWN_NICK)
|
color = dump_tuple(get_theme().COLOR_OWN_NICK)
|
||||||
else:
|
else:
|
||||||
color = 3
|
color = "3"
|
||||||
|
|
||||||
if message:
|
if message:
|
||||||
msg = ('\x19%(color_spec)s}%(spec)s\x19%(info_col)s} '
|
msg = ('\x19%(color_spec)s}%(spec)s\x19%(info_col)s} '
|
||||||
|
@ -179,7 +180,10 @@ class MucTab(ChatTab):
|
||||||
muc.leave_groupchat(self.core.xmpp, self.name, self.own_nick,
|
muc.leave_groupchat(self.core.xmpp, self.name, self.own_nick,
|
||||||
message)
|
message)
|
||||||
|
|
||||||
def change_affiliation(self, nick_or_jid, affiliation, reason=''):
|
def change_affiliation(self,
|
||||||
|
nick_or_jid: Union[str, JID],
|
||||||
|
affiliation: str,
|
||||||
|
reason=''):
|
||||||
"""
|
"""
|
||||||
Change the affiliation of a nick or JID
|
Change the affiliation of a nick or JID
|
||||||
"""
|
"""
|
||||||
|
@ -215,7 +219,7 @@ class MucTab(ChatTab):
|
||||||
callback=callback,
|
callback=callback,
|
||||||
reason=reason)
|
reason=reason)
|
||||||
|
|
||||||
def change_role(self, nick, role, reason=''):
|
def change_role(self, nick: str, role: str, reason=''):
|
||||||
"""
|
"""
|
||||||
Change the role of a nick
|
Change the role of a nick
|
||||||
"""
|
"""
|
||||||
|
@ -238,7 +242,7 @@ class MucTab(ChatTab):
|
||||||
self.core.xmpp, self.name, nick, reason, role, callback=callback)
|
self.core.xmpp, self.name, nick, reason, role, callback=callback)
|
||||||
|
|
||||||
@refresh_wrapper.conditional
|
@refresh_wrapper.conditional
|
||||||
def print_info(self, nick):
|
def print_info(self, nick: str) -> bool:
|
||||||
"""Print information about a user"""
|
"""Print information about a user"""
|
||||||
user = self.get_user_by_name(nick)
|
user = self.get_user_by_name(nick)
|
||||||
if not user:
|
if not user:
|
||||||
|
@ -269,7 +273,7 @@ class MucTab(ChatTab):
|
||||||
self.add_message(info, typ=0)
|
self.add_message(info, typ=0)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def change_topic(self, topic):
|
def change_topic(self, topic: str):
|
||||||
"""Change the current topic"""
|
"""Change the current topic"""
|
||||||
muc.change_subject(self.core.xmpp, self.name, topic)
|
muc.change_subject(self.core.xmpp, self.name, topic)
|
||||||
|
|
||||||
|
@ -331,7 +335,7 @@ class MucTab(ChatTab):
|
||||||
self.text_win.rebuild_everything(self._text_buffer)
|
self.text_win.rebuild_everything(self._text_buffer)
|
||||||
|
|
||||||
@refresh_wrapper.conditional
|
@refresh_wrapper.conditional
|
||||||
def set_nick_color(self, nick, color):
|
def set_nick_color(self, nick: str, color: str) -> bool:
|
||||||
"Set a custom color for a nick, permanently"
|
"Set a custom color for a nick, permanently"
|
||||||
user = self.get_user_by_name(nick)
|
user = self.get_user_by_name(nick)
|
||||||
if color not in xhtml.colors and color not in ('unset', 'random'):
|
if color not in xhtml.colors and color not in ('unset', 'random'):
|
||||||
|
@ -374,7 +378,7 @@ class MucTab(ChatTab):
|
||||||
self.send_composing_chat_state(empty_after)
|
self.send_composing_chat_state(empty_after)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def get_nick(self):
|
def get_nick(self) -> str:
|
||||||
if config.get('show_muc_jid'):
|
if config.get('show_muc_jid'):
|
||||||
return self.name
|
return self.name
|
||||||
bookmark = self.core.bookmarks[self.name]
|
bookmark = self.core.bookmarks[self.name]
|
||||||
|
@ -479,7 +483,7 @@ class MucTab(ChatTab):
|
||||||
status_codes.add(status_code.attrib['code'])
|
status_codes.add(status_code.attrib['code'])
|
||||||
self.own_join(from_nick, new_user, status_codes)
|
self.own_join(from_nick, new_user, status_codes)
|
||||||
|
|
||||||
def own_join(self, from_nick, new_user, status_codes):
|
def own_join(self, from_nick: str, new_user: User, status_codes: Set[str]):
|
||||||
"""
|
"""
|
||||||
Handle the last presence we received, entering the room
|
Handle the last presence we received, entering the room
|
||||||
"""
|
"""
|
||||||
|
@ -500,7 +504,7 @@ class MucTab(ChatTab):
|
||||||
self.general_jid):
|
self.general_jid):
|
||||||
color = dump_tuple(new_user.color)
|
color = dump_tuple(new_user.color)
|
||||||
else:
|
else:
|
||||||
color = 3
|
color = "3"
|
||||||
|
|
||||||
info_col = dump_tuple(get_theme().COLOR_INFORMATION_TEXT)
|
info_col = dump_tuple(get_theme().COLOR_INFORMATION_TEXT)
|
||||||
warn_col = dump_tuple(get_theme().COLOR_WARNING_TEXT)
|
warn_col = dump_tuple(get_theme().COLOR_WARNING_TEXT)
|
||||||
|
@ -848,11 +852,11 @@ class MucTab(ChatTab):
|
||||||
self.add_message(kick_msg, typ=2)
|
self.add_message(kick_msg, typ=2)
|
||||||
|
|
||||||
def on_user_leave_groupchat(self,
|
def on_user_leave_groupchat(self,
|
||||||
user,
|
user: User,
|
||||||
jid,
|
jid: JID,
|
||||||
status,
|
status: str,
|
||||||
from_nick,
|
from_nick: str,
|
||||||
from_room,
|
from_room: JID,
|
||||||
server_initiated=False):
|
server_initiated=False):
|
||||||
"""
|
"""
|
||||||
When an user leaves a groupchat
|
When an user leaves a groupchat
|
||||||
|
@ -960,17 +964,12 @@ class MucTab(ChatTab):
|
||||||
self.general_jid)
|
self.general_jid)
|
||||||
if hide_status_change < -1:
|
if hide_status_change < -1:
|
||||||
hide_status_change = -1
|
hide_status_change = -1
|
||||||
if ((hide_status_change == -1 or \
|
if ((hide_status_change == -1
|
||||||
user.has_talked_since(hide_status_change) or\
|
or user.has_talked_since(hide_status_change)
|
||||||
user.nick == self.own_nick)\
|
or user.nick == self.own_nick) and
|
||||||
and\
|
(affiliation != user.affiliation or role != user.role
|
||||||
(affiliation != user.affiliation or\
|
or show != user.show or status != user.status)) or (
|
||||||
role != user.role or\
|
affiliation != user.affiliation or role != user.role):
|
||||||
show != user.show or\
|
|
||||||
status != user.status))\
|
|
||||||
or\
|
|
||||||
(affiliation != user.affiliation or\
|
|
||||||
role != user.role):
|
|
||||||
# display the message in the room
|
# display the message in the room
|
||||||
self._text_buffer.add_message(msg)
|
self._text_buffer.add_message(msg)
|
||||||
self.core.on_user_changed_status_in_private(
|
self.core.on_user_changed_status_in_private(
|
||||||
|
|
|
@ -1114,10 +1114,8 @@ class RosterInfoTab(Tab):
|
||||||
if key == '^M':
|
if key == '^M':
|
||||||
selected_row = self.roster_win.get_selected_row()
|
selected_row = self.roster_win.get_selected_row()
|
||||||
res = self.input.do_command(key, raw=raw)
|
res = self.input.do_command(key, raw=raw)
|
||||||
if res and not isinstance(self.input, windows.Input):
|
if res:
|
||||||
return True
|
return not isinstance(self.input, windows.Input)
|
||||||
elif res:
|
|
||||||
return False
|
|
||||||
if key == '^M':
|
if key == '^M':
|
||||||
self.core.on_roster_enter_key(selected_row)
|
self.core.on_roster_enter_key(selected_row)
|
||||||
return selected_row
|
return selected_row
|
||||||
|
|
|
@ -281,7 +281,7 @@ class Theme:
|
||||||
(224, -1), (225, -1), (226, -1), (227, -1)]
|
(224, -1), (225, -1), (226, -1), (227, -1)]
|
||||||
# XEP-0392 consistent color generation palette placeholder
|
# XEP-0392 consistent color generation palette placeholder
|
||||||
# it’s generated on first use when accessing the ccg_palette property
|
# it’s generated on first use when accessing the ccg_palette property
|
||||||
CCG_PALETTE = None
|
CCG_PALETTE = None # type: Optional[Dict[float, int]]
|
||||||
CCG_Y = 0.5**0.45
|
CCG_Y = 0.5**0.45
|
||||||
|
|
||||||
# yapf: enable
|
# yapf: enable
|
||||||
|
@ -566,8 +566,8 @@ def reload_theme() -> Optional[str]:
|
||||||
if hasattr(new_theme, 'theme'):
|
if hasattr(new_theme, 'theme'):
|
||||||
theme = new_theme.theme
|
theme = new_theme.theme
|
||||||
prepare_ccolor_palette(theme)
|
prepare_ccolor_palette(theme)
|
||||||
else:
|
return None
|
||||||
return 'No theme present in the theme file'
|
return 'No theme present in the theme file'
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -15,6 +15,8 @@ log = logging.getLogger(__name__)
|
||||||
import curses
|
import curses
|
||||||
import string
|
import string
|
||||||
|
|
||||||
|
from typing import Optional, Tuple
|
||||||
|
|
||||||
from poezio.theming import to_curses_attr, read_tuple
|
from poezio.theming import to_curses_attr, read_tuple
|
||||||
|
|
||||||
FORMAT_CHAR = '\x19'
|
FORMAT_CHAR = '\x19'
|
||||||
|
@ -51,7 +53,7 @@ class Win:
|
||||||
if self._win is None:
|
if self._win is None:
|
||||||
self._win = DummyWin()
|
self._win = DummyWin()
|
||||||
|
|
||||||
def resize(self, height, width, y, x):
|
def resize(self, height: int, width: int, y: int, x: int):
|
||||||
"""
|
"""
|
||||||
Override if something has to be done on resize
|
Override if something has to be done on resize
|
||||||
"""
|
"""
|
||||||
|
@ -81,13 +83,13 @@ class Win:
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def move(self, y, x):
|
def move(self, y: int, x: int):
|
||||||
try:
|
try:
|
||||||
self._win.move(y, x)
|
self._win.move(y, x)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def addstr_colored(self, text, y=None, x=None):
|
def addstr_colored(self, text: str, y=None, x=None):
|
||||||
"""
|
"""
|
||||||
Write a string on the window, setting the
|
Write a string on the window, setting the
|
||||||
attributes as they are in the string.
|
attributes as they are in the string.
|
||||||
|
@ -146,7 +148,7 @@ class Win:
|
||||||
next_attr_char = text.find(FORMAT_CHAR)
|
next_attr_char = text.find(FORMAT_CHAR)
|
||||||
self.addstr(text)
|
self.addstr(text)
|
||||||
|
|
||||||
def finish_line(self, color=None):
|
def finish_line(self, color: Optional[Tuple] = None):
|
||||||
"""
|
"""
|
||||||
Write colored spaces until the end of line
|
Write colored spaces until the end of line
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -3,16 +3,17 @@ Standalone functions used by the modules
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import string
|
import string
|
||||||
DIGITS = string.digits + '-'
|
from typing import Optional, List
|
||||||
|
|
||||||
from poezio.windows.base_wins import FORMAT_CHAR, format_chars
|
from poezio.windows.base_wins import FORMAT_CHAR, format_chars
|
||||||
|
|
||||||
|
DIGITS = string.digits + '-'
|
||||||
|
|
||||||
def find_first_format_char(text, chars=None):
|
|
||||||
if chars is None:
|
def find_first_format_char(text: str,
|
||||||
chars = format_chars
|
chars: Optional[List[str]] = None) -> int:
|
||||||
|
to_find = chars or format_chars
|
||||||
pos = -1
|
pos = -1
|
||||||
for char in chars:
|
for char in to_find:
|
||||||
p = text.find(char)
|
p = text.find(char)
|
||||||
if p == -1:
|
if p == -1:
|
||||||
continue
|
continue
|
||||||
|
@ -21,7 +22,7 @@ def find_first_format_char(text, chars=None):
|
||||||
return pos
|
return pos
|
||||||
|
|
||||||
|
|
||||||
def truncate_nick(nick, size=10):
|
def truncate_nick(nick: str, size=10) -> str:
|
||||||
if size < 1:
|
if size < 1:
|
||||||
size = 1
|
size = 1
|
||||||
if nick and len(nick) > size:
|
if nick and len(nick) > size:
|
||||||
|
@ -29,7 +30,7 @@ def truncate_nick(nick, size=10):
|
||||||
return nick
|
return nick
|
||||||
|
|
||||||
|
|
||||||
def parse_attrs(text, previous=None):
|
def parse_attrs(text: str, previous: Optional[List[str]] = None) -> List[str]:
|
||||||
next_attr_char = text.find(FORMAT_CHAR)
|
next_attr_char = text.find(FORMAT_CHAR)
|
||||||
if previous:
|
if previous:
|
||||||
attrs = previous
|
attrs = previous
|
||||||
|
|
|
@ -32,7 +32,8 @@ class GlobalInfoBar(Win):
|
||||||
show_inactive = config.get('show_inactive_tabs')
|
show_inactive = config.get('show_inactive_tabs')
|
||||||
|
|
||||||
for nb, tab in enumerate(self.core.tabs):
|
for nb, tab in enumerate(self.core.tabs):
|
||||||
if not tab: continue
|
if not tab:
|
||||||
|
continue
|
||||||
color = tab.color
|
color = tab.color
|
||||||
if not show_inactive and color is get_theme().COLOR_TAB_NORMAL:
|
if not show_inactive and color is get_theme().COLOR_TAB_NORMAL:
|
||||||
continue
|
continue
|
||||||
|
@ -72,8 +73,10 @@ class VerticalGlobalInfoBar(Win):
|
||||||
self._win.erase()
|
self._win.erase()
|
||||||
sorted_tabs = [tab for tab in self.core.tabs if tab]
|
sorted_tabs = [tab for tab in self.core.tabs if tab]
|
||||||
if not config.get('show_inactive_tabs'):
|
if not config.get('show_inactive_tabs'):
|
||||||
sorted_tabs = [tab for tab in sorted_tabs if\
|
sorted_tabs = [
|
||||||
tab.vertical_color != get_theme().COLOR_VERTICAL_TAB_NORMAL]
|
tab for tab in sorted_tabs
|
||||||
|
if tab.vertical_color != get_theme().COLOR_VERTICAL_TAB_NORMAL
|
||||||
|
]
|
||||||
nb_tabs = len(sorted_tabs)
|
nb_tabs = len(sorted_tabs)
|
||||||
use_nicks = config.get('use_tab_nicks')
|
use_nicks = config.get('use_tab_nicks')
|
||||||
if nb_tabs >= height:
|
if nb_tabs >= height:
|
||||||
|
|
Loading…
Reference in a new issue