use std::{
env,
fs::{File, *},
io::{copy, Cursor},
path::{Path, PathBuf},
time::Duration,
};
use zip::read::ZipArchive;
pub mod company_house;
pub mod karate_club;
pub mod lotr_graph;
pub mod neo4j_examples;
pub mod reddit_hyperlinks;
pub mod stable_coins;
pub mod sx_superuser_graph;
pub fn fetch_file(
name: &str,
tmp_save: bool,
url: &str,
timeout: u64,
) -> Result<PathBuf, Box<dyn std::error::Error>> {
let filepath = if tmp_save {
let tmp_dir = env::temp_dir();
tmp_dir.join(name)
} else {
PathBuf::from(name)
};
if !filepath.exists() {
let client = reqwest::blocking::Client::builder()
.timeout(Duration::from_secs(timeout))
.build()?;
let response = client.get(url).send()?.error_for_status()?;
let mut content = Cursor::new(response.bytes()?);
if !filepath.exists() {
let mut file = File::create(&filepath)?;
copy(&mut content, &mut file)?;
}
}
Ok(filepath)
}
fn unzip_file(zip_file_path: &str, destination_path: &str) -> std::io::Result<()> {
let file = File::open(zip_file_path)?;
let mut archive = ZipArchive::new(file)?;
for i in 0..archive.len() {
let mut file = archive.by_index(i)?;
let file_path = file.name();
let dest_path = format!("{}/{}", destination_path, file_path);
if file.is_dir() {
create_dir_all(&dest_path)?;
} else {
if let Some(parent) = Path::new(&dest_path).parent() {
if !parent.exists() {
create_dir_all(parent)?;
}
}
let mut output_file = File::create(&dest_path)?;
std::io::copy(&mut file, &mut output_file)?;
}
}
Ok(())
}
#[cfg(test)]
mod graph_loader_test {
use crate::{graph_loader::fetch_file, prelude::*};
use csv::StringRecord;
use raphtory_api::core::utils::logging::global_info_logger;
#[test]
fn test_fetch_file() {
let path = fetch_file(
"lotr2.csv",
true,
"https://raw.githubusercontent.com/Raphtory/Data/main/lotr_test.csv",
600,
);
assert!(path.is_ok());
}
#[test]
fn test_lotr_load_graph() {
let g = crate::graph_loader::lotr_graph::lotr_graph();
assert_eq!(g.count_edges(), 701);
}
#[test]
fn test_graph_at() {
let g = crate::graph_loader::lotr_graph::lotr_graph();
let g_at_empty = g.at(1);
let g_astart = g.at(7059);
let g_at_another = g.at(28373);
assert_eq!(g_at_empty.count_nodes(), 0);
assert_eq!(g_astart.count_nodes(), 3);
assert_eq!(g_at_another.count_nodes(), 4);
}
#[test]
fn test_karate_graph() {
let g = crate::graph_loader::karate_club::karate_club_graph();
assert_eq!(g.count_nodes(), 34);
assert_eq!(g.count_edges(), 155);
}
#[test]
fn db_lotr() {
let g = Graph::new();
let data_dir =
crate::graph_loader::lotr_graph::lotr_file().expect("Failed to get lotr.csv file");
fn parse_record(rec: &StringRecord) -> Option<(String, String, i64)> {
let src = rec.get(0).and_then(|s| s.parse::<String>().ok())?;
let dst = rec.get(1).and_then(|s| s.parse::<String>().ok())?;
let t = rec.get(2).and_then(|s| s.parse::<i64>().ok())?;
Some((src, dst, t))
}
if let Ok(mut reader) = csv::Reader::from_path(data_dir) {
for rec in reader.records().flatten() {
if let Some((src, dst, t)) = parse_record(&rec) {
let src_id = src.id();
let dst_id = dst.id();
g.add_node(t, src_id, [("name", Prop::str("Character"))], None)
.unwrap();
g.add_node(t, dst_id, [("name", Prop::str("Character"))], None)
.unwrap();
g.add_edge(
t,
src_id,
dst_id,
[("name", Prop::str("Character Co-occurrence"))],
None,
)
.unwrap();
}
}
}
let gandalf = "Gandalf".id();
assert!(g.has_node(gandalf));
assert!(g.has_node("Gandalf"))
}
#[test]
fn test_all_degrees_window() {
let g = crate::graph_loader::lotr_graph::lotr_graph();
assert_eq!(g.count_edges(), 701);
assert_eq!(g.node("Gandalf").unwrap().degree(), 49);
assert_eq!(g.node("Gandalf").unwrap().window(1356, 24792).degree(), 34);
assert_eq!(g.node("Gandalf").unwrap().in_degree(), 24);
assert_eq!(
g.node("Gandalf").unwrap().window(1356, 24792).in_degree(),
16
);
assert_eq!(g.node("Gandalf").unwrap().out_degree(), 35);
assert_eq!(
g.node("Gandalf").unwrap().window(1356, 24792).out_degree(),
20
);
}
#[test]
fn test_all_neighbours_window() {
global_info_logger();
let g = crate::graph_loader::lotr_graph::lotr_graph();
assert_eq!(g.count_edges(), 701);
assert_eq!(g.node("Gandalf").unwrap().neighbours().iter().count(), 49);
assert_eq!(
g.node("Gandalf")
.unwrap()
.window(1356, 24792)
.neighbours()
.iter()
.count(),
34
);
assert_eq!(
g.node("Gandalf").unwrap().in_neighbours().iter().count(),
24
);
assert_eq!(
g.node("Gandalf")
.unwrap()
.window(1356, 24792)
.in_neighbours()
.iter()
.count(),
16
);
assert_eq!(
g.node("Gandalf").unwrap().out_neighbours().iter().count(),
35
);
assert_eq!(
g.node("Gandalf")
.unwrap()
.window(1356, 24792)
.out_neighbours()
.iter()
.count(),
20
);
}
#[test]
fn test_all_edges_window() {
let g = crate::graph_loader::lotr_graph::lotr_graph();
assert_eq!(g.count_edges(), 701);
assert_eq!(g.node("Gandalf").unwrap().edges().iter().count(), 59);
assert_eq!(
g.node("Gandalf")
.unwrap()
.window(1356, 24792)
.edges()
.iter()
.count(),
36
);
assert_eq!(g.node("Gandalf").unwrap().in_edges().iter().count(), 24);
assert_eq!(
g.node("Gandalf")
.unwrap()
.window(1356, 24792)
.in_edges()
.iter()
.count(),
16
);
assert_eq!(g.node("Gandalf").unwrap().out_edges().iter().count(), 35);
assert_eq!(
g.node("Gandalf")
.unwrap()
.window(1356, 24792)
.out_edges()
.iter()
.count(),
20
);
}
}