Commit f1fcb00d authored by Daniel Garcia Moreno's avatar Daniel Garcia Moreno

Merge branch 'alatiera/macros' into 'master'

Macro-pocalypse

See merge request World/fractal!230
parents 7ffc87fb 0e3248e3
......@@ -12,8 +12,8 @@ use backend::types::BKResponse;
use backend::types::Backend;
use util::json_q;
use util::dw_media;
use util::cache_path;
use util::media;
use types::Room;
use types::Protocol;
......@@ -117,7 +117,7 @@ pub fn room_search(bk: &Backend,
/* download the avatar */
if let Some(avatar) = r.avatar.clone() {
if let Ok(dest) = cache_path(&id) {
media!(&base.clone(), &avatar, Some(&dest)).unwrap_or_default();
media(&base.clone(), &avatar, Some(&dest)).unwrap_or_default();
}
}
rooms.push(r);
......
......@@ -5,19 +5,21 @@ use error::Error;
use backend::types::BKResponse;
use backend::types::Backend;
use util::dw_media;
use util::download_file;
use util::cache_dir_path;
use util::get_room_media_list;
use util::resolve_media_url;
use util::semaphore;
use util::thumb;
use util;
use types::Message;
pub fn get_thumb_async(bk: &Backend, media: String, tx: Sender<String>) -> Result<(), Error> {
let baseu = bk.get_base_url()?;
semaphore!(bk.limit_threads, {
match thumb!(&baseu, &media) {
semaphore(bk.limit_threads.clone(), move || {
match thumb(&baseu, &media) {
Ok(fname) => {
tx.send(fname).unwrap();
}
......@@ -33,8 +35,8 @@ pub fn get_thumb_async(bk: &Backend, media: String, tx: Sender<String>) -> Resul
pub fn get_media_async(bk: &Backend, media: String, tx: Sender<String>) -> Result<(), Error> {
let baseu = bk.get_base_url()?;
semaphore!(bk.limit_threads, {
match media!(&baseu, &media) {
semaphore(bk.limit_threads.clone(), move || {
match util::media(&baseu, &media, None) {
Ok(fname) => {
tx.send(fname).unwrap();
}
......@@ -56,7 +58,7 @@ pub fn get_media_list_async(bk: &Backend,
let baseu = bk.get_base_url()?;
let tk = bk.data.lock().unwrap().access_token.clone();
semaphore!(bk.limit_threads, {
semaphore(bk.limit_threads.clone(), move || {
match get_room_media_list(&baseu, tk, roomid.clone(),
globals::PAGE_LIMIT,
first_media_id, prev_batch) {
......@@ -77,7 +79,7 @@ pub fn get_media(bk: &Backend, media: String) -> Result<(), Error> {
let tx = bk.tx.clone();
thread::spawn(move || {
match media!(&baseu, &media) {
match util::media(&baseu, &media, None) {
Ok(fname) => {
tx.send(BKResponse::Media(fname)).unwrap();
}
......@@ -93,7 +95,7 @@ pub fn get_media(bk: &Backend, media: String) -> Result<(), Error> {
pub fn get_media_url(bk: &Backend, media: String, tx: Sender<String>) -> Result<(), Error> {
let baseu = bk.get_base_url()?;
semaphore!(bk.limit_threads, {
semaphore(bk.limit_threads.clone(), move || {
match resolve_media_url(&baseu, &media, false, 0, 0) {
Ok(uri) => {
tx.send(uri.to_string()).unwrap();
......
......@@ -6,7 +6,7 @@ use std::sync::mpsc::channel;
use std::sync::mpsc::RecvError;
use std::collections::HashMap;
use util::build_url;
use util::client_url;
use error::Error;
......@@ -66,7 +66,7 @@ impl Backend {
let mut params2 = params.to_vec();
params2.push(("access_token", tk.clone()));
client_url!(&base, path, params2)
client_url(&base, path, params2)
}
pub fn run(mut self) -> Sender<BKCommand> {
......
......@@ -12,11 +12,11 @@ use std::thread;
use error::Error;
use util::json_q;
use util::dw_media;
use util::get_initial_room_messages;
use util::build_url;
use util::{client_url, media_url};
use util::put_media;
use util;
use util::media;
use util::cache_path;
use backend::types::Backend;
......@@ -71,7 +71,7 @@ pub fn get_room_avatar(bk: &Backend, roomid: String) -> Result<(), Error> {
match r["url"].as_str() {
Some(u) => {
if let Ok(dest) = cache_path(&roomid) {
avatar = media!(&baseu, u, Some(&dest)).unwrap_or_default();
avatar = media(&baseu, u, Some(&dest)).unwrap_or_default();
} else {
avatar = String::from("");
}
......@@ -144,7 +144,7 @@ pub fn get_room_messages(bk: &Backend, roomid: String) -> Result<(), Error> {
}
fn parse_context(tx: Sender<BKResponse>, tk: String, baseu: Url, roomid: String, eid: String, limit: i32) -> Result<(), Error> {
let url = client_url!(&baseu, &format!("rooms/{}/context/{}", roomid, eid),
let url = client_url(&baseu, &format!("rooms/{}/context/{}", roomid, eid),
vec![("limit", format!("{}", limit)), ("access_token", tk.clone())])?;
get!(&url,
......@@ -341,7 +341,7 @@ pub fn set_room_avatar(bk: &Backend, roomid: String, avatar: String) -> Result<(
let baseu = bk.get_base_url()?;
let tk = bk.data.lock().unwrap().access_token.clone();
let params = vec![("access_token", tk.clone())];
let mediaurl = media_url!(&baseu, "upload", params)?;
let mediaurl = media_url(&baseu, "upload", params)?;
let roomurl = bk.url(&format!("rooms/{}/state/m.room.avatar", roomid), vec![])?;
let mut file = File::open(&avatar)?;
......@@ -388,7 +388,7 @@ pub fn attach_file(bk: &Backend, msg: Message) -> Result<(), Error> {
let baseu = bk.get_base_url()?;
let tk = bk.data.lock().unwrap().access_token.clone();
let params = vec![("access_token", tk.clone())];
let mediaurl = media_url!(&baseu, "upload", params)?;
let mediaurl = media_url(&baseu, "upload", params)?;
let mut m = msg.clone();
let tx = bk.tx.clone();
......
......@@ -6,7 +6,7 @@ use self::chrono::prelude::*;
use std::thread;
use util::json_q;
use util::build_url;
use util::{scalar_url, client_url};
use url::Url;
use std::sync::{Arc, Mutex};
use backend::BackendData;
......@@ -170,7 +170,7 @@ fn url(data: Arc<Mutex<BackendData>>, path: &str, params: Vec<(&str, String)>) -
let mut params2 = params.to_vec();
params2.push(("access_token", tk.clone()));
client_url!(&base, path, params2)
client_url(&base, path, params2)
}
fn get_scalar_token(data: Arc<Mutex<BackendData>>) -> Result<String, Error> {
......@@ -204,6 +204,6 @@ fn vurl(data: Arc<Mutex<BackendData>>, path: &str, params: Vec<(&str, String)>)
let mut params2 = params.to_vec();
params2.push(("scalar_token", tk));
scalar_url!(&base, path, params2)
scalar_url(&base, path, params2)
}
......@@ -11,12 +11,13 @@ use std::sync::{Arc, Mutex};
use std::sync::mpsc::Sender;
use error::Error;
use util::json_q;
use util::build_url;
use util::{build_url, media_url};
use util::put_media;
use util::get_user_avatar;
use util::get_user_avatar_img;
use backend::types::BKResponse;
use backend::types::Backend;
use util::semaphore;
use types::Member;
use types::UserInfo;
......@@ -321,7 +322,7 @@ pub fn get_user_info_async(bk: &mut Backend,
let cache_key = u.clone();
let cache_value = info.clone();
semaphore!(bk.limit_threads, {
semaphore(bk.limit_threads.clone(), move || {
let i0 = info.lock();
match get_user_avatar(&baseu, &u) {
Ok(info) => {
......@@ -375,7 +376,7 @@ pub fn get_avatar_async(bk: &Backend, member: Option<Member>, tx: Sender<String>
let uid = m.uid.clone();
let avatar = m.avatar.clone();
semaphore!(bk.limit_threads, {
semaphore(bk.limit_threads.clone(), move || {
match get_user_avatar_img(&baseu, uid,
avatar.unwrap_or_default()) {
Ok(fname) => { tx.send(fname.clone()).unwrap(); }
......@@ -391,7 +392,7 @@ pub fn set_user_avatar(bk: &Backend, avatar: String) -> Result<(), Error> {
let id = bk.data.lock().unwrap().user_id.clone();
let tk = bk.data.lock().unwrap().access_token.clone();
let params = vec![("access_token", tk.clone())];
let mediaurl = media_url!(&baseu, "upload", params)?;
let mediaurl = media_url(&baseu, "upload", params)?;
let url = bk.url(&format!("profile/{}/avatar_url", id), vec![])?;
let mut file = File::open(&avatar)?;
......
......@@ -20,6 +20,8 @@ use std::fs::create_dir_all;
use std::io::prelude::*;
use std::collections::HashSet;
use std::sync::{Mutex, Condvar, Arc};
use std::thread;
use std::time::Duration as StdDuration;
......@@ -33,33 +35,32 @@ use self::reqwest::header::CONTENT_TYPE;
use globals;
macro_rules! semaphore {
($cv: expr, $blk: block) => {{
let thread_count = $cv.clone();
thread::spawn(move || {
// waiting, less than 20 threads at the same time
// this is a semaphore
// TODO: use std::sync::Semaphore when it's on stable version
// https://doc.rust-lang.org/1.1.0/std/sync/struct.Semaphore.html
let &(ref num, ref cvar) = &*thread_count;
{
let mut start = num.lock().unwrap();
while *start >= 20 {
start = cvar.wait(start).unwrap()
}
*start += 1;
pub fn semaphore<F>(thread_count: Arc<(Mutex<u8>, Condvar)>, func: F)
where F: FnOnce() + Send + 'static
{
thread::spawn(move || {
// waiting, less than 20 threads at the same time
// this is a semaphore
// TODO: use std::sync::Semaphore when it's on stable version
// https://doc.rust-lang.org/1.1.0/std/sync/struct.Semaphore.html
let &(ref num, ref cvar) = &*thread_count;
{
let mut start = num.lock().unwrap();
while *start >= 20 {
start = cvar.wait(start).unwrap()
}
*start += 1;
}
$blk
func();
// freeing the cvar for new threads
{
let mut counter = num.lock().unwrap();
*counter -= 1;
}
cvar.notify_one();
});
}}
// freeing the cvar for new threads
{
let mut counter = num.lock().unwrap();
*counter -= 1;
}
cvar.notify_one();
});
}
// from https://stackoverflow.com/a/43992218/1592377
......@@ -81,27 +82,6 @@ macro_rules! clone {
);
}
#[macro_export]
macro_rules! client_url {
($b: expr, $path: expr, $params: expr) => (
build_url($b, &format!("/_matrix/client/r0/{}", $path), $params)
)
}
#[macro_export]
macro_rules! scalar_url {
($b: expr, $path: expr, $params: expr) => (
build_url($b, &format!("api/{}", $path), $params)
)
}
#[macro_export]
macro_rules! media_url {
($b: expr, $path: expr, $params: expr) => (
build_url($b, &format!("/_matrix/media/r0/{}", $path), $params)
)
}
#[macro_export]
macro_rules! derror {
($from: path, $to: path) => {
......@@ -173,29 +153,6 @@ macro_rules! query {
};
}
#[macro_export]
macro_rules! media {
($base: expr, $url: expr, $dest: expr) => {
dw_media($base, $url, false, $dest, 0, 0)
};
($base: expr, $url: expr) => {
dw_media($base, $url, false, None, 0, 0)
};
}
#[macro_export]
macro_rules! thumb {
($base: expr, $url: expr) => {
dw_media($base, $url, true, None, 64, 64)
};
($base: expr, $url: expr, $size: expr) => {
dw_media($base, $url, true, None, $size, $size)
};
($base: expr, $url: expr, $w: expr, $h: expr) => {
dw_media($base, $url, true, None, $w, $h)
};
}
pub fn evc(events: &JsonValue, t: &str, field: &str) -> String {
events
.as_array()
......@@ -459,7 +416,7 @@ pub fn get_prev_batch_from(baseu: &Url, tk: String, roomid: String, evid: String
];
let path = format!("rooms/{}/context/{}", roomid, evid);
let url = client_url!(baseu, &path, params)?;
let url = client_url(baseu, &path, params)?;
let r = json_q("get", &url, &json!(null), globals::TIMEOUT)?;
let prev_batch = r["start"].to_string().trim_matches('"').to_string();
......@@ -491,7 +448,7 @@ pub fn get_room_media_list(baseu: &Url,
};
let path = format!("rooms/{}/messages", roomid);
let url = client_url!(baseu, &path, params)?;
let url = client_url(baseu, &path, params)?;
let r = json_q("get", &url, &json!(null), globals::TIMEOUT)?;
let array = r["chunk"].as_array();
......@@ -557,7 +514,7 @@ pub fn resolve_media_url(
path = format!("download/{}/{}", server, media);
}
media_url!(base, &path, params)
media_url(base, &path, params)
}
pub fn dw_media(base: &Url,
......@@ -584,7 +541,7 @@ pub fn dw_media(base: &Url,
path = format!("download/{}/{}", server, media);
}
let url = media_url!(base, &path, params)?;
let url = media_url(base, &path, params)?;
let fname = match dest {
None if thumb => { cache_dir_path("thumbs", &media)? }
......@@ -595,6 +552,14 @@ pub fn dw_media(base: &Url,
download_file(url.as_str(), fname, dest)
}
pub fn media(base: &Url, url: &str, dest: Option<&str>) -> Result<String, Error> {
dw_media(base, url, false, dest, 0, 0)
}
pub fn thumb(base: &Url, url: &str)-> Result<String, Error> {
dw_media(base, url, true, None, 64, 64)
}
pub fn download_file(url: &str, fname: String, dest: Option<&str>) -> Result<String, Error> {
let pathname = fname.clone();
let p = Path::new(&pathname);
......@@ -665,7 +630,7 @@ pub fn json_q(method: &str, url: &Url, attrs: &JsonValue, timeout: u64) -> Resul
}
pub fn get_user_avatar(baseu: &Url, userid: &str) -> Result<(String, String), Error> {
let url = client_url!(baseu, &format!("profile/{}", userid), vec![])?;
let url = client_url(baseu, &format!("profile/{}", userid), vec![])?;
let attrs = json!(null);
match json_q("get", &url, &attrs, globals::TIMEOUT) {
......@@ -690,7 +655,7 @@ pub fn get_user_avatar(baseu: &Url, userid: &str) -> Result<(String, String), Er
}
pub fn get_room_st(base: &Url, tk: &str, roomid: &str) -> Result<JsonValue, Error> {
let url = client_url!(base, &format!("rooms/{}/state", roomid), vec![("access_token", String::from(tk))])?;
let url = client_url(base, &format!("rooms/{}/state", roomid), vec![("access_token", String::from(tk))])?;
let attrs = json!(null);
let st = json_q("get", &url, &attrs, globals::TIMEOUT)?;
......@@ -717,7 +682,7 @@ pub fn get_room_avatar(base: &Url, tk: &str, userid: &str, roomid: &str) -> Resu
let mut fname = match members.count() {
1 => {
if let Ok(dest) = cache_path(&roomid) {
media!(&base, m1, Some(&dest)).unwrap_or_default()
media(&base, m1, Some(&dest)).unwrap_or_default()
} else {
String::new()
}
......@@ -823,7 +788,7 @@ pub fn get_initial_room_messages(baseu: &Url,
};
let path = format!("rooms/{}/messages", roomid);
let url = client_url!(baseu, &path, params)?;
let url = client_url(baseu, &path, params)?;
let r = json_q("get", &url, &json!(null), globals::TIMEOUT)?;
nend = String::from(r["end"].as_str().unwrap_or(""));
......@@ -873,7 +838,7 @@ pub fn fill_room_gap(baseu: &Url,
params.push(("to", to.clone()));
let path = format!("rooms/{}/messages", roomid);
let url = client_url!(baseu, &path, params)?;
let url = client_url(baseu, &path, params)?;
let r = json_q("get", &url, &json!(null), globals::TIMEOUT)?;
nend = String::from(r["end"].as_str().unwrap_or(""));
......@@ -913,6 +878,18 @@ pub fn build_url(base: &Url, path: &str, params: Vec<(&str, String)>) -> Result<
Ok(url)
}
pub fn client_url(base: &Url, path: &str, params: Vec<(&str, String)>) -> Result<Url, Error> {
build_url(base, &format!("/_matrix/client/r0/{}", path), params)
}
pub fn scalar_url(base: &Url, path: &str, params: Vec<(&str, String)>) -> Result<Url, Error> {
build_url(base, &format!("api/{}", path), params)
}
pub fn media_url(base: &Url, path: &str, params: Vec<(&str, String)>) -> Result<Url, Error> {
build_url(base, &format!("/_matrix/media/r0/{}", path), params)
}
pub fn cache_path(name: &str) -> Result<String, Error> {
let mut path = match glib::get_user_cache_dir() {
Some(path) => path,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment