mirror of
https://github.com/chatmail/core.git
synced 2026-04-23 00:16:34 +03:00
apply black with new line-length == 120
This commit is contained in:
@@ -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))
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|
||||||
|
|||||||
@@ -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))
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -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."""
|
||||||
|
|||||||
@@ -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]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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()))
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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 = []
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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())
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
Reference in New Issue
Block a user