apply black with new line-length == 120

This commit is contained in:
adbenitez
2022-05-31 23:05:20 -04:00
parent d3e6cc5acb
commit 17aab01eaa
19 changed files with 86 additions and 289 deletions

View File

@@ -14,9 +14,7 @@ class EchoPlugin:
message.create_chat() message.create_chat()
addr = message.get_sender_contact().addr addr = message.get_sender_contact().addr
if message.is_system_message(): if message.is_system_message():
message.chat.send_text( message.chat.send_text("echoing system message from {}:\n{}".format(addr, message))
"echoing system message from {}:\n{}".format(addr, message)
)
else: else:
text = message.text text = message.text
message.chat.send_text("echoing from {}:\n{}".format(addr, text)) message.chat.send_text("echoing from {}:\n{}".format(addr, text))

View File

@@ -52,9 +52,7 @@ def run_cmdline(argv=None, account_plugins=None):
parser = argparse.ArgumentParser(prog=argv[0] if argv else None) parser = argparse.ArgumentParser(prog=argv[0] if argv else None)
parser.add_argument("db", action="store", help="database file") parser.add_argument("db", action="store", help="database file")
parser.add_argument( parser.add_argument("--show-ffi", action="store_true", help="show low level ffi events")
"--show-ffi", action="store_true", help="show low level ffi events"
)
parser.add_argument("--email", action="store", help="email address") parser.add_argument("--email", action="store", help="email address")
parser.add_argument("--password", action="store", help="password") parser.add_argument("--password", action="store", help="password")

View File

@@ -34,9 +34,7 @@ def local_build_flags(projdir, target):
flags["libraries"] = ["rt", "dl", "m"] flags["libraries"] = ["rt", "dl", "m"]
flags["extra_link_args"] = [] flags["extra_link_args"] = []
else: else:
raise NotImplementedError( raise NotImplementedError("Compilation not supported yet on Windows, can you help?")
"Compilation not supported yet on Windows, can you help?"
)
target_dir = os.environ.get("CARGO_TARGET_DIR") target_dir = os.environ.get("CARGO_TARGET_DIR")
if target_dir is None: if target_dir is None:
target_dir = os.path.join(projdir, "target") target_dir = os.path.join(projdir, "target")
@@ -117,9 +115,7 @@ def find_header(flags):
) )
finally: finally:
os.chdir(cwd) os.chdir(cwd)
cc.link_executable( cc.link_executable(objects=[obj_name], output_progname="where", output_dir=tmpdir)
objects=[obj_name], output_progname="where", output_dir=tmpdir
)
return subprocess.check_output(dst_name) return subprocess.check_output(dst_name)
finally: finally:
shutil.rmtree(tmpdir) shutil.rmtree(tmpdir)

View File

@@ -37,9 +37,7 @@ def get_core_info():
path.close() path.close()
return get_dc_info_as_dict( return get_dc_info_as_dict(
ffi.gc( ffi.gc(
lib.dc_context_new( lib.dc_context_new(as_dc_charpointer(""), as_dc_charpointer(path.name), ffi.NULL),
as_dc_charpointer(""), as_dc_charpointer(path.name), ffi.NULL
),
lib.dc_context_unref, lib.dc_context_unref,
) )
) )
@@ -114,11 +112,7 @@ class Account(object):
def _check_config_key(self, name: str) -> None: def _check_config_key(self, name: str) -> None:
if name not in self._configkeys: if name not in self._configkeys:
raise KeyError( raise KeyError("{!r} not a valid config key, existing keys: {!r}".format(name, self._configkeys))
"{!r} not a valid config key, existing keys: {!r}".format(
name, self._configkeys
)
)
def get_info(self) -> Dict[str, str]: def get_info(self) -> Dict[str, str]:
"""return dictionary of built config parameters.""" """return dictionary of built config parameters."""
@@ -334,9 +328,7 @@ class Account(object):
:returns: list of :class:`deltachat.contact.Contact` objects. :returns: list of :class:`deltachat.contact.Contact` objects.
""" """
dc_array = ffi.gc( dc_array = ffi.gc(lib.dc_get_blocked_contacts(self._dc_context), lib.dc_array_unref)
lib.dc_get_blocked_contacts(self._dc_context), lib.dc_array_unref
)
return list(iter_array(dc_array, lambda x: Contact(self, x))) return list(iter_array(dc_array, lambda x: Contact(self, x)))
def get_contacts( def get_contacts(
@@ -359,9 +351,7 @@ class Account(object):
flags |= const.DC_GCL_VERIFIED_ONLY flags |= const.DC_GCL_VERIFIED_ONLY
if with_self: if with_self:
flags |= const.DC_GCL_ADD_SELF flags |= const.DC_GCL_ADD_SELF
dc_array = ffi.gc( dc_array = ffi.gc(lib.dc_get_contacts(self._dc_context, flags, query), lib.dc_array_unref)
lib.dc_get_contacts(self._dc_context, flags, query), lib.dc_array_unref
)
return list(iter_array(dc_array, lambda x: Contact(self, x))) return list(iter_array(dc_array, lambda x: Contact(self, x)))
def get_fresh_messages(self) -> Generator[Message, None, None]: def get_fresh_messages(self) -> Generator[Message, None, None]:
@@ -400,9 +390,7 @@ class Account(object):
:returns: a list of :class:`deltachat.chat.Chat` objects. :returns: a list of :class:`deltachat.chat.Chat` objects.
""" """
dc_chatlist = ffi.gc( dc_chatlist = ffi.gc(lib.dc_get_chatlist(self._dc_context, 0, ffi.NULL, 0), lib.dc_chatlist_unref)
lib.dc_get_chatlist(self._dc_context, 0, ffi.NULL, 0), lib.dc_chatlist_unref
)
assert dc_chatlist != ffi.NULL assert dc_chatlist != ffi.NULL
chatlist = [] chatlist = []
@@ -538,9 +526,7 @@ class Account(object):
def check_qr(self, qr): def check_qr(self, qr):
"""check qr code and return :class:`ScannedQRCode` instance representing the result""" """check qr code and return :class:`ScannedQRCode` instance representing the result"""
res = ffi.gc( res = ffi.gc(lib.dc_check_qr(self._dc_context, as_dc_charpointer(qr)), lib.dc_lot_unref)
lib.dc_check_qr(self._dc_context, as_dc_charpointer(qr)), lib.dc_lot_unref
)
lot = DCLot(res) lot = DCLot(res)
if lot.state() == const.DC_QR_ERROR: if lot.state() == const.DC_QR_ERROR:
raise ValueError("invalid or unknown QR code: {}".format(lot.text1())) raise ValueError("invalid or unknown QR code: {}".format(lot.text1()))
@@ -575,9 +561,7 @@ class Account(object):
raise ValueError("could not join group") raise ValueError("could not join group")
return Chat(self, chat_id) return Chat(self, chat_id)
def set_location( def set_location(self, latitude: float = 0.0, longitude: float = 0.0, accuracy: float = 0.0) -> None:
self, latitude: float = 0.0, longitude: float = 0.0, accuracy: float = 0.0
) -> None:
"""set a new location. It effects all chats where we currently """set a new location. It effects all chats where we currently
have enabled location streaming. have enabled location streaming.

View File

@@ -32,10 +32,7 @@ class Chat(object):
self.id = id self.id = id
def __eq__(self, other) -> bool: def __eq__(self, other) -> bool:
return ( return self.id == getattr(other, "id", None) and self.account._dc_context == other.account._dc_context
self.id == getattr(other, "id", None)
and self.account._dc_context == other.account._dc_context
)
def __ne__(self, other) -> bool: def __ne__(self, other) -> bool:
return not (self == other) return not (self == other)
@@ -45,9 +42,7 @@ class Chat(object):
@property @property
def _dc_chat(self): def _dc_chat(self):
return ffi.gc( return ffi.gc(lib.dc_get_chat(self.account._dc_context, self.id), lib.dc_chat_unref)
lib.dc_get_chat(self.account._dc_context, self.id), lib.dc_chat_unref
)
def delete(self) -> None: def delete(self) -> None:
"""Delete this chat and all its messages. """Delete this chat and all its messages.
@@ -140,9 +135,7 @@ class Chat(object):
mute_duration = -1 mute_duration = -1
else: else:
mute_duration = duration mute_duration = duration
ret = lib.dc_set_chat_mute_duration( ret = lib.dc_set_chat_mute_duration(self.account._dc_context, self.id, mute_duration)
self.account._dc_context, self.id, mute_duration
)
if not bool(ret): if not bool(ret):
raise ValueError("Call to dc_set_chat_mute_duration failed") raise ValueError("Call to dc_set_chat_mute_duration failed")
@@ -177,9 +170,7 @@ class Chat(object):
:returns: True on success, False otherwise :returns: True on success, False otherwise
""" """
return bool( return bool(lib.dc_set_chat_ephemeral_timer(self.account._dc_context, self.id, timer))
lib.dc_set_chat_ephemeral_timer(self.account._dc_context, self.id, timer)
)
def get_type(self) -> int: def get_type(self) -> int:
"""(deprecated) return type of this chat. """(deprecated) return type of this chat.
@@ -402,9 +393,7 @@ class Chat(object):
:returns: None :returns: None
""" """
contact = self.account.get_contact(obj) contact = self.account.get_contact(obj)
ret = lib.dc_remove_contact_from_chat( ret = lib.dc_remove_contact_from_chat(self.account._dc_context, self.id, contact.id)
self.account._dc_context, self.id, contact.id
)
if ret != 1: if ret != 1:
raise ValueError("could not remove contact {!r} from chat".format(contact)) raise ValueError("could not remove contact {!r} from chat".format(contact))
@@ -489,10 +478,7 @@ class Chat(object):
"""return True if this chat is archived. """return True if this chat is archived.
:returns: True if archived. :returns: True if archived.
""" """
return ( return lib.dc_chat_get_visibility(self._dc_chat) == const.DC_CHAT_VISIBILITY_ARCHIVED
lib.dc_chat_get_visibility(self._dc_chat)
== const.DC_CHAT_VISIBILITY_ARCHIVED
)
def enable_sending_locations(self, seconds): def enable_sending_locations(self, seconds):
"""enable sending locations for this chat. """enable sending locations for this chat.
@@ -523,20 +509,14 @@ class Chat(object):
else: else:
contact_id = contact.id contact_id = contact.id
dc_array = lib.dc_get_locations( dc_array = lib.dc_get_locations(self.account._dc_context, self.id, contact_id, time_from, time_to)
self.account._dc_context, self.id, contact_id, time_from, time_to
)
return [ return [
Location( Location(
latitude=lib.dc_array_get_latitude(dc_array, i), latitude=lib.dc_array_get_latitude(dc_array, i),
longitude=lib.dc_array_get_longitude(dc_array, i), longitude=lib.dc_array_get_longitude(dc_array, i),
accuracy=lib.dc_array_get_accuracy(dc_array, i), accuracy=lib.dc_array_get_accuracy(dc_array, i),
timestamp=datetime.fromtimestamp( timestamp=datetime.fromtimestamp(lib.dc_array_get_timestamp(dc_array, i), timezone.utc),
lib.dc_array_get_timestamp(dc_array, i), timezone.utc marker=from_optional_dc_charpointer(lib.dc_array_get_marker(dc_array, i)),
),
marker=from_optional_dc_charpointer(
lib.dc_array_get_marker(dc_array, i)
),
) )
for i in range(lib.dc_array_get_cnt(dc_array)) for i in range(lib.dc_array_get_cnt(dc_array))
] ]

View File

@@ -23,24 +23,17 @@ class Contact(object):
self.id = id self.id = id
def __eq__(self, other): def __eq__(self, other):
return ( return self.account._dc_context == other.account._dc_context and self.id == other.id
self.account._dc_context == other.account._dc_context
and self.id == other.id
)
def __ne__(self, other): def __ne__(self, other):
return not (self == other) return not (self == other)
def __repr__(self): def __repr__(self):
return "<Contact id={} addr={} dc_context={}>".format( return "<Contact id={} addr={} dc_context={}>".format(self.id, self.addr, self.account._dc_context)
self.id, self.addr, self.account._dc_context
)
@property @property
def _dc_contact(self): def _dc_contact(self):
return ffi.gc( return ffi.gc(lib.dc_get_contact(self.account._dc_context, self.id), lib.dc_contact_unref)
lib.dc_get_contact(self.account._dc_context, self.id), lib.dc_contact_unref
)
@props.with_doc @props.with_doc
def addr(self) -> str: def addr(self) -> str:
@@ -58,9 +51,7 @@ class Contact(object):
@props.with_doc @props.with_doc
def last_seen(self) -> date: def last_seen(self) -> date:
"""Last seen timestamp.""" """Last seen timestamp."""
return datetime.fromtimestamp( return datetime.fromtimestamp(lib.dc_contact_get_last_seen(self._dc_contact), timezone.utc)
lib.dc_contact_get_last_seen(self._dc_contact), timezone.utc
)
def is_blocked(self): def is_blocked(self):
"""Return True if the contact is blocked.""" """Return True if the contact is blocked."""

View File

@@ -182,16 +182,9 @@ class DirectImap:
self.conn.append(bytes(msg, encoding="ascii"), folder) self.conn.append(bytes(msg, encoding="ascii"), folder)
def get_uid_by_message_id(self, message_id) -> str: def get_uid_by_message_id(self, message_id) -> str:
msgs = [ msgs = [msg.uid for msg in self.conn.fetch(AND(header=Header("MESSAGE-ID", message_id)))]
msg.uid
for msg in self.conn.fetch(AND(header=Header("MESSAGE-ID", message_id)))
]
if len(msgs) == 0: if len(msgs) == 0:
raise Exception( raise Exception("Did not find message " + message_id + ", maybe you forgot to select the correct folder?")
"Did not find message "
+ message_id
+ ", maybe you forgot to select the correct folder?"
)
return msgs[0] return msgs[0]

View File

@@ -135,12 +135,7 @@ class FFIEventTracker:
if current == expected_next: if current == expected_next:
return return
elif current != previous: elif current != previous:
raise Exception( raise Exception("Expected connectivity " + str(expected_next) + " but got " + str(current))
"Expected connectivity "
+ str(expected_next)
+ " but got "
+ str(current)
)
self.get_matching("DC_EVENT_CONNECTIVITY_CHANGED") self.get_matching("DC_EVENT_CONNECTIVITY_CHANGED")
@@ -252,12 +247,8 @@ class EventThread(threading.Thread):
lib.dc_event_unref(event) lib.dc_event_unref(event)
ffi_event = FFIEvent(name=evt_name, data1=data1, data2=data2) ffi_event = FFIEvent(name=evt_name, data1=data1, data2=data2)
with self.swallow_and_log_exception( with self.swallow_and_log_exception("ac_process_ffi_event {}".format(ffi_event)):
"ac_process_ffi_event {}".format(ffi_event) self.account._pm.hook.ac_process_ffi_event(account=self, ffi_event=ffi_event)
):
self.account._pm.hook.ac_process_ffi_event(
account=self, ffi_event=ffi_event
)
for name, kwargs in self._map_ffi_event(ffi_event): for name, kwargs in self._map_ffi_event(ffi_event):
hook = getattr(self.account._pm.hook, name) hook = getattr(self.account._pm.hook, name)
info = "call {} kwargs={} failed".format(name, kwargs) info = "call {} kwargs={} failed".format(name, kwargs)
@@ -271,9 +262,7 @@ class EventThread(threading.Thread):
except Exception as ex: except Exception as ex:
logfile = io.StringIO() logfile = io.StringIO()
traceback.print_exception(*sys.exc_info(), file=logfile) traceback.print_exception(*sys.exc_info(), file=logfile)
self.account.log( self.account.log("{}\nException {}\nTraceback:\n{}".format(info, ex, logfile.getvalue()))
"{}\nException {}\nTraceback:\n{}".format(info, ex, logfile.getvalue())
)
def _map_ffi_event(self, ffi_event: FFIEvent): def _map_ffi_event(self, ffi_event: FFIEvent):
name = ffi_event.name name = ffi_event.name

View File

@@ -46,9 +46,7 @@ class Message(object):
@classmethod @classmethod
def from_db(cls, account, id): def from_db(cls, account, id):
assert id > 0 assert id > 0
return cls( return cls(account, ffi.gc(lib.dc_get_msg(account._dc_context, id), lib.dc_msg_unref))
account, ffi.gc(lib.dc_get_msg(account._dc_context, id), lib.dc_msg_unref)
)
@classmethod @classmethod
def new_empty(cls, account, view_type): def new_empty(cls, account, view_type):
@@ -63,9 +61,7 @@ class Message(object):
view_type_code = get_viewtype_code_from_name(view_type) view_type_code = get_viewtype_code_from_name(view_type)
return Message( return Message(
account, account,
ffi.gc( ffi.gc(lib.dc_msg_new(account._dc_context, view_type_code), lib.dc_msg_unref),
lib.dc_msg_new(account._dc_context, view_type_code), lib.dc_msg_unref
),
) )
def create_chat(self): def create_chat(self):
@@ -96,12 +92,7 @@ class Message(object):
@props.with_doc @props.with_doc
def html(self) -> str: def html(self) -> str:
"""html text of this messages (might be empty if not an html message).""" """html text of this messages (might be empty if not an html message)."""
return ( return from_optional_dc_charpointer(lib.dc_get_msg_html(self.account._dc_context, self.id)) or ""
from_optional_dc_charpointer(
lib.dc_get_msg_html(self.account._dc_context, self.id)
)
or ""
)
def has_html(self): def has_html(self):
"""return True if this message has an html part, False otherwise.""" """return True if this message has an html part, False otherwise."""
@@ -166,15 +157,11 @@ class Message(object):
The text is multiline and may contain eg. the raw text of the message. The text is multiline and may contain eg. the raw text of the message.
""" """
return from_dc_charpointer( return from_dc_charpointer(lib.dc_get_msg_info(self.account._dc_context, self.id))
lib.dc_get_msg_info(self.account._dc_context, self.id)
)
def continue_key_transfer(self, setup_code): def continue_key_transfer(self, setup_code):
"""extract key and use it as primary key for this account.""" """extract key and use it as primary key for this account."""
res = lib.dc_continue_key_transfer( res = lib.dc_continue_key_transfer(self.account._dc_context, self.id, as_dc_charpointer(setup_code))
self.account._dc_context, self.id, as_dc_charpointer(setup_code)
)
if res == 0: if res == 0:
raise ValueError("could not decrypt") raise ValueError("could not decrypt")
@@ -281,9 +268,7 @@ class Message(object):
Usually used to impersonate someone else. Usually used to impersonate someone else.
""" """
return from_optional_dc_charpointer( return from_optional_dc_charpointer(lib.dc_msg_get_override_sender_name(self._dc_msg))
lib.dc_msg_get_override_sender_name(self._dc_msg)
)
def set_override_sender_name(self, name): def set_override_sender_name(self, name):
"""set different sender name for a message.""" """set different sender name for a message."""
@@ -315,9 +300,7 @@ class Message(object):
dc_msg = self._dc_msg dc_msg = self._dc_msg
else: else:
# load message from db to get a fresh/current state # load message from db to get a fresh/current state
dc_msg = ffi.gc( dc_msg = ffi.gc(lib.dc_get_msg(self.account._dc_context, self.id), lib.dc_msg_unref)
lib.dc_get_msg(self.account._dc_context, self.id), lib.dc_msg_unref
)
return lib.dc_msg_get_state(dc_msg) return lib.dc_msg_get_state(dc_msg)
def is_in_fresh(self): def is_in_fresh(self):
@@ -440,8 +423,7 @@ def get_viewtype_code_from_name(view_type_name):
if code is not None: if code is not None:
return code return code
raise ValueError( raise ValueError(
"message typecode not found for {!r}, " "message typecode not found for {!r}, " "available {!r}".format(view_type_name, list(_view_type_mapping.keys()))
"available {!r}".format(view_type_name, list(_view_type_mapping.keys()))
) )

View File

@@ -16,9 +16,7 @@ class Provider(object):
def __init__(self, account, addr) -> None: def __init__(self, account, addr) -> None:
provider = ffi.gc( provider = ffi.gc(
lib.dc_provider_new_from_email( lib.dc_provider_new_from_email(account._dc_context, as_dc_charpointer(addr)),
account._dc_context, as_dc_charpointer(addr)
),
lib.dc_provider_unref, lib.dc_provider_unref,
) )
if provider == ffi.NULL: if provider == ffi.NULL:
@@ -33,9 +31,7 @@ class Provider(object):
@property @property
def get_before_login_hints(self) -> str: def get_before_login_hints(self) -> str:
"""Should be shown to the user on login.""" """Should be shown to the user on login."""
return from_dc_charpointer( return from_dc_charpointer(lib.dc_provider_get_before_login_hint(self._provider))
lib.dc_provider_get_before_login_hint(self._provider)
)
@property @property
def status(self) -> int: def status(self) -> int:

View File

@@ -29,8 +29,7 @@ def pytest_addoption(parser):
"--liveconfig", "--liveconfig",
action="store", action="store",
default=None, default=None,
help="a file with >=2 lines where each line " help="a file with >=2 lines where each line " "contains NAME=VALUE config settings for one account",
"contains NAME=VALUE config settings for one account",
) )
group.addoption( group.addoption(
"--ignored", "--ignored",
@@ -159,9 +158,7 @@ class TestProcess:
""" """
liveconfig_opt = self.pytestconfig.getoption("--liveconfig") liveconfig_opt = self.pytestconfig.getoption("--liveconfig")
if not liveconfig_opt: if not liveconfig_opt:
pytest.skip( pytest.skip("specify DCC_NEW_TMP_EMAIL or --liveconfig to provide live accounts")
"specify DCC_NEW_TMP_EMAIL or --liveconfig to provide live accounts"
)
if not liveconfig_opt.startswith("http"): if not liveconfig_opt.startswith("http"):
for line in open(liveconfig_opt): for line in open(liveconfig_opt):
@@ -181,21 +178,13 @@ class TestProcess:
except IndexError: except IndexError:
res = requests.post(liveconfig_opt) res = requests.post(liveconfig_opt)
if res.status_code != 200: if res.status_code != 200:
pytest.fail( pytest.fail("newtmpuser count={} code={}: '{}'".format(index, res.status_code, res.text))
"newtmpuser count={} code={}: '{}'".format(
index, res.status_code, res.text
)
)
d = res.json() d = res.json()
config = dict(addr=d["email"], mail_pw=d["password"]) config = dict(addr=d["email"], mail_pw=d["password"])
print("newtmpuser {}: addr={}".format(index, config["addr"])) print("newtmpuser {}: addr={}".format(index, config["addr"]))
self._configlist.append(config) self._configlist.append(config)
yield config yield config
pytest.fail( pytest.fail("more than {} live accounts requested.".format(MAX_LIVE_CREATED_ACCOUNTS))
"more than {} live accounts requested.".format(
MAX_LIVE_CREATED_ACCOUNTS
)
)
def cache_maybe_retrieve_configured_db_files(self, cache_addr, db_target_path): def cache_maybe_retrieve_configured_db_files(self, cache_addr, db_target_path):
db_target_path = pathlib.Path(db_target_path) db_target_path = pathlib.Path(db_target_path)
@@ -252,9 +241,7 @@ def data(request):
os.path.normpath(x) os.path.normpath(x)
for x in [ for x in [
os.path.join(os.path.dirname(request.fspath.strpath), "data"), os.path.join(os.path.dirname(request.fspath.strpath), "data"),
os.path.join( os.path.join(os.path.dirname(__file__), "..", "..", "..", "test-data"),
os.path.dirname(__file__), "..", "..", "..", "test-data"
),
] ]
] ]
@@ -299,9 +286,7 @@ class ACSetup:
"""add an already configured account.""" """add an already configured account."""
assert account.is_configured() assert account.is_configured()
self._account2state[account] = self.CONFIGURED self._account2state[account] = self.CONFIGURED
self.log( self.log("added already configured account", account, account.get_config("addr"))
"added already configured account", account, account.get_config("addr")
)
def start_configure(self, account, reconfigure=False): def start_configure(self, account, reconfigure=False):
"""add an account and start its configure process.""" """add an account and start its configure process."""
@@ -452,9 +437,7 @@ class ACFactory:
# we need to use fixed database basename for maybe_cache_* functions to work # we need to use fixed database basename for maybe_cache_* functions to work
path = self.tmpdir.mkdir(logid).join("dc.db") path = self.tmpdir.mkdir(logid).join("dc.db")
if try_cache_addr: if try_cache_addr:
self.testprocess.cache_maybe_retrieve_configured_db_files( self.testprocess.cache_maybe_retrieve_configured_db_files(try_cache_addr, path)
try_cache_addr, path
)
ac = Account(path.strpath, logging=self._logging) ac = Account(path.strpath, logging=self._logging)
ac._logid = logid # later instantiated FFIEventLogger needs this ac._logid = logid # later instantiated FFIEventLogger needs this
ac._evtracker = ac.add_account_plugin(FFIEventTracker(ac)) ac._evtracker = ac.add_account_plugin(FFIEventTracker(ac))
@@ -476,12 +459,8 @@ class ACFactory:
except IndexError: except IndexError:
pass pass
else: else:
fname_pub = self.data.read_path( fname_pub = self.data.read_path("key/{name}-public.asc".format(name=keyname))
"key/{name}-public.asc".format(name=keyname) fname_sec = self.data.read_path("key/{name}-secret.asc".format(name=keyname))
)
fname_sec = self.data.read_path(
"key/{name}-secret.asc".format(name=keyname)
)
if fname_pub and fname_sec: if fname_pub and fname_sec:
account._preconfigure_keypair(addr, fname_pub, fname_sec) account._preconfigure_keypair(addr, fname_pub, fname_sec)
return True return True
@@ -638,9 +617,7 @@ class BotProcess:
# we read stdout as quickly as we can in a thread and make # we read stdout as quickly as we can in a thread and make
# the (unicode) lines available for readers through a queue. # the (unicode) lines available for readers through a queue.
self.stdout_queue = queue.Queue() self.stdout_queue = queue.Queue()
self.stdout_thread = t = threading.Thread( self.stdout_thread = t = threading.Thread(target=self._run_stdout_thread, name="bot-stdout-thread")
target=self._run_stdout_thread, name="bot-stdout-thread"
)
t.daemon = True t.daemon = True
t.start() t.start()
@@ -663,9 +640,7 @@ class BotProcess:
self.popen.wait(timeout=timeout) self.popen.wait(timeout=timeout)
def fnmatch_lines(self, pattern_lines): def fnmatch_lines(self, pattern_lines):
patterns = [ patterns = [x.strip() for x in Source(pattern_lines.rstrip()).lines if x.strip()]
x.strip() for x in Source(pattern_lines.rstrip()).lines if x.strip()
]
for next_pattern in patterns: for next_pattern in patterns:
print("+++FNMATCH:", next_pattern) print("+++FNMATCH:", next_pattern)
ignored = [] ignored = []

View File

@@ -19,16 +19,12 @@ class ImexTracker:
elif ffi_event.name == "DC_EVENT_IMEX_FILE_WRITTEN": elif ffi_event.name == "DC_EVENT_IMEX_FILE_WRITTEN":
self._imex_events.put(ffi_event.data2) self._imex_events.put(ffi_event.data2)
def wait_progress( def wait_progress(self, target_progress, progress_upper_limit=1000, progress_timeout=60):
self, target_progress, progress_upper_limit=1000, progress_timeout=60
):
while True: while True:
ev = self._imex_events.get(timeout=progress_timeout) ev = self._imex_events.get(timeout=progress_timeout)
if isinstance(ev, int) and ev >= target_progress: if isinstance(ev, int) and ev >= target_progress:
assert ev <= progress_upper_limit, ( assert ev <= progress_upper_limit, (
str(ev) str(ev) + " exceeded upper progress limit " + str(progress_upper_limit)
+ " exceeded upper progress limit "
+ str(progress_upper_limit)
) )
return ev return ev
if ev == 0: if ev == 0:

View File

@@ -8,10 +8,6 @@ if __name__ == "__main__":
# pip wheel will build in an isolated tmp dir that does not have git # pip wheel will build in an isolated tmp dir that does not have git
# history so setuptools_scm can not automatically determine a # history so setuptools_scm can not automatically determine a
# version there. So pass in the version through an env var. # version there. So pass in the version through an env var.
version = ( version = subprocess.check_output(["python", "setup.py", "--version"]).strip().split(b"\n")[-1]
subprocess.check_output(["python", "setup.py", "--version"])
.strip()
.split(b"\n")[-1]
)
os.environ["SETUPTOOLS_SCM_PRETEND_VERSION"] = version.decode("ascii") os.environ["SETUPTOOLS_SCM_PRETEND_VERSION"] = version.decode("ascii")
subprocess.check_call(("pip wheel . -w %s" % wheelhousedir).split()) subprocess.check_call(("pip wheel . -w %s" % wheelhousedir).split())

View File

@@ -41,9 +41,7 @@ def test_db_busy_error(acfactory, tmpdir):
# each replier receives all events and sends report events to receive_queue # each replier receives all events and sends report events to receive_queue
repliers = [] repliers = []
for acc in accounts: for acc in accounts:
replier = AutoReplier( replier = AutoReplier(acc, log=log, num_send=500, num_bigfiles=5, report_func=report_func)
acc, log=log, num_send=500, num_bigfiles=5, report_func=report_func
)
acc.add_account_plugin(replier) acc.add_account_plugin(replier)
repliers.append(replier) repliers.append(replier)
@@ -65,11 +63,7 @@ def test_db_busy_error(acfactory, tmpdir):
elif report_type == ReportType.message_echo: elif report_type == ReportType.message_echo:
continue continue
else: else:
raise ValueError( raise ValueError("{} unknown report type {}, args={}".format(addr, report_type, report_args))
"{} unknown report type {}, args={}".format(
addr, report_type, report_args
)
)
alive_count -= 1 alive_count -= 1
replier.log("shutting down") replier.log("shutting down")
replier.account.shutdown() replier.account.shutdown()
@@ -92,9 +86,7 @@ class AutoReplier:
self.current_sent = 0 self.current_sent = 0
self.addr = self.account.get_self_contact().addr self.addr = self.account.get_self_contact().addr
self._thread = threading.Thread( self._thread = threading.Thread(name="Stats{}".format(self.account), target=self.thread_stats)
name="Stats{}".format(self.account), target=self.thread_stats
)
self._thread.setDaemon(True) self._thread.setDaemon(True)
self._thread.start() self._thread.start()
@@ -119,16 +111,11 @@ class AutoReplier:
self.current_sent += 1 self.current_sent += 1
# we are still alive, let's send a reply # we are still alive, let's send a reply
if ( if self.num_bigfiles and self.current_sent % (self.num_send / self.num_bigfiles) == 0:
self.num_bigfiles
and self.current_sent % (self.num_send / self.num_bigfiles) == 0
):
message.chat.send_text("send big file as reply to: {}".format(message.text)) message.chat.send_text("send big file as reply to: {}".format(message.text))
msg = message.chat.send_file(self.account.bigfile) msg = message.chat.send_file(self.account.bigfile)
else: else:
msg = message.chat.send_text( msg = message.chat.send_text("got message id {}, small text reply".format(message.id))
"got message id {}, small text reply".format(message.id)
)
assert msg.text assert msg.text
self.log("message-sent: {}".format(msg)) self.log("message-sent: {}".format(msg))
self.report_func(self, ReportType.message_echo) self.report_func(self, ReportType.message_echo)

View File

@@ -216,9 +216,7 @@ def test_fetch_existing(acfactory, lp, mvbox_move):
chat.send_text("message text") chat.send_text("message text")
assert_folders_configured(ac1) assert_folders_configured(ac1)
lp.sec( lp.sec("wait until the bcc_self message arrives in correct folder and is marked seen")
"wait until the bcc_self message arrives in correct folder and is marked seen"
)
assert idle1.wait_for_seen() assert idle1.wait_for_seen()
assert_folders_configured(ac1) assert_folders_configured(ac1)
@@ -257,9 +255,7 @@ def test_fetch_existing_msgs_group_and_single(acfactory, lp):
acfactory.bring_accounts_online() acfactory.bring_accounts_online()
lp.sec("receive a message") lp.sec("receive a message")
ac2.create_group_chat("group name", contacts=[ac1]).send_text( ac2.create_group_chat("group name", contacts=[ac1]).send_text("incoming, unencrypted group message")
"incoming, unencrypted group message"
)
ac1._evtracker.wait_next_incoming_message() ac1._evtracker.wait_next_incoming_message()
lp.sec("send out message with bcc to ourselves") lp.sec("send out message with bcc to ourselves")

View File

@@ -35,12 +35,8 @@ def test_basic_imap_api(acfactory, tmpdir):
def test_configure_generate_key(acfactory, lp): def test_configure_generate_key(acfactory, lp):
# A slow test which will generate new keys. # A slow test which will generate new keys.
acfactory.remove_preconfigured_keys() acfactory.remove_preconfigured_keys()
ac1 = acfactory.new_online_configuring_account( ac1 = acfactory.new_online_configuring_account(key_gen_type=str(const.DC_KEY_GEN_RSA2048))
key_gen_type=str(const.DC_KEY_GEN_RSA2048) ac2 = acfactory.new_online_configuring_account(key_gen_type=str(const.DC_KEY_GEN_ED25519))
)
ac2 = acfactory.new_online_configuring_account(
key_gen_type=str(const.DC_KEY_GEN_ED25519)
)
acfactory.bring_accounts_online() acfactory.bring_accounts_online()
chat = acfactory.get_accepted_chat(ac1, ac2) chat = acfactory.get_accepted_chat(ac1, ac2)
@@ -91,9 +87,7 @@ def test_export_import_self_keys(acfactory, tmpdir, lp):
lp.indent(dir.strpath + os.sep + name) lp.indent(dir.strpath + os.sep + name)
lp.sec("importing into existing account") lp.sec("importing into existing account")
ac2.import_self_keys(dir.strpath) ac2.import_self_keys(dir.strpath)
(key_id2,) = ac2._evtracker.get_info_regex_groups( (key_id2,) = ac2._evtracker.get_info_regex_groups(r".*stored.*KeyId\((.*)\).*", check_error=False)
r".*stored.*KeyId\((.*)\).*", check_error=False
)
assert key_id2 == key_id assert key_id2 == key_id
@@ -249,9 +243,7 @@ def test_mvbox_sentbox_threads(acfactory, lp):
ac1 = acfactory.new_online_configuring_account(mvbox_move=True, sentbox_watch=True) ac1 = acfactory.new_online_configuring_account(mvbox_move=True, sentbox_watch=True)
lp.sec("ac2: start without mvbox/sentbox threads") lp.sec("ac2: start without mvbox/sentbox threads")
ac2 = acfactory.new_online_configuring_account( ac2 = acfactory.new_online_configuring_account(mvbox_move=False, sentbox_watch=False)
mvbox_move=False, sentbox_watch=False
)
lp.sec("ac2 and ac1: waiting for configuration") lp.sec("ac2 and ac1: waiting for configuration")
acfactory.bring_accounts_online() acfactory.bring_accounts_online()
@@ -473,10 +465,7 @@ def test_moved_markseen(acfactory, lp):
ac2.mark_seen_messages([msg]) ac2.mark_seen_messages([msg])
uid = idle2.wait_for_seen() uid = idle2.wait_for_seen()
assert ( assert len([a for a in ac2.direct_imap.conn.fetch(AND(seen=True, uid=U(uid, "*")))]) == 1
len([a for a in ac2.direct_imap.conn.fetch(AND(seen=True, uid=U(uid, "*")))])
== 1
)
def test_message_override_sender_name(acfactory, lp): def test_message_override_sender_name(acfactory, lp):
@@ -880,9 +869,7 @@ def test_dont_show_emails(acfactory, lp):
assert ac1.direct_imap.get_uid_by_message_id("spam.message@junk.org") assert ac1.direct_imap.get_uid_by_message_id("spam.message@junk.org")
ac1.stop_io() ac1.stop_io()
lp.sec( lp.sec("'Send out' the draft, i.e. move it to the Sent folder, and wait for DC to display it this time")
"'Send out' the draft, i.e. move it to the Sent folder, and wait for DC to display it this time"
)
ac1.direct_imap.select_folder("Drafts") ac1.direct_imap.select_folder("Drafts")
uid = ac1.direct_imap.get_uid_by_message_id("aepiors@example.org") uid = ac1.direct_imap.get_uid_by_message_id("aepiors@example.org")
ac1.direct_imap.conn.move(uid, "Sent") ac1.direct_imap.conn.move(uid, "Sent")
@@ -917,9 +904,7 @@ def test_no_old_msg_is_fresh(acfactory, lp):
assert ac1.create_chat(ac2).count_fresh_messages() == 1 assert ac1.create_chat(ac2).count_fresh_messages() == 1
assert len(list(ac1.get_fresh_messages())) == 1 assert len(list(ac1.get_fresh_messages())) == 1
lp.sec( lp.sec("Send a message from ac1_clone to ac2 and check that ac1 marks the first message as 'noticed'")
"Send a message from ac1_clone to ac2 and check that ac1 marks the first message as 'noticed'"
)
ac1_clone.create_chat(ac2).send_text("Hi back") ac1_clone.create_chat(ac2).send_text("Hi back")
ev = ac1._evtracker.get_matching("DC_EVENT_MSGS_NOTICED") ev = ac1._evtracker.get_matching("DC_EVENT_MSGS_NOTICED")
@@ -1215,10 +1200,7 @@ def test_import_export_online_all(acfactory, tmpdir, data, lp):
assert len(messages) == 3 assert len(messages) == 3
assert messages[0].text == "msg1" assert messages[0].text == "msg1"
assert messages[1].filemime == "image/png" assert messages[1].filemime == "image/png"
assert ( assert os.stat(messages[1].filename).st_size == os.stat(original_image_path).st_size
os.stat(messages[1].filename).st_size
== os.stat(original_image_path).st_size
)
ac.set_config("displayname", "new displayname") ac.set_config("displayname", "new displayname")
assert ac.get_config("displayname") == "new displayname" assert ac.get_config("displayname") == "new displayname"
@@ -1364,9 +1346,7 @@ def test_set_get_contact_avatar(acfactory, data, lp):
assert open(received_path, "rb").read() == open(p, "rb").read() assert open(received_path, "rb").read() == open(p, "rb").read()
lp.sec("ac2: send back message") lp.sec("ac2: send back message")
msg3 = msg2.create_chat().send_text( msg3 = msg2.create_chat().send_text("yes, i received your avatar -- how do you like mine?")
"yes, i received your avatar -- how do you like mine?"
)
assert msg3.is_encrypted() assert msg3.is_encrypted()
lp.sec("ac1: wait for receiving message and avatar from ac2") lp.sec("ac1: wait for receiving message and avatar from ac2")
@@ -1411,17 +1391,11 @@ def test_add_remove_member_remote_events(acfactory, lp):
@account_hookimpl @account_hookimpl
def ac_member_added(self, chat, contact, message): def ac_member_added(self, chat, contact, message):
in_list.put( in_list.put(EventHolder(action="added", chat=chat, contact=contact, message=message))
EventHolder(action="added", chat=chat, contact=contact, message=message)
)
@account_hookimpl @account_hookimpl
def ac_member_removed(self, chat, contact, message): def ac_member_removed(self, chat, contact, message):
in_list.put( in_list.put(EventHolder(action="removed", chat=chat, contact=contact, message=message))
EventHolder(
action="removed", chat=chat, contact=contact, message=message
)
)
ac2.add_account_plugin(InPlugin()) ac2.add_account_plugin(InPlugin())
@@ -1433,9 +1407,7 @@ def test_add_remove_member_remote_events(acfactory, lp):
ev = in_list.get() ev = in_list.get()
assert ev.action == "chat-modified" assert ev.action == "chat-modified"
assert chat.is_promoted() assert chat.is_promoted()
assert sorted(x.addr for x in chat.get_contacts()) == sorted( assert sorted(x.addr for x in chat.get_contacts()) == sorted(x.addr for x in ev.chat.get_contacts())
x.addr for x in ev.chat.get_contacts()
)
lp.sec("ac1: add address2") lp.sec("ac1: add address2")
# note that if the above create_chat() would not # note that if the above create_chat() would not
@@ -1575,9 +1547,7 @@ def test_connectivity(acfactory, lp):
ac1.start_io() ac1.start_io()
ac1._evtracker.wait_for_connectivity(const.DC_CONNECTIVITY_CONNECTING) ac1._evtracker.wait_for_connectivity(const.DC_CONNECTIVITY_CONNECTING)
ac1._evtracker.wait_for_connectivity_change( ac1._evtracker.wait_for_connectivity_change(const.DC_CONNECTIVITY_CONNECTING, const.DC_CONNECTIVITY_CONNECTED)
const.DC_CONNECTIVITY_CONNECTING, const.DC_CONNECTIVITY_CONNECTED
)
lp.sec( lp.sec(
"Test that after calling start_io(), maybe_network() and waiting for `all_work_done()`, " "Test that after calling start_io(), maybe_network() and waiting for `all_work_done()`, "
@@ -1594,26 +1564,18 @@ def test_connectivity(acfactory, lp):
assert len(msgs) == 1 assert len(msgs) == 1
assert msgs[0].text == "Hi" assert msgs[0].text == "Hi"
lp.sec( lp.sec("Test that the connectivity changes to WORKING while new messages are fetched")
"Test that the connectivity changes to WORKING while new messages are fetched"
)
ac2.create_chat(ac1).send_text("Hi 2") ac2.create_chat(ac1).send_text("Hi 2")
ac1._evtracker.wait_for_connectivity_change( ac1._evtracker.wait_for_connectivity_change(const.DC_CONNECTIVITY_CONNECTED, const.DC_CONNECTIVITY_WORKING)
const.DC_CONNECTIVITY_CONNECTED, const.DC_CONNECTIVITY_WORKING ac1._evtracker.wait_for_connectivity_change(const.DC_CONNECTIVITY_WORKING, const.DC_CONNECTIVITY_CONNECTED)
)
ac1._evtracker.wait_for_connectivity_change(
const.DC_CONNECTIVITY_WORKING, const.DC_CONNECTIVITY_CONNECTED
)
msgs = ac1.create_chat(ac2).get_messages() msgs = ac1.create_chat(ac2).get_messages()
assert len(msgs) == 2 assert len(msgs) == 2
assert msgs[1].text == "Hi 2" assert msgs[1].text == "Hi 2"
lp.sec( lp.sec("Test that the connectivity doesn't flicker to WORKING if there are no new messages")
"Test that the connectivity doesn't flicker to WORKING if there are no new messages"
)
ac1.maybe_network() ac1.maybe_network()
while 1: while 1:
@@ -1622,9 +1584,7 @@ def test_connectivity(acfactory, lp):
break break
ac1._evtracker.get_matching("DC_EVENT_CONNECTIVITY_CHANGED") ac1._evtracker.get_matching("DC_EVENT_CONNECTIVITY_CHANGED")
lp.sec( lp.sec("Test that the connectivity doesn't flicker to WORKING if the sender of the message is blocked")
"Test that the connectivity doesn't flicker to WORKING if the sender of the message is blocked"
)
ac1.create_contact(ac2).block() ac1.create_contact(ac2).block()
ac1.direct_imap.select_config_folder("inbox") ac1.direct_imap.select_config_folder("inbox")
@@ -1690,10 +1650,7 @@ def test_fetch_deleted_msg(acfactory, lp):
if ev.name == "DC_EVENT_MSGS_CHANGED": if ev.name == "DC_EVENT_MSGS_CHANGED":
pytest.fail("A deleted message was shown to the user") pytest.fail("A deleted message was shown to the user")
if ( if ev.name == "DC_EVENT_INFO" and "INBOX: Idle entering wait-on-remote state" in ev.data2:
ev.name == "DC_EVENT_INFO"
and "INBOX: Idle entering wait-on-remote state" in ev.data2
):
break # DC is done with reading messages break # DC is done with reading messages

View File

@@ -85,22 +85,16 @@ class TestOnlineInCreation:
assert prepared_original.is_out_preparing() assert prepared_original.is_out_preparing()
shutil.copyfile(orig, path) shutil.copyfile(orig, path)
chat.send_prepared(prepared_original) chat.send_prepared(prepared_original)
assert ( assert prepared_original.is_out_pending() or prepared_original.is_out_delivered()
prepared_original.is_out_pending() or prepared_original.is_out_delivered()
)
lp.sec("check that both forwarded and original message are proper.") lp.sec("check that both forwarded and original message are proper.")
wait_msgs_changed( wait_msgs_changed(ac1, [(chat2.id, forwarded_id), (chat.id, prepared_original.id)])
ac1, [(chat2.id, forwarded_id), (chat.id, prepared_original.id)]
)
fwd_msg = ac1.get_message_by_id(forwarded_id) fwd_msg = ac1.get_message_by_id(forwarded_id)
assert fwd_msg.is_out_pending() or fwd_msg.is_out_delivered() assert fwd_msg.is_out_pending() or fwd_msg.is_out_delivered()
lp.sec("wait for both messages to be delivered to SMTP") lp.sec("wait for both messages to be delivered to SMTP")
wait_msg_delivered( wait_msg_delivered(ac1, [(chat2.id, forwarded_id), (chat.id, prepared_original.id)])
ac1, [(chat2.id, forwarded_id), (chat.id, prepared_original.id)]
)
lp.sec("wait1 for original or forwarded messages to arrive") lp.sec("wait1 for original or forwarded messages to arrive")
received_original = ac2._evtracker.wait_next_incoming_message() received_original = ac2._evtracker.wait_next_incoming_message()

View File

@@ -292,11 +292,7 @@ class TestOfflineChat:
assert d["archived"] == chat.is_archived() assert d["archived"] == chat.is_archived()
# assert d["param"] == chat.param # assert d["param"] == chat.param
assert d["color"] == chat.get_color() assert d["color"] == chat.get_color()
assert ( assert d["profile_image"] == "" if chat.get_profile_image() is None else chat.get_profile_image()
d["profile_image"] == ""
if chat.get_profile_image() is None
else chat.get_profile_image()
)
assert d["draft"] == "" if chat.get_draft() is None else chat.get_draft() assert d["draft"] == "" if chat.get_draft() is None else chat.get_draft()
def test_group_chat_creation_with_translation(self, ac1): def test_group_chat_creation_with_translation(self, ac1):

View File

@@ -43,9 +43,7 @@ class TestACSetup:
pc.bring_online() pc.bring_online()
assert pc._account2state[acc] == pc.IDLEREADY assert pc._account2state[acc] == pc.IDLEREADY
def test_two_accounts_one_waited_all_started( def test_two_accounts_one_waited_all_started(self, monkeypatch, acfactory, testprocess):
self, monkeypatch, acfactory, testprocess
):
pc = ACSetup(init_time=0.0, testprocess=testprocess) pc = ACSetup(init_time=0.0, testprocess=testprocess)
monkeypatch.setattr(pc, "init_imap", lambda *args, **kwargs: None) monkeypatch.setattr(pc, "init_imap", lambda *args, **kwargs: None)
monkeypatch.setattr(pc, "_onconfigure_start_io", lambda *args, **kwargs: None) monkeypatch.setattr(pc, "_onconfigure_start_io", lambda *args, **kwargs: None)
@@ -172,12 +170,7 @@ def test_provider_info_none():
lib.dc_context_new(ffi.NULL, ffi.NULL, ffi.NULL), lib.dc_context_new(ffi.NULL, ffi.NULL, ffi.NULL),
lib.dc_context_unref, lib.dc_context_unref,
) )
assert ( assert lib.dc_provider_new_from_email(ctx, cutil.as_dc_charpointer("email@unexistent.no")) == ffi.NULL
lib.dc_provider_new_from_email(
ctx, cutil.as_dc_charpointer("email@unexistent.no")
)
== ffi.NULL
)
def test_get_info_open(tmpdir): def test_get_info_open(tmpdir):