mirror of
https://github.com/YGGverse/aquatic-crawler.git
synced 2026-04-02 18:15:31 +00:00
show bytes as description, implement format bytes trait
This commit is contained in:
parent
d05b15c7a3
commit
f49ed0e11b
5 changed files with 66 additions and 13 deletions
24
src/format.rs
Normal file
24
src/format.rs
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
pub trait Format {
|
||||||
|
/// Format bytes to KB/MB/GB presentation
|
||||||
|
fn bytes(self) -> String;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Format for u64 {
|
||||||
|
fn bytes(self) -> String {
|
||||||
|
const KB: f32 = 1024.0;
|
||||||
|
const MB: f32 = KB * KB;
|
||||||
|
const GB: f32 = MB * KB;
|
||||||
|
|
||||||
|
let f = self as f32;
|
||||||
|
|
||||||
|
if f < KB {
|
||||||
|
format!("{self} B")
|
||||||
|
} else if f < MB {
|
||||||
|
format!("{:.2} KB", f / KB)
|
||||||
|
} else if f < GB {
|
||||||
|
format!("{:.2} MB", f / MB)
|
||||||
|
} else {
|
||||||
|
format!("{:.2} GB", f / GB)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
18
src/index.rs
18
src/index.rs
|
|
@ -12,14 +12,16 @@ pub struct Index {
|
||||||
is_changed: bool,
|
is_changed: bool,
|
||||||
/// Store the index value in memory only when it is in use by the init options
|
/// Store the index value in memory only when it is in use by the init options
|
||||||
has_name: bool,
|
has_name: bool,
|
||||||
|
has_length: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Index {
|
impl Index {
|
||||||
pub fn init(capacity: usize, has_name: bool) -> Self {
|
pub fn init(capacity: usize, has_name: bool, has_length: bool) -> Self {
|
||||||
Self {
|
Self {
|
||||||
index: HashMap::with_capacity(capacity),
|
index: HashMap::with_capacity(capacity),
|
||||||
is_changed: false,
|
is_changed: false,
|
||||||
has_name,
|
has_name,
|
||||||
|
has_length,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -43,12 +45,22 @@ impl Index {
|
||||||
self.index.values().map(|i| i.node).sum::<u64>()
|
self.index.values().map(|i| i.node).sum::<u64>()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert(&mut self, infohash: String, node: u64, name: Option<String>) {
|
pub fn insert(
|
||||||
|
&mut self,
|
||||||
|
infohash: String,
|
||||||
|
node: u64,
|
||||||
|
name: Option<String>,
|
||||||
|
length: Option<u64>,
|
||||||
|
) {
|
||||||
if self
|
if self
|
||||||
.index
|
.index
|
||||||
.insert(
|
.insert(
|
||||||
infohash,
|
infohash,
|
||||||
Value::new(node, if self.has_name { name } else { None }),
|
Value::new(
|
||||||
|
node,
|
||||||
|
if self.has_name { name } else { None },
|
||||||
|
if self.has_length { length } else { None },
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.is_none()
|
.is_none()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -6,16 +6,18 @@ const NAME_MAX_LEN: usize = 125; // + 3 bytes for `...` offset @TODO optional
|
||||||
pub struct Value {
|
pub struct Value {
|
||||||
pub time: DateTime<Utc>,
|
pub time: DateTime<Utc>,
|
||||||
pub node: u64,
|
pub node: u64,
|
||||||
/// Isolate by applying internal filter on value set
|
// Isolate by applying internal filter on value set
|
||||||
|
length: Option<u64>,
|
||||||
name: Option<String>,
|
name: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Value {
|
impl Value {
|
||||||
/// Create new `Self` with current timestamp
|
/// Create new `Self` with current timestamp
|
||||||
pub fn new(node: u64, name: Option<String>) -> Self {
|
pub fn new(node: u64, name: Option<String>, length: Option<u64>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
time: Utc::now(),
|
time: Utc::now(),
|
||||||
node,
|
node,
|
||||||
|
length,
|
||||||
name: filter_name(name),
|
name: filter_name(name),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -23,6 +25,10 @@ impl Value {
|
||||||
pub fn name(&self) -> Option<&String> {
|
pub fn name(&self) -> Option<&String> {
|
||||||
self.name.as_ref()
|
self.name.as_ref()
|
||||||
}
|
}
|
||||||
|
/// Get reference to the safely constructed `length` member
|
||||||
|
pub fn length(&self) -> Option<u64> {
|
||||||
|
self.length
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prevent unexpected memory usage on store values from unknown source
|
/// Prevent unexpected memory usage on store values from unknown source
|
||||||
|
|
|
||||||
23
src/main.rs
23
src/main.rs
|
|
@ -1,6 +1,7 @@
|
||||||
mod api;
|
mod api;
|
||||||
mod config;
|
mod config;
|
||||||
mod debug;
|
mod debug;
|
||||||
|
mod format;
|
||||||
mod index;
|
mod index;
|
||||||
mod peers;
|
mod peers;
|
||||||
mod preload;
|
mod preload;
|
||||||
|
|
@ -11,6 +12,7 @@ mod trackers;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use config::Config;
|
use config::Config;
|
||||||
use debug::Debug;
|
use debug::Debug;
|
||||||
|
use format::Format;
|
||||||
use index::Index;
|
use index::Index;
|
||||||
use peers::Peers;
|
use peers::Peers;
|
||||||
use rss::Rss;
|
use rss::Rss;
|
||||||
|
|
@ -73,7 +75,11 @@ async fn main() -> Result<()> {
|
||||||
|
|
||||||
// begin
|
// begin
|
||||||
debug.info("Crawler started");
|
debug.info("Crawler started");
|
||||||
let mut index = Index::init(config.index_capacity, config.export_rss.is_some());
|
let mut index = Index::init(
|
||||||
|
config.index_capacity,
|
||||||
|
config.export_rss.is_some(),
|
||||||
|
config.export_rss.is_some(),
|
||||||
|
);
|
||||||
loop {
|
loop {
|
||||||
debug.info("Index queue begin...");
|
debug.info("Index queue begin...");
|
||||||
index.refresh();
|
index.refresh();
|
||||||
|
|
@ -127,7 +133,7 @@ async fn main() -> Result<()> {
|
||||||
config.preload_max_filecount.unwrap_or_default(),
|
config.preload_max_filecount.unwrap_or_default(),
|
||||||
);
|
);
|
||||||
mt.wait_until_initialized().await?;
|
mt.wait_until_initialized().await?;
|
||||||
let name = mt.with_metadata(|m| {
|
let (name, length) = mt.with_metadata(|m| {
|
||||||
// init preload files list
|
// init preload files list
|
||||||
if let Some(ref p) = preload {
|
if let Some(ref p) = preload {
|
||||||
for (id, info) in m.file_infos.iter().enumerate() {
|
for (id, info) in m.file_infos.iter().enumerate() {
|
||||||
|
|
@ -160,7 +166,7 @@ async fn main() -> Result<()> {
|
||||||
if let Some(ref t) = torrent {
|
if let Some(ref t) = torrent {
|
||||||
save_torrent_file(t, &debug, &i, &m.torrent_bytes)
|
save_torrent_file(t, &debug, &i, &m.torrent_bytes)
|
||||||
}
|
}
|
||||||
m.info.name.as_ref().map(|n|n.to_string())
|
(m.info.name.as_ref().map(|n|n.to_string()), m.info.length)
|
||||||
})?;
|
})?;
|
||||||
session.update_only_files(&mt, &only_files).await?;
|
session.update_only_files(&mt, &only_files).await?;
|
||||||
session.unpause(&mt).await?;
|
session.unpause(&mt).await?;
|
||||||
|
|
@ -175,7 +181,7 @@ async fn main() -> Result<()> {
|
||||||
p.cleanup(&i, Some(only_files_keep))?
|
p.cleanup(&i, Some(only_files_keep))?
|
||||||
}
|
}
|
||||||
|
|
||||||
index.insert(i, only_files_size, name)
|
index.insert(i, only_files_size, name, length)
|
||||||
}
|
}
|
||||||
Ok(AddTorrentResponse::ListOnly(r)) => {
|
Ok(AddTorrentResponse::ListOnly(r)) => {
|
||||||
if let Some(ref t) = torrent {
|
if let Some(ref t) = torrent {
|
||||||
|
|
@ -186,7 +192,12 @@ async fn main() -> Result<()> {
|
||||||
// use `r.info` for Memory, SQLite,
|
// use `r.info` for Memory, SQLite,
|
||||||
// Manticore and other alternative storage type
|
// Manticore and other alternative storage type
|
||||||
|
|
||||||
index.insert(i, 0, r.info.name.map(|n| n.to_string()))
|
index.insert(
|
||||||
|
i,
|
||||||
|
0,
|
||||||
|
r.info.name.map(|n| n.to_string()),
|
||||||
|
r.info.length,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
// unexpected as should be deleted
|
// unexpected as should be deleted
|
||||||
Ok(AddTorrentResponse::AlreadyManaged(..)) => panic!(),
|
Ok(AddTorrentResponse::AlreadyManaged(..)) => panic!(),
|
||||||
|
|
@ -213,7 +224,7 @@ async fn main() -> Result<()> {
|
||||||
rss.push(
|
rss.push(
|
||||||
k,
|
k,
|
||||||
v.name().unwrap_or(k),
|
v.name().unwrap_or(k),
|
||||||
None, // @TODO
|
v.length().map(|l| l.bytes()),
|
||||||
Some(&v.time.to_rfc2822()),
|
Some(&v.time.to_rfc2822()),
|
||||||
)?
|
)?
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ impl Rss {
|
||||||
&mut self,
|
&mut self,
|
||||||
infohash: &str,
|
infohash: &str,
|
||||||
title: &str,
|
title: &str,
|
||||||
description: Option<&str>,
|
description: Option<String>,
|
||||||
pub_date: Option<&str>,
|
pub_date: Option<&str>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.file.write_all(
|
self.file.write_all(
|
||||||
|
|
@ -72,7 +72,7 @@ impl Rss {
|
||||||
)?;
|
)?;
|
||||||
if let Some(s) = description {
|
if let Some(s) = description {
|
||||||
self.file.write_all(b"<description>")?;
|
self.file.write_all(b"<description>")?;
|
||||||
self.file.write_all(escape(s).as_bytes())?;
|
self.file.write_all(escape(&s).as_bytes())?;
|
||||||
self.file.write_all(b"</description>")?
|
self.file.write_all(b"</description>")?
|
||||||
}
|
}
|
||||||
if let Some(s) = pub_date {
|
if let Some(s) = pub_date {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue