mirror of
https://github.com/chatmail/core.git
synced 2026-05-22 16:26:31 +03:00
fix various location-streaming issue, test passes now
This commit is contained in:
@@ -417,7 +417,7 @@ class Chat(object):
|
|||||||
|
|
||||||
class Location:
|
class Location:
|
||||||
def __init__(self, latitude, longitude, accuracy, timestamp):
|
def __init__(self, latitude, longitude, accuracy, timestamp):
|
||||||
assert isinstance(timestamp, datetime.datetime)
|
assert isinstance(timestamp, datetime)
|
||||||
self.latitude = latitude
|
self.latitude = latitude
|
||||||
self.longitude = longitude
|
self.longitude = longitude
|
||||||
self.accuracy = accuracy
|
self.accuracy = accuracy
|
||||||
|
|||||||
@@ -827,17 +827,20 @@ class TestOnlineAccount:
|
|||||||
lp.sec("ac1: enable location sending in chat")
|
lp.sec("ac1: enable location sending in chat")
|
||||||
chat1.enable_sending_locations(seconds=100)
|
chat1.enable_sending_locations(seconds=100)
|
||||||
assert chat1.is_sending_locations()
|
assert chat1.is_sending_locations()
|
||||||
|
ac1._evlogger.get_matching("DC_EVENT_SMTP_MESSAGE_SENT")
|
||||||
|
|
||||||
lp.sec("ac1: setting location")
|
ac1.set_location(latitude=2.0, longitude=3.0)
|
||||||
ac1.set_location(latitude=1.0, longitude=2.0)
|
|
||||||
ac1._evlogger.get_matching("DC_EVENT_LOCATION_CHANGED")
|
ac1._evlogger.get_matching("DC_EVENT_LOCATION_CHANGED")
|
||||||
chat1.send_text("hello")
|
chat1.send_text("hello")
|
||||||
ac1._evlogger.get_matching("DC_EVENT_SMTP_MESSAGE_SENT")
|
ac1._evlogger.get_matching("DC_EVENT_SMTP_MESSAGE_SENT")
|
||||||
ac1._evlogger.get_matching("DC_EVENT_SMTP_MESSAGE_SENT")
|
|
||||||
|
|
||||||
lp.sec("ac2: wait for incoming location message")
|
lp.sec("ac2: wait for incoming location message")
|
||||||
ac2._evlogger.get_matching("DC_EVENT_INCOMING_MSG")
|
ac2._evlogger.get_matching("DC_EVENT_INCOMING_MSG") # "enabled-location streaming"
|
||||||
ac2._evlogger.get_matching("DC_EVENT_INCOMING_MSG")
|
|
||||||
|
# currently core emits location changed before event_incoming message
|
||||||
|
ac2._evlogger.get_matching("DC_EVENT_LOCATION_CHANGED")
|
||||||
|
ac2._evlogger.get_matching("DC_EVENT_INCOMING_MSG") # text message with location
|
||||||
|
|
||||||
# contact = ac2.create_contact(ac1.get_config("addr"))
|
# contact = ac2.create_contact(ac1.get_config("addr"))
|
||||||
locations = chat2.get_locations() # XXX per contact
|
locations = chat2.get_locations() # XXX per contact
|
||||||
assert len(locations) >= 1
|
assert len(locations) >= 1
|
||||||
|
|||||||
@@ -598,7 +598,7 @@ impl<'a> MimeParser<'a> {
|
|||||||
let mut decoded_data = match wrapmime::mailmime_transfer_decode(mime) {
|
let mut decoded_data = match wrapmime::mailmime_transfer_decode(mime) {
|
||||||
Ok(decoded_data) => decoded_data,
|
Ok(decoded_data) => decoded_data,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
// Note that it's now always an error - might be no data
|
// Note that it's not always an error - might be no data
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -736,19 +736,6 @@ impl<'a> MimeParser<'a> {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if desired_filename.starts_with("location") && desired_filename.ends_with(".kml") {
|
|
||||||
if !decoded_data.is_empty() {
|
|
||||||
let d = std::string::String::from_utf8_lossy(&decoded_data);
|
|
||||||
self.location_kml = location::Kml::parse(self.context, &d).ok();
|
|
||||||
}
|
|
||||||
} else if desired_filename.starts_with("message")
|
|
||||||
&& desired_filename.ends_with(".kml")
|
|
||||||
{
|
|
||||||
if !decoded_data.is_empty() {
|
|
||||||
let d = std::string::String::from_utf8_lossy(&decoded_data);
|
|
||||||
self.message_kml = location::Kml::parse(self.context, &d).ok();
|
|
||||||
}
|
|
||||||
} else if !decoded_data.is_empty() {
|
|
||||||
self.do_add_single_file_part(
|
self.do_add_single_file_part(
|
||||||
msg_type,
|
msg_type,
|
||||||
mime_type,
|
mime_type,
|
||||||
@@ -757,7 +744,6 @@ impl<'a> MimeParser<'a> {
|
|||||||
&desired_filename,
|
&desired_filename,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
/* add object? (we do not add all objects, eg. signatures etc. are ignored) */
|
/* add object? (we do not add all objects, eg. signatures etc. are ignored) */
|
||||||
@@ -770,20 +756,47 @@ impl<'a> MimeParser<'a> {
|
|||||||
mime_type: libc::c_int,
|
mime_type: libc::c_int,
|
||||||
raw_mime: Option<&String>,
|
raw_mime: Option<&String>,
|
||||||
decoded_data: &[u8],
|
decoded_data: &[u8],
|
||||||
desired_filename: &str,
|
filename: &str,
|
||||||
) {
|
) {
|
||||||
/* write decoded data to new blob file */
|
if decoded_data.is_empty() {
|
||||||
let blob = match BlobObject::create(self.context, desired_filename, decoded_data) {
|
return;
|
||||||
|
}
|
||||||
|
// treat location/message kml file attachments specially
|
||||||
|
if filename.ends_with(".kml") {
|
||||||
|
// XXX what if somebody sends eg an "location-highlights.kml"
|
||||||
|
// attachment unrelated to location streaming?
|
||||||
|
if filename.starts_with("location") || filename.starts_with("message") {
|
||||||
|
let d = std::string::String::from_utf8_lossy(&decoded_data);
|
||||||
|
let parsed = match location::Kml::parse(self.context, &d) {
|
||||||
|
Ok(res) => Some(res),
|
||||||
|
Err(err) => {
|
||||||
|
warn!(self.context, "failed to parse kml part: {}", err);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if filename.starts_with("location") {
|
||||||
|
self.location_kml = parsed;
|
||||||
|
} else {
|
||||||
|
self.message_kml = parsed;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* we have a regular file attachment,
|
||||||
|
write decoded data to new blob object */
|
||||||
|
|
||||||
|
let blob = match BlobObject::create(self.context, filename, decoded_data) {
|
||||||
Ok(blob) => blob,
|
Ok(blob) => blob,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!(
|
error!(
|
||||||
self.context,
|
self.context,
|
||||||
"Could not add blob for mime part {}, error {}", desired_filename, err
|
"Could not add blob for mime part {}, error {}", filename, err
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* create and register Mime part referencing the new Blob object */
|
||||||
let mut part = Part::default();
|
let mut part = Part::default();
|
||||||
part.typ = msg_type;
|
part.typ = msg_type;
|
||||||
part.mimetype = mime_type;
|
part.mimetype = mime_type;
|
||||||
@@ -803,11 +816,19 @@ impl<'a> MimeParser<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn do_add_single_part(&mut self, mut part: Part) {
|
fn do_add_single_part(&mut self, mut part: Part) {
|
||||||
if self.encrypted && self.signatures.len() > 0 {
|
// we transfer the encryption-state to each part
|
||||||
|
// because each part lands to each part ? Autocrypt does not define "partially encrypted"
|
||||||
|
// so either the whole message is encrypted properly or nothing
|
||||||
|
if self.encrypted {
|
||||||
|
if self.signatures.len() > 0 {
|
||||||
part.param.set_int(Param::GuaranteeE2ee, 1);
|
part.param.set_int(Param::GuaranteeE2ee, 1);
|
||||||
} else if self.encrypted {
|
} else {
|
||||||
|
// XXX if the message was encrypted but not signed
|
||||||
|
// it's not neccessarily an error we need to signal.
|
||||||
|
// we could just treat it as if it was not encrypted.
|
||||||
part.param.set_int(Param::ErroneousE2ee, 0x2);
|
part.param.set_int(Param::ErroneousE2ee, 0x2);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
self.parts.push(part);
|
self.parts.push(part);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ pub unsafe fn dc_receive_imf(
|
|||||||
&mut created_db_entries,
|
&mut created_db_entries,
|
||||||
&mut create_event_to_send,
|
&mut create_event_to_send,
|
||||||
) {
|
) {
|
||||||
info!(context, "{}", err);
|
warn!(context, "{}", err);
|
||||||
|
|
||||||
cleanup(
|
cleanup(
|
||||||
context,
|
context,
|
||||||
@@ -257,7 +257,7 @@ pub unsafe fn dc_receive_imf(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !mime_parser.message_kml.is_none() && chat_id > DC_CHAT_ID_LAST_SPECIAL {
|
if mime_parser.location_kml.is_some() || mime_parser.message_kml.is_some() {
|
||||||
save_locations(
|
save_locations(
|
||||||
context,
|
context,
|
||||||
&mime_parser,
|
&mime_parser,
|
||||||
@@ -604,6 +604,7 @@ unsafe fn add_parts(
|
|||||||
// into only one message; mails sent by other clients may result in several messages
|
// into only one message; mails sent by other clients may result in several messages
|
||||||
// (eg. one per attachment))
|
// (eg. one per attachment))
|
||||||
let icnt = mime_parser.parts.len();
|
let icnt = mime_parser.parts.len();
|
||||||
|
|
||||||
let mut txt_raw = None;
|
let mut txt_raw = None;
|
||||||
|
|
||||||
context.sql.prepare(
|
context.sql.prepare(
|
||||||
@@ -644,17 +645,6 @@ unsafe fn add_parts(
|
|||||||
.set_int(Param::Cmd, mime_parser.is_system_message as i32);
|
.set_int(Param::Cmd, mime_parser.is_system_message as i32);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
info!(
|
|
||||||
context,
|
|
||||||
"received mime message {:?}",
|
|
||||||
String::from_utf8_lossy(std::slice::from_raw_parts(
|
|
||||||
imf_raw_not_terminated as *const u8,
|
|
||||||
imf_raw_bytes,
|
|
||||||
))
|
|
||||||
);
|
|
||||||
*/
|
|
||||||
|
|
||||||
stmt.execute(params![
|
stmt.execute(params![
|
||||||
rfc724_mid,
|
rfc724_mid,
|
||||||
server_folder.as_ref(),
|
server_folder.as_ref(),
|
||||||
@@ -850,10 +840,20 @@ fn save_locations(
|
|||||||
insert_msg_id: MsgId,
|
insert_msg_id: MsgId,
|
||||||
hidden: i32,
|
hidden: i32,
|
||||||
) {
|
) {
|
||||||
|
if chat_id <= DC_CHAT_ID_LAST_SPECIAL as libc::c_uint {
|
||||||
|
return ();
|
||||||
|
}
|
||||||
let mut location_id_written = false;
|
let mut location_id_written = false;
|
||||||
let mut send_event = false;
|
let mut send_event = false;
|
||||||
|
|
||||||
if !mime_parser.message_kml.is_none() && chat_id > DC_CHAT_ID_LAST_SPECIAL as libc::c_uint {
|
info!(
|
||||||
|
context,
|
||||||
|
"saving locations chat_id={} insert_msg_id={}",
|
||||||
|
chat_id,
|
||||||
|
insert_msg_id.to_u32()
|
||||||
|
);
|
||||||
|
|
||||||
|
if mime_parser.message_kml.is_some() {
|
||||||
let locations = &mime_parser.message_kml.as_ref().unwrap().locations;
|
let locations = &mime_parser.message_kml.as_ref().unwrap().locations;
|
||||||
let newest_location_id =
|
let newest_location_id =
|
||||||
location::save(context, chat_id, from_id, locations, 1).unwrap_or_default();
|
location::save(context, chat_id, from_id, locations, 1).unwrap_or_default();
|
||||||
@@ -865,12 +865,10 @@ fn save_locations(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !mime_parser.location_kml.is_none() && chat_id > DC_CHAT_ID_LAST_SPECIAL as libc::c_uint {
|
if mime_parser.location_kml.is_some() {
|
||||||
if let Some(ref addr) = mime_parser.location_kml.as_ref().unwrap().addr {
|
if let Some(ref addr) = mime_parser.location_kml.as_ref().unwrap().addr {
|
||||||
if let Ok(contact) = Contact::get_by_id(context, from_id) {
|
if let Ok(contact) = Contact::get_by_id(context, from_id) {
|
||||||
if !contact.get_addr().is_empty()
|
if contact.get_addr().to_lowercase() == addr.to_lowercase() {
|
||||||
&& contact.get_addr().to_lowercase() == addr.to_lowercase()
|
|
||||||
{
|
|
||||||
let locations = &mime_parser.location_kml.as_ref().unwrap().locations;
|
let locations = &mime_parser.location_kml.as_ref().unwrap().locations;
|
||||||
let newest_location_id =
|
let newest_location_id =
|
||||||
location::save(context, chat_id, from_id, locations, 0).unwrap_or_default();
|
location::save(context, chat_id, from_id, locations, 0).unwrap_or_default();
|
||||||
|
|||||||
Reference in New Issue
Block a user