Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,712 changes: 1,652 additions & 60 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ rust-version = "1.92"
[dependencies]
axum = { version = "0.8", features = ["macros"] }
tokio = { version = "1.0", features = ["full"] }
tokio-cron-scheduler = "0.15.1"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
reqwest = { version = "0.13", default-features = false, features = ["json", "rustls"] }
Expand All @@ -17,3 +18,4 @@ tracing-subscriber = { version = "0.3", features = ["env-filter"] }
itertools = "0.14"
thiserror = "2.0"
anyhow = "1.0"
polars = { version = "0.45", features = ["lazy", "serde", "json"] }
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check the latest version of polars on crates.io
curl -s https://crates.io/api/v1/crates/polars | jq '.crate.max_version, .crate.newest_version'

Repository: crazyuploader/NetViz

Length of output: 81


Update polars to a current version.

Polars 0.45 is outdated. The latest stable version is 0.52.0. Update to a recent version to ensure access to latest features, improvements, and security patches.

🤖 Prompt for AI Agents
In `@Cargo.toml` at line 21, Update the polars dependency in Cargo.toml from
version "0.45" to a current stable release (e.g., "0.52.0") by changing the
polars entry polars = { version = "0.45", features = ["lazy", "serde", "json"] }
to use the new version string (retain the features unless compatibility requires
adjustment); after updating, run cargo update and cargo build to catch any API
or feature changes and adjust code referencing Polars types/functions if needed.

3 changes: 3 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ FROM debian:bookworm-slim
# Set Time Zone to IST
ENV TZ="Asia/Kolkata"

# Set logging level
ENV RUST_LOG="info"

# Add required runtime packages
RUN apt-get update && \
apt-get install --yes --no-install-recommends \
Expand Down
123 changes: 123 additions & 0 deletions assets/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/* Custom Styling for NetViz on top of Pico CSS v2 */

:root {
--pico-font-family: "Inter", system-ui, -apple-system, sans-serif;
--pico-primary: #3b82f6;
--pico-primary-background: #3b82f6;
--pico-primary-hover: #2563eb;
--pico-primary-underline: rgba(59, 130, 246, 0.5);

--pico-border-radius: 0.5rem;
--pico-form-element-spacing-vertical: 0.75rem;
--pico-form-element-spacing-horizontal: 1rem;
}

/* Typography */
@import url("https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap");
Comment on lines +3 to +16
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Move @import rule before :root declaration.

CSS @import rules must precede all other at-rules and style rules to be valid. The Google Fonts import on line 16 should be moved to the top of the file.

🔧 Proposed fix
 /* Custom Styling for NetViz on top of Pico CSS v2 */
 
+/* Typography */
+@import url("https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap");
+
 :root {
   --pico-font-family: "Inter", system-ui, -apple-system, sans-serif;
   --pico-primary: `#3b82f6`;
   --pico-primary-background: `#3b82f6`;
   --pico-primary-hover: `#2563eb`;
   --pico-primary-underline: rgba(59, 130, 246, 0.5);
 
   --pico-border-radius: 0.5rem;
   --pico-form-element-spacing-vertical: 0.75rem;
   --pico-form-element-spacing-horizontal: 1rem;
 }
 
-/* Typography */
-@import url("https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap");
-
 body {
🧰 Tools
🪛 Biome (2.1.2)

[error] 16-16: This @import is in the wrong position.

Any @import rules must precede all other valid at-rules and style rules in a stylesheet (ignoring @charset and @layer), or else the @import rule is invalid.
Consider moving import position.

(lint/correctness/noInvalidPositionAtImportRule)

🤖 Prompt for AI Agents
In `@assets/style.css` around lines 3 - 16, Move the `@import` rule so it appears
before the :root declaration; specifically, take the existing `@import`
url("https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap")
line and place it at the top of the file as the first statement, ensuring the
:root block (which defines --pico-* variables) comes after the import to satisfy
CSS ordering requirements.


body {
font-weight: 400;
}

h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: 600;
margin-bottom: 1rem;
}

/* Component Overrides & Custom Utilities */

.card {
padding: var(--pico-block-spacing-vertical)
var(--pico-block-spacing-horizontal);
border-radius: var(--pico-border-radius);
background: var(--pico-card-background-color);
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1),
0 2px 4px -1px rgba(0, 0, 0, 0.06);
margin-bottom: var(--pico-block-spacing-vertical);
border: 1px solid var(--pico-muted-border-color);
}

.stat-card {
text-align: center;
}

.stat-value {
font-size: 2.5rem;
font-weight: 700;
color: var(--pico-primary);
margin-bottom: 0.5rem;
}

.stat-label {
font-size: 0.875rem;
color: var(--pico-muted-color);
text-transform: uppercase;
letter-spacing: 0.05em;
}

/* Charts */
.chart-container {
position: relative;
height: 400px;
width: 100%;
}

/* Grid adjustments */
.grid-stats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: var(--pico-grid-column-gap);
margin-bottom: var(--pico-block-spacing-vertical);
}

/* Navbar */
nav strong {
font-size: 1.25rem;
background: -webkit-linear-gradient(45deg, var(--pico-primary), #8b5cf6);
background: linear-gradient(45deg, var(--pico-primary), #8b5cf6);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
}

/* Badge styled pills */
.badge {
display: inline-block;
padding: 0.25em 0.5em;
font-size: 0.75em;
font-weight: 600;
line-height: 1;
text-align: center;
white-space: nowrap;
vertical-align: baseline;
border-radius: var(--pico-border-radius);
background-color: var(--pico-primary);
color: white;
margin-right: 0.25rem;
}

.badge-secondary {
background-color: var(--pico-secondary-background);
color: var(--pico-color);
}

/* Animations */
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}

main > * {
animation: fadeIn 0.4s ease-out;
}
4 changes: 4 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,8 @@ pub enum NetVizError {
/// Unexpected API response format.
#[error("Invalid API response: {0}")]
InvalidApiResponse(String),

/// Polars error.
#[error("Polars error: {0}")]
Polars(#[from] polars::prelude::PolarsError),
}
6 changes: 3 additions & 3 deletions src/fetcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
use crate::error::NetVizError;
use reqwest::header::{HeaderMap, HeaderValue, AUTHORIZATION};
use serde_json::Value;
use std::fs;
use std::path::PathBuf;
use std::time::Duration;
use tokio::fs;
use tracing::{error, info, warn};

/// Base URL for the PeeringDB API.
Expand All @@ -32,7 +32,7 @@ const OUTPUT_DIR: &str = "data/peeringdb";
/// Returns `NetVizError::InvalidApiResponse` if the API index format is unexpected.
pub async fn fetch_and_save_peeringdb_data() -> Result<(), NetVizError> {
let output_path = PathBuf::from(OUTPUT_DIR);
fs::create_dir_all(&output_path)?;
fs::create_dir_all(&output_path).await?;

let client = reqwest::Client::builder()
.user_agent("NetViz/1.0.0")
Expand Down Expand Up @@ -71,7 +71,7 @@ pub async fn fetch_and_save_peeringdb_data() -> Result<(), NetVizError> {
Ok(resp) => match resp.json::<Value>().await {
Ok(data) => match serde_json::to_string_pretty(&data) {
Ok(json_data) => {
if let Err(e) = fs::write(&file_path, json_data) {
if let Err(e) = fs::write(&file_path, json_data).await {
error!("Failed to write data to {:?}: {}", file_path, e);
} else {
info!("Successfully saved data to {:?}", file_path);
Expand Down
Loading
Loading