Allow for alts command on known bots or text.

This commit is contained in:
Syfaro 2020-01-13 17:39:42 -06:00
parent 2ab2b44160
commit 3c7a715791
3 changed files with 108 additions and 25 deletions

View File

@ -62,6 +62,7 @@ alternate-distance = · { $link } (distance of { $distance })
alternate-feedback = Finding alternate images is an experimental feature, please use the buttons below to let me know if it is working as expected.
alternate-feedback-y = Looking good
alternate-feedback-n = Not great :(
alternate-multiple-photo = I can only find alternates for a single photo, sorry.
# Error Messages
error-generic = Oh no, something went wrong! Please send a message to my creator { -creatorName } if you continue having issues.

View File

@ -455,6 +455,7 @@ impl MessageHandler {
let influx = self.influx.clone();
{
let mut sites = self.sites.lock().await;
let links = links.iter().map(|link| link.as_str()).collect();
utils::find_images(&inline.from, links, &mut sites, &mut |info| {
let influx = influx.clone();
let duration = info.duration;
@ -761,23 +762,73 @@ impl MessageHandler {
(message.message_id, message)
};
let photo = match message.photo.clone() {
Some(photo) if !photo.is_empty() => photo,
_ => {
completed.store(true, std::sync::atomic::Ordering::SeqCst);
self.send_generic_reply(&message, "source-no-photo").await;
return;
let bytes = match message.photo.clone() {
Some(photo) => {
let best_photo = utils::find_best_photo(&photo).unwrap();
match utils::download_by_id(&self.bot, &best_photo.file_id).await {
Ok(bytes) => bytes,
Err(e) => {
completed.store(true, std::sync::atomic::Ordering::SeqCst);
log::error!("Unable to download file: {:?}", e);
let tags = Some(vec![("command", "source".to_string())]);
self.report_error(&message, tags, || capture_fail(&e)).await;
return;
}
}
}
};
None => {
let mut links = vec![];
let best_photo = utils::find_best_photo(&photo).unwrap();
let bytes = match utils::download_by_id(&self.bot, &best_photo.file_id).await {
Ok(bytes) => bytes,
Err(e) => {
log::error!("Unable to download file: {:?}", e);
let tags = Some(vec![("command", "source".to_string())]);
self.report_error(&message, tags, || capture_fail(&e)).await;
return;
if let Some(bot_links) = utils::parse_known_bots(&message) {
log::trace!("is known bot, adding links");
links.extend(bot_links);
} else if let Some(text) = &message.text {
log::trace!("message had text, looking at links");
links.extend(
self.finder
.links(&text)
.map(|link| link.as_str().to_string()),
);
}
if links.is_empty() {
completed.store(true, std::sync::atomic::Ordering::SeqCst);
self.send_generic_reply(&message, "source-no-photo").await;
return;
} else if links.len() > 1 {
completed.store(true, std::sync::atomic::Ordering::SeqCst);
self.send_generic_reply(&message, "alternate-multiple-photo")
.await;
return;
}
let mut sites = self.sites.lock().await;
let links = links.iter().map(|link| link.as_str()).collect();
let mut link = None;
utils::find_images(
&message.from.clone().unwrap(),
links,
&mut sites,
&mut |info| {
link = info.results.into_iter().next();
},
)
.await;
match link {
Some(link) => reqwest::get(&link.url)
.await
.unwrap()
.bytes()
.await
.unwrap()
.to_vec(),
None => {
completed.store(true, std::sync::atomic::Ordering::SeqCst);
self.send_generic_reply(&message, "source-no-photo").await;
return;
}
}
}
};
@ -788,6 +839,7 @@ impl MessageHandler {
{
Ok(matches) => matches,
Err(e) => {
completed.store(true, std::sync::atomic::Ordering::SeqCst);
log::error!("Unable to find matches: {:?}", e);
let tags = Some(vec![("command", "source".to_string())]);
self.report_error(&message, tags, || capture_fail(&e)).await;
@ -796,6 +848,7 @@ impl MessageHandler {
};
if matches.is_empty() {
completed.store(true, std::sync::atomic::Ordering::SeqCst);
self.send_generic_reply(&message, "reverse-no-results")
.await;
return;
@ -998,6 +1051,7 @@ impl MessageHandler {
let missing = {
let mut sites = self.sites.lock().await;
let links = links.iter().map(|link| link.as_str()).collect();
utils::find_images(&from, links, &mut sites, &mut |info| {
results.extend(info.results);
})

View File

@ -1,4 +1,3 @@
use linkify::Link;
use sentry::integrations::failure::capture_fail;
use std::time::Instant;
@ -15,7 +14,7 @@ pub struct SiteCallback<'a> {
pub async fn find_images<'a, C>(
user: &telegram::User,
links: Vec<Link<'a>>,
links: Vec<&'a str>,
sites: &mut [BoxedSite],
callback: &mut C,
) -> Vec<&'a str>
@ -25,15 +24,13 @@ where
let mut missing = vec![];
'link: for link in links {
let link_str = link.as_str();
for site in sites.iter_mut() {
let start = Instant::now();
if site.url_supported(link_str).await {
log::debug!("Link {} supported by {}", link_str, site.name());
if site.url_supported(link).await {
log::debug!("Link {} supported by {}", link, site.name());
match site.get_images(user.id, link_str).await {
match site.get_images(user.id, link).await {
// Got results successfully and there were results
// Execute callback with site info and results
Ok(results) if results.is_some() => {
@ -41,7 +38,7 @@ where
log::debug!("Found images: {:?}", results);
callback(SiteCallback {
site: &site,
link: link_str,
link,
duration: start.elapsed().as_millis() as i64,
results,
});
@ -49,12 +46,12 @@ where
// Got results successfully and there were NO results
// Continue onto next link
Ok(_) => {
missing.push(link_str);
missing.push(link);
continue 'link;
}
// Got error while processing, report and move onto next link
Err(e) => {
missing.push(link_str);
missing.push(link);
log::warn!("Unable to get results: {:?}", e);
with_user_scope(
Some(user),
@ -215,3 +212,34 @@ pub fn build_alternate_response(bundle: Bundle, mut items: AlternateItems) -> (S
(s, used_hashes)
}
pub fn parse_known_bots(message: &telegram::Message) -> Option<Vec<String>> {
let from = if let Some(ref forward_from) = message.forward_from {
Some(forward_from)
} else {
message.from.as_ref()
};
let from = match &from {
Some(from) => from,
None => return None,
};
log::trace!("evaluating if known bot: {}", from.id);
match from.id {
// FAwatchbot
190_600_517 => {
let urls = match message.entities {
Some(ref entities) => entities.iter().filter_map(|entity| {
{ entity.url.as_ref().map(|url| url.to_string()) }
.filter(|url| url.contains("furaffinity.net/view/"))
}),
None => return None,
};
Some(urls.collect())
}
_ => None,
}
}