fix various location-streaming issue, test passes now

This commit is contained in:
holger krekel
2019-11-02 22:05:33 +01:00
parent d74c70a57c
commit d24a982757
4 changed files with 76 additions and 54 deletions

View File

@@ -417,7 +417,7 @@ class Chat(object):
class Location:
def __init__(self, latitude, longitude, accuracy, timestamp):
assert isinstance(timestamp, datetime.datetime)
assert isinstance(timestamp, datetime)
self.latitude = latitude
self.longitude = longitude
self.accuracy = accuracy

View File

@@ -827,17 +827,20 @@ class TestOnlineAccount:
lp.sec("ac1: enable location sending in chat")
chat1.enable_sending_locations(seconds=100)
assert chat1.is_sending_locations()
ac1._evlogger.get_matching("DC_EVENT_SMTP_MESSAGE_SENT")
lp.sec("ac1: setting location")
ac1.set_location(latitude=1.0, longitude=2.0)
ac1.set_location(latitude=2.0, longitude=3.0)
ac1._evlogger.get_matching("DC_EVENT_LOCATION_CHANGED")
chat1.send_text("hello")
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")
ac2._evlogger.get_matching("DC_EVENT_INCOMING_MSG")
ac2._evlogger.get_matching("DC_EVENT_INCOMING_MSG")
ac2._evlogger.get_matching("DC_EVENT_INCOMING_MSG") # "enabled-location streaming"
# 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"))
locations = chat2.get_locations() # XXX per contact
assert len(locations) >= 1

View File

@@ -598,7 +598,7 @@ impl<'a> MimeParser<'a> {
let mut decoded_data = match wrapmime::mailmime_transfer_decode(mime) {
Ok(decoded_data) => decoded_data,
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;
}
};
@@ -736,27 +736,13 @@ impl<'a> MimeParser<'a> {
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(
msg_type,
mime_type,
raw_mime.as_ref(),
&decoded_data,
&desired_filename,
);
}
self.do_add_single_file_part(
msg_type,
mime_type,
raw_mime.as_ref(),
&decoded_data,
&desired_filename,
);
}
_ => {}
}
@@ -770,20 +756,47 @@ impl<'a> MimeParser<'a> {
mime_type: libc::c_int,
raw_mime: Option<&String>,
decoded_data: &[u8],
desired_filename: &str,
filename: &str,
) {
/* write decoded data to new blob file */
let blob = match BlobObject::create(self.context, desired_filename, decoded_data) {
if decoded_data.is_empty() {
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,
Err(err) => {
error!(
self.context,
"Could not add blob for mime part {}, error {}", desired_filename, err
"Could not add blob for mime part {}, error {}", filename, err
);
return;
}
};
/* create and register Mime part referencing the new Blob object */
let mut part = Part::default();
part.typ = msg_type;
part.mimetype = mime_type;
@@ -803,10 +816,18 @@ impl<'a> MimeParser<'a> {
}
fn do_add_single_part(&mut self, mut part: Part) {
if self.encrypted && self.signatures.len() > 0 {
part.param.set_int(Param::GuaranteeE2ee, 1);
} else if self.encrypted {
part.param.set_int(Param::ErroneousE2ee, 0x2);
// 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);
} 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);
}
}
self.parts.push(part);
}

View File

@@ -227,7 +227,7 @@ pub unsafe fn dc_receive_imf(
&mut created_db_entries,
&mut create_event_to_send,
) {
info!(context, "{}", err);
warn!(context, "{}", err);
cleanup(
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(
context,
&mime_parser,
@@ -604,6 +604,7 @@ unsafe fn add_parts(
// into only one message; mails sent by other clients may result in several messages
// (eg. one per attachment))
let icnt = mime_parser.parts.len();
let mut txt_raw = None;
context.sql.prepare(
@@ -644,17 +645,6 @@ unsafe fn add_parts(
.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![
rfc724_mid,
server_folder.as_ref(),
@@ -850,10 +840,20 @@ fn save_locations(
insert_msg_id: MsgId,
hidden: i32,
) {
if chat_id <= DC_CHAT_ID_LAST_SPECIAL as libc::c_uint {
return ();
}
let mut location_id_written = 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 newest_location_id =
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 Ok(contact) = Contact::get_by_id(context, from_id) {
if !contact.get_addr().is_empty()
&& contact.get_addr().to_lowercase() == addr.to_lowercase()
{
if contact.get_addr().to_lowercase() == addr.to_lowercase() {
let locations = &mime_parser.location_kml.as_ref().unwrap().locations;
let newest_location_id =
location::save(context, chat_id, from_id, locations, 0).unwrap_or_default();