Skip to content

Instantly share code, notes, and snippets.

@tadyjp
Last active August 20, 2017 12:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tadyjp/8facfcffbd94f47ef191696559c2ca0a to your computer and use it in GitHub Desktop.
Save tadyjp/8facfcffbd94f47ef191696559c2ca0a to your computer and use it in GitHub Desktop.
RustでFREETELのギガ数を取得してInfluxDBにいれてGrafanaで見るまで ~ Dockerに添えて ~ ref: http://qiita.com/tady/items/b58a1e469e73268d0716
version: "2"
services:
rust:
build: .
volumes:
- "./mount/rust:/opt/rust"
influxdb:
image: influxdb
ports:
- "8083:8083"
- "8086:8086"
volumes:
- "./mount/influxdb:/var/lib/influxdb"
grafana:
image: grafana/grafana
ports:
- "3000:3000"
volumes:
- "./mount/grafana:/var/lib/grafana"
FROM rust:1.19.0
RUN apt-get update && apt-get install -y pkg-config libssl-dev
RUN mkdir -p /opt/rust
WORKDIR /opt/rust
CMD ["sh", "-c", "tail -f /dev/null"]
$ docker -v
Docker version 17.07.0-ce-rc2, build 36ce605
$ docker-compose -v
docker-compose version 1.15.0, build e12f3b9
$ docker-compose exec rust env FREETEL_EMAIL=<メールアドレス> FREETEL_PASSWORD=<パスワード> FREETEL_TEL=<ハイフン無し電話番号> cargo run
let email = env::var("FREETEL_EMAIL").expect("env 'FREETEL_EMAIL' not found");message...
use select::document::Document;
use select::predicate::{Predicate, Attr, Class};
use regex::Regex;
let re_usage = Regex::new(r"([\d\.]+)GB").unwrap();
let mut current_usage: f32 = 0.0;
let mut usage_limit: f32 = 0.0;
let document = Document::from(html);
for node in document.find(Class("sim-usage").descendant((Attr("style", "font-size: x-large;")))).take(1) {
let text = node.text();
let caps = re_usage.captures(&text).unwrap();
current_usage = caps.get(1).unwrap().as_str().parse::<f32>().unwrap();
}
for node in document.find(Class("sim-usage").descendant((Attr("style", "font-size: smaller;")))).take(1) {
let text = node.text();
let caps = re_usage.captures(&text).unwrap();
usage_limit = caps.get(1).unwrap().as_str().parse::<f32>().unwrap();
}
(current_usage, usage_limit)
$ curl -i -XPOST 'http://INFLUXDB_URL' --data 'freetel_usage value=0.64 1503063534888000000'
let timespec = time::get_time();
let current_time_nano = [timespec.sec.to_string(), format!("{:09}", timespec.nsec.to_string())].join("");
let data = [
format!("freetel_usage value={} {}", current_usage, current_time_nano),
format!("freetel_limit value={} {}", usage_limit, current_time_nano)
].join("\n");
let client = reqwest::Client::new().unwrap();
let resp = client.post(INFLUXDB_URL).unwrap()
.body(data.clone())
.send().unwrap();
println!("resp: {:?}", resp);
if !resp.status().is_success() {
panic!("influxdb request failed! {}, {:?}, {:?}", INFLUXDB_URL, resp.status(), data);
}
$ docker-compose build
$ docker-compose start
Starting influxdb ... done
Starting rust ... done
Starting grafana ... done
$ docker-compose ps
Name Command State Ports
------------------------------------------------------------------------------------------------------------
foo_grafana_1 /run.sh Up 0.0.0.0:3000->3000/tcp
foo_influxdb_1 /entrypoint.sh influxd Up 0.0.0.0:8083->8083/tcp, 0.0.0.0:8086->8086/tcp
foo_rust_1 sh -c tail -f /dev/null Up
docker-compose exec rust cargo run
// GET
let client = reqwest::Client::new().unwrap();
let mut resp = client.get("http://example.com/").unwrap()
.header(...) // hedderの付与
.send().unwrap();
let mut content = String::new(); // レスポンスの入れ物
resp.read_to_string(&mut content).unwrap();
// POST
let client = reqwest::Client::builder().unwrap()
.redirect(...) // カスタムリダイレクトポリシーの設定
.build().unwrap();
let params = [
("key", "value")
];
// HTTP Post リクエスト実行
let resp = client.post(LOGIN_FORM_URL).unwrap()
.header(...) // hedderの付与
.form(&params).unwrap() // formデータの付与
.send().unwrap();
resp.status() // スレータスの取得
resp.headers() // レスポンスヘッダの取得
// カスタムリダイレクトポリシー
// ログインリクエスト後に別のページに遷移するのを防ぐため `stop()` する
let custom = RedirectPolicy::custom(|attempt| {
// attempt.url() //=> リダイレクトしようとしている次のURL
// attempt.previous() //=> リダイレクトしてきた過去のURLの配列
attempt.stop()
});
let client = reqwest::Client::builder().unwrap()
.redirect(custom)
.build().unwrap();
if let Some(set_cookies) = resp.headers().get::<header::SetCookie>() {
let mut set_cookie_value = String::new();
for set_cookie in &set_cookies.0 {
let c = Cookie::parse(set_cookie.clone()).expect("Failed to parse cookie.");
let (name, value) = c.name_value();
if name == SESSION_COOKIE_NAME {
set_cookie_value = value.to_string();
}
}
if set_cookie_value != "" {
return set_cookie_value;
}
panic!("Set-Cookie '{}' does not exist!, Set-Cookies: {:?}", SESSION_COOKIE_NAME, set_cookies);
} else {
panic!("Set-Cookie '{}' does not exist!", SESSION_COOKIE_NAME);
}
[package]
name = "freetel_usage"
version = "0.0.1"
authors = [ "tady <a.dat.jp@gmail.com>" ]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment