Deploying to gh-pages from @ 8830961e04 🚀

This commit is contained in:
realaravinth
2021-07-25 15:50:05 +00:00
parent ce2f623ec1
commit 987534a0dc
85 changed files with 1268 additions and 251 deletions

View File

@@ -153,41 +153,103 @@
<span id="150">150</span>
<span id="151">151</span>
<span id="152">152</span>
<span id="153">153</span>
<span id="154">154</span>
<span id="155">155</span>
<span id="156">156</span>
<span id="157">157</span>
<span id="158">158</span>
<span id="159">159</span>
<span id="160">160</span>
<span id="161">161</span>
<span id="162">162</span>
<span id="163">163</span>
<span id="164">164</span>
<span id="165">165</span>
<span id="166">166</span>
<span id="167">167</span>
<span id="168">168</span>
<span id="169">169</span>
<span id="170">170</span>
<span id="171">171</span>
<span id="172">172</span>
<span id="173">173</span>
<span id="174">174</span>
<span id="175">175</span>
<span id="176">176</span>
<span id="177">177</span>
<span id="178">178</span>
<span id="179">179</span>
<span id="180">180</span>
<span id="181">181</span>
<span id="182">182</span>
<span id="183">183</span>
<span id="184">184</span>
<span id="185">185</span>
<span id="186">186</span>
<span id="187">187</span>
<span id="188">188</span>
<span id="189">189</span>
<span id="190">190</span>
<span id="191">191</span>
</pre><div class="example-wrap"><pre class="rust ">
<span class="comment">/*
* Copyright (C) 2021 Aravinth Manivannan &lt;realaravinth@batsense.net&gt;
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see &lt;https://www.gnu.org/licenses/&gt;.
*/</span>
* Copyright (C) 2021 Aravinth Manivannan &lt;realaravinth@batsense.net&gt;
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see &lt;https://www.gnu.org/licenses/&gt;.
*/</span>
<span class="kw">use</span> <span class="ident">actix_web</span>::{<span class="ident">web</span>, <span class="ident">HttpResponse</span>, <span class="ident">Responder</span>};
<span class="kw">use</span> <span class="ident">serde</span>::{<span class="ident">Deserialize</span>, <span class="ident">Serialize</span>};
<span class="kw">use</span> <span class="ident">sqlx::PgPool</span>;
<span class="kw">use</span> <span class="kw">crate</span><span class="ident">::date::Date</span>;
<span class="kw">use</span> <span class="kw">crate</span><span class="ident">::errors</span>::<span class="kw-2">*</span>;
<span class="kw">use</span> <span class="kw">crate</span><span class="ident">::AppData</span>;
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Clone</span>, <span class="ident">Deserialize</span>, <span class="ident">Serialize</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">Stats</span> {
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">StatsUnixTimestamp</span> {
<span class="kw">pub</span> <span class="ident">config_fetches</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">i64</span><span class="op">&gt;</span>,
<span class="kw">pub</span> <span class="ident">solves</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">i64</span><span class="op">&gt;</span>,
<span class="kw">pub</span> <span class="ident">confirms</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">i64</span><span class="op">&gt;</span>,
}
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">Stats</span> {
<span class="kw">pub</span> <span class="ident">config_fetches</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">Date</span><span class="op">&gt;</span>,
<span class="kw">pub</span> <span class="ident">solves</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">Date</span><span class="op">&gt;</span>,
<span class="kw">pub</span> <span class="ident">confirms</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">Date</span><span class="op">&gt;</span>,
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Clone</span>, <span class="ident">Deserialize</span>, <span class="ident">Serialize</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">StatsPayload</span> {
<span class="kw">pub</span> <span class="ident">key</span>: <span class="ident">String</span>,
}
<span class="attribute">#[<span class="ident">my_codegen::post</span>(<span class="ident">path</span> <span class="op">=</span> <span class="string">&quot;crate::V1_API_ROUTES.auth.login&quot;</span>, <span class="ident">wrap</span> <span class="op">=</span> <span class="string">&quot;crate::CheckLogin&quot;</span>)]</span>
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">get_stats</span>(
<span class="ident">payload</span>: <span class="ident">web::Json</span><span class="op">&lt;</span><span class="ident">StatsPayload</span><span class="op">&gt;</span>,
<span class="ident">data</span>: <span class="ident">AppData</span>,
) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">ServiceResult</span><span class="op">&lt;</span><span class="kw">impl</span> <span class="ident">Responder</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">stats</span> <span class="op">=</span> <span class="ident">Stats::new</span>(<span class="kw-2">&amp;</span><span class="ident">payload</span>.<span class="ident">key</span>, <span class="kw-2">&amp;</span><span class="ident">data</span>.<span class="ident">db</span>).<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let</span> <span class="ident">stats</span> <span class="op">=</span> <span class="ident">StatsUnixTimestamp::from_stats</span>(<span class="kw-2">&amp;</span><span class="ident">stats</span>);
<span class="prelude-val">Ok</span>(<span class="ident">HttpResponse::Ok</span>().<span class="ident">json</span>(<span class="kw-2">&amp;</span><span class="ident">stats</span>))
}
<span class="kw">impl</span> <span class="ident">Stats</span> {
<span class="kw">pub</span> <span class="kw">async</span> <span class="kw">fn</span> <span class="ident">new</span>(<span class="ident">key</span>: <span class="kw-2">&amp;</span><span class="ident">str</span>, <span class="ident">db</span>: <span class="kw-2">&amp;</span><span class="ident">PgPool</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">ServiceResult</span><span class="op">&lt;</span><span class="self">Self</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">config_fetches_fut</span> <span class="op">=</span> <span class="self">Self</span><span class="ident">::fetch_config_fetched</span>(<span class="ident">key</span>, <span class="ident">db</span>);
<span class="kw">let</span> <span class="ident">solves_fut</span> <span class="op">=</span> <span class="self">Self</span><span class="ident">::fetch_solve</span>(<span class="ident">key</span>, <span class="ident">db</span>);
<span class="kw">let</span> <span class="ident">confirms_fut</span> <span class="op">=</span> <span class="self">Self</span><span class="ident">::fetch_confirm</span>(<span class="ident">key</span>, <span class="ident">db</span>);
<span class="kw">let</span> <span class="ident">config_fetches_fut</span> <span class="op">=</span> <span class="ident">runners::fetch_config_fetched</span>(<span class="ident">key</span>, <span class="ident">db</span>);
<span class="kw">let</span> <span class="ident">solves_fut</span> <span class="op">=</span> <span class="ident">runners::fetch_solve</span>(<span class="ident">key</span>, <span class="ident">db</span>);
<span class="kw">let</span> <span class="ident">confirms_fut</span> <span class="op">=</span> <span class="ident">runners::fetch_confirm</span>(<span class="ident">key</span>, <span class="ident">db</span>);
<span class="kw">let</span> (<span class="ident">config_fetches</span>, <span class="ident">solves</span>, <span class="ident">confirms</span>) <span class="op">=</span>
<span class="macro">futures::try_join!</span>(<span class="ident">config_fetches_fut</span>, <span class="ident">solves_fut</span>, <span class="ident">confirms_fut</span>)<span class="question-mark">?</span>;
@@ -200,70 +262,81 @@
<span class="prelude-val">Ok</span>(<span class="ident">res</span>)
}
}
<span class="kw">impl</span> <span class="ident">StatsUnixTimestamp</span> {
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">from_stats</span>(<span class="ident">stats</span>: <span class="kw-2">&amp;</span><span class="ident">Stats</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="self">Self</span> {
<span class="kw">let</span> <span class="ident">config_fetches</span> <span class="op">=</span> <span class="self">Self</span><span class="ident">::unix_timestamp</span>(<span class="kw-2">&amp;</span><span class="ident">stats</span>.<span class="ident">config_fetches</span>);
<span class="kw">let</span> <span class="ident">solves</span> <span class="op">=</span> <span class="self">Self</span><span class="ident">::unix_timestamp</span>(<span class="kw-2">&amp;</span><span class="ident">stats</span>.<span class="ident">solves</span>);
<span class="kw">let</span> <span class="ident">confirms</span> <span class="op">=</span> <span class="self">Self</span><span class="ident">::unix_timestamp</span>(<span class="kw-2">&amp;</span><span class="ident">stats</span>.<span class="ident">confirms</span>);
<span class="self">Self</span> {
<span class="ident">config_fetches</span>,
<span class="ident">solves</span>,
<span class="ident">confirms</span>,
}
}
<span class="doccomment">/// featch PoWConfig confirms</span>
<span class="attribute">#[<span class="ident">inline</span>]</span>
<span class="kw">fn</span> <span class="ident">unix_timestamp</span>(<span class="ident">dates</span>: <span class="kw-2">&amp;</span><span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">Date</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">i64</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">res</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">i64</span><span class="op">&gt;</span> <span class="op">=</span> <span class="ident">Vec::with_capacity</span>(<span class="ident">dates</span>.<span class="ident">len</span>());
<span class="ident">dates</span>
.<span class="ident">iter</span>()
.<span class="ident">for_each</span>(<span class="op">|</span><span class="ident">record</span><span class="op">|</span> <span class="ident">res</span>.<span class="ident">push</span>(<span class="ident">record</span>.<span class="ident">time</span>.<span class="ident">unix_timestamp</span>()));
<span class="ident">res</span>
}
}
<span class="kw">pub</span> <span class="kw">mod</span> <span class="ident">runners</span> {
<span class="kw">use</span> <span class="kw">super</span>::<span class="kw-2">*</span>;
<span class="doccomment">/// featch PoWConfig fetches</span>
<span class="attribute">#[<span class="ident">inline</span>]</span>
<span class="kw">pub</span> <span class="kw">async</span> <span class="kw">fn</span> <span class="ident">fetch_config_fetched</span>(
<span class="ident">key</span>: <span class="kw-2">&amp;</span><span class="ident">str</span>,
<span class="ident">db</span>: <span class="kw-2">&amp;</span><span class="ident">PgPool</span>,
) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">ServiceResult</span><span class="op">&lt;</span><span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">i64</span><span class="op">&gt;</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">records</span> <span class="op">=</span> <span class="macro">sqlx::query!</span>(
<span class="string">&quot;SELECT fetched_at FROM mcaptcha_pow_fetched_stats WHERE config_id =
) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">ServiceResult</span><span class="op">&lt;</span><span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">Date</span><span class="op">&gt;</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">records</span> <span class="op">=</span> <span class="macro">sqlx::query_as!</span>(
<span class="ident">Date</span>,
<span class="string">&quot;SELECT time FROM mcaptcha_pow_fetched_stats WHERE config_id =
(SELECT config_id FROM mcaptcha_config where key = $1)&quot;</span>,
<span class="kw-2">&amp;</span><span class="ident">key</span>,
)
.<span class="ident">fetch_all</span>(<span class="ident">db</span>)
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">res</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">i64</span><span class="op">&gt;</span> <span class="op">=</span> <span class="ident">Vec::with_capacity</span>(<span class="ident">records</span>.<span class="ident">len</span>());
<span class="ident">records</span>
.<span class="ident">iter</span>()
.<span class="ident">for_each</span>(<span class="op">|</span><span class="ident">record</span><span class="op">|</span> <span class="ident">res</span>.<span class="ident">push</span>(<span class="ident">record</span>.<span class="ident">fetched_at</span>.<span class="ident">unix_timestamp</span>()));
<span class="prelude-val">Ok</span>(<span class="ident">res</span>)
<span class="prelude-val">Ok</span>(<span class="ident">records</span>)
}
<span class="doccomment">/// featch PoWConfig solves</span>
<span class="attribute">#[<span class="ident">inline</span>]</span>
<span class="kw">pub</span> <span class="kw">async</span> <span class="kw">fn</span> <span class="ident">fetch_solve</span>(<span class="ident">key</span>: <span class="kw-2">&amp;</span><span class="ident">str</span>, <span class="ident">db</span>: <span class="kw-2">&amp;</span><span class="ident">PgPool</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">ServiceResult</span><span class="op">&lt;</span><span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">i64</span><span class="op">&gt;</span><span class="op">&gt;</span> {
<span class="comment">// &quot;SELECT solved_at FROM mcaptcha_pow_solved_stats WHERE config_id =</span>
<span class="comment">// (SELECT config_id FROM mcaptcha_config where key = $1)&quot;</span>
<span class="kw">let</span> <span class="ident">records</span> <span class="op">=</span> <span class="macro">sqlx::query!</span>(
<span class="string">&quot;SELECT solved_at FROM mcaptcha_pow_solved_stats WHERE config_id =
<span class="kw">pub</span> <span class="kw">async</span> <span class="kw">fn</span> <span class="ident">fetch_solve</span>(<span class="ident">key</span>: <span class="kw-2">&amp;</span><span class="ident">str</span>, <span class="ident">db</span>: <span class="kw-2">&amp;</span><span class="ident">PgPool</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">ServiceResult</span><span class="op">&lt;</span><span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">Date</span><span class="op">&gt;</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">records</span> <span class="op">=</span> <span class="macro">sqlx::query_as!</span>(
<span class="ident">Date</span>,
<span class="string">&quot;SELECT time FROM mcaptcha_pow_solved_stats WHERE config_id =
(SELECT config_id FROM mcaptcha_config where key = $1)&quot;</span>,
<span class="kw-2">&amp;</span><span class="ident">key</span>,
)
.<span class="ident">fetch_all</span>(<span class="ident">db</span>)
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">res</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">i64</span><span class="op">&gt;</span> <span class="op">=</span> <span class="ident">Vec::with_capacity</span>(<span class="ident">records</span>.<span class="ident">len</span>());
<span class="ident">records</span>
.<span class="ident">iter</span>()
.<span class="ident">for_each</span>(<span class="op">|</span><span class="ident">record</span><span class="op">|</span> <span class="ident">res</span>.<span class="ident">push</span>(<span class="ident">record</span>.<span class="ident">solved_at</span>.<span class="ident">unix_timestamp</span>()));
<span class="prelude-val">Ok</span>(<span class="ident">res</span>)
<span class="prelude-val">Ok</span>(<span class="ident">records</span>)
}
<span class="doccomment">/// featch PoWConfig confirms</span>
<span class="attribute">#[<span class="ident">inline</span>]</span>
<span class="kw">pub</span> <span class="kw">async</span> <span class="kw">fn</span> <span class="ident">fetch_confirm</span>(<span class="ident">key</span>: <span class="kw-2">&amp;</span><span class="ident">str</span>, <span class="ident">db</span>: <span class="kw-2">&amp;</span><span class="ident">PgPool</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">ServiceResult</span><span class="op">&lt;</span><span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">i64</span><span class="op">&gt;</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">records</span> <span class="op">=</span> <span class="macro">sqlx::query!</span>(
<span class="string">&quot;SELECT confirmed_at FROM mcaptcha_pow_confirmed_stats WHERE config_id = (
<span class="kw">pub</span> <span class="kw">async</span> <span class="kw">fn</span> <span class="ident">fetch_confirm</span>(<span class="ident">key</span>: <span class="kw-2">&amp;</span><span class="ident">str</span>, <span class="ident">db</span>: <span class="kw-2">&amp;</span><span class="ident">PgPool</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">ServiceResult</span><span class="op">&lt;</span><span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">Date</span><span class="op">&gt;</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">records</span> <span class="op">=</span> <span class="macro">sqlx::query_as!</span>(
<span class="ident">Date</span>,
<span class="string">&quot;SELECT time FROM mcaptcha_pow_confirmed_stats WHERE config_id = (
SELECT config_id FROM mcaptcha_config where key = $1)&quot;</span>,
<span class="kw-2">&amp;</span><span class="ident">key</span>
)
.<span class="ident">fetch_all</span>(<span class="ident">db</span>)
.<span class="kw">await</span><span class="question-mark">?</span>;
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">res</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">i64</span><span class="op">&gt;</span> <span class="op">=</span> <span class="ident">Vec::with_capacity</span>(<span class="ident">records</span>.<span class="ident">len</span>());
<span class="ident">records</span>
.<span class="ident">iter</span>()
.<span class="ident">for_each</span>(<span class="op">|</span><span class="ident">record</span><span class="op">|</span> <span class="ident">res</span>.<span class="ident">push</span>(<span class="ident">record</span>.<span class="ident">confirmed_at</span>.<span class="ident">unix_timestamp</span>()));
<span class="prelude-val">Ok</span>(<span class="ident">res</span>)
<span class="prelude-val">Ok</span>(<span class="ident">records</span>)
}
}
@@ -304,6 +377,11 @@
<span class="macro">assert_eq!</span>(<span class="ident">stats</span>.<span class="ident">config_fetches</span>.<span class="ident">len</span>(), <span class="number">1</span>);
<span class="macro">assert_eq!</span>(<span class="ident">stats</span>.<span class="ident">solves</span>.<span class="ident">len</span>(), <span class="number">1</span>);
<span class="macro">assert_eq!</span>(<span class="ident">stats</span>.<span class="ident">confirms</span>.<span class="ident">len</span>(), <span class="number">1</span>);
<span class="kw">let</span> <span class="ident">ustats</span> <span class="op">=</span> <span class="ident">StatsUnixTimestamp::from_stats</span>(<span class="kw-2">&amp;</span><span class="ident">stats</span>);
<span class="macro">assert_eq!</span>(<span class="ident">ustats</span>.<span class="ident">config_fetches</span>.<span class="ident">len</span>(), <span class="number">1</span>);
<span class="macro">assert_eq!</span>(<span class="ident">ustats</span>.<span class="ident">solves</span>.<span class="ident">len</span>(), <span class="number">1</span>);
<span class="macro">assert_eq!</span>(<span class="ident">ustats</span>.<span class="ident">confirms</span>.<span class="ident">len</span>(), <span class="number">1</span>);
}
}
</pre></div>