Move some code into a post module
This commit is contained in:
137
src/main.rs
137
src/main.rs
@@ -2,32 +2,12 @@ use clap::Parser;
|
||||
use colored::*;
|
||||
use futures_util::StreamExt;
|
||||
use log::{debug, warn};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use tokio_tungstenite::{connect_async, tungstenite::protocol::Message};
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
struct Post {
|
||||
kind: Option<String>,
|
||||
#[serde(rename = "type")]
|
||||
type_: Option<String>,
|
||||
time_us: Option<u64>,
|
||||
did: Option<String>,
|
||||
commit: Option<CommitData>,
|
||||
}
|
||||
mod post;
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
struct CommitData {
|
||||
#[serde(rename = "type")]
|
||||
type_: Option<String>,
|
||||
operation: Option<String>,
|
||||
record: Option<RecordData>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
struct RecordData {
|
||||
text: Option<String>,
|
||||
}
|
||||
use post::*;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
@@ -91,17 +71,6 @@ impl BlueskyFirehosePrinter {
|
||||
colored::Color::TrueColor { r, g, b }
|
||||
}
|
||||
|
||||
fn extract_post_text(&self, post: &Post) -> String {
|
||||
if let Some(ref commit) = post.commit {
|
||||
if let Some(ref record) = commit.record {
|
||||
if let Some(ref text) = record.text {
|
||||
return text.chars().take(200).collect();
|
||||
}
|
||||
}
|
||||
}
|
||||
format!("{:?}", post)
|
||||
}
|
||||
|
||||
async fn connect_and_print(
|
||||
&self,
|
||||
websocket_url: &str,
|
||||
@@ -126,79 +95,40 @@ impl BlueskyFirehosePrinter {
|
||||
match serde_json::from_str::<Post>(&text) {
|
||||
Ok(mut post) => {
|
||||
// Handle missing fields
|
||||
if post.kind.is_none() {
|
||||
post.kind = post.type_.clone();
|
||||
}
|
||||
post.normalize();
|
||||
|
||||
// Apply filters
|
||||
if !onlys.is_empty() {
|
||||
if let Some(ref kind) = post.kind {
|
||||
if !onlys.contains(kind) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if !post.matches_only_filter(onlys) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(ref kind) = post.kind {
|
||||
if skips.contains(kind) {
|
||||
continue;
|
||||
}
|
||||
if post.should_skip(skips) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let ts = post.time_us.unwrap_or(0) / 10_000;
|
||||
let ts = post.get_time_us().unwrap_or(0) / 10_000;
|
||||
|
||||
// Generate HSV color based on timestamp
|
||||
let h = ((ts as f64 / 4.0) % 255.0) / 255.0 * 360.0;
|
||||
let mut s = 0.8;
|
||||
let mut v = 0.8;
|
||||
let v;
|
||||
|
||||
let mut text = String::new();
|
||||
// Apply commit type filters
|
||||
if !post.matches_commit_type_filters(cfilters) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle commit type filtering and text extraction
|
||||
if post.kind.as_deref() == Some("commit") {
|
||||
if let Some(ref commit) = post.commit {
|
||||
if let Some(ref commit_type) = commit.type_ {
|
||||
// Apply commit type filters
|
||||
if let Some(excludes) = cfilters.get("-") {
|
||||
if excludes.iter().any(|w| commit_type.contains(w)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if let Some(includes) = cfilters.get("+") {
|
||||
if !includes.iter().any(|w| commit_type.contains(w)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Extract and filter text
|
||||
let text = match post.extract_and_filter_text(fkeeps, fdrops) {
|
||||
Some(text) => text,
|
||||
None => continue, // Text was filtered out
|
||||
};
|
||||
|
||||
if let Some(ref record) = commit.record {
|
||||
if let Some(ref record_text) = record.text {
|
||||
// Apply text filters
|
||||
if !fdrops.is_empty() {
|
||||
if fdrops.iter().any(|w| record_text.contains(w)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if !fkeeps.is_empty() {
|
||||
if !fkeeps.iter().any(|w| record_text.contains(w)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
text = record_text.clone();
|
||||
// Adjust brightness based on text length
|
||||
v = 1.0
|
||||
- (text.len() as f64)
|
||||
.ln()
|
||||
.min(16.0 * 256.0_f64.ln())
|
||||
/ (16.0 * 256.0_f64.ln());
|
||||
} else {
|
||||
text = format!("commit.record={:?}", record);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Adjust color based on post type and text
|
||||
if post.get_kind() == Some("commit") {
|
||||
// Adjust brightness based on text length
|
||||
v = post.calculate_text_brightness(&text);
|
||||
} else {
|
||||
text = self.extract_post_text(&post);
|
||||
s = 0.8;
|
||||
v = 120.0 / 255.0;
|
||||
}
|
||||
@@ -213,24 +143,15 @@ impl BlueskyFirehosePrinter {
|
||||
|
||||
// Print colored output
|
||||
let hsv_str = format!("{:.1}:{:.1}:{:.1}", h / 360.0, s, v);
|
||||
let _post_id = post
|
||||
.did
|
||||
.unwrap_or_else(|| format!("r:{}", rand::random::<f64>()));
|
||||
let _post_id = post.get_post_id();
|
||||
|
||||
let type_str = post.type_.as_deref().unwrap_or("None");
|
||||
let kind_str = post.kind.as_deref().unwrap_or("None");
|
||||
let type_str = post.get_type().unwrap_or("None");
|
||||
let kind_str = post.get_kind().unwrap_or("None");
|
||||
|
||||
if post.type_.as_deref() == Some("com") {
|
||||
let commit_type = post
|
||||
.commit
|
||||
.as_ref()
|
||||
.and_then(|c| c.type_.as_deref())
|
||||
.unwrap_or("None");
|
||||
let operation = post
|
||||
.commit
|
||||
.as_ref()
|
||||
.and_then(|c| c.operation.as_deref())
|
||||
.unwrap_or("None");
|
||||
if post.get_type() == Some("com") {
|
||||
let (commit_type, operation) = post.get_commit_info();
|
||||
let commit_type = commit_type.unwrap_or("None");
|
||||
let operation = operation.unwrap_or("None");
|
||||
|
||||
println!(
|
||||
"{}{}|type:{}|{}{}{}|hsv:{} type:{} kind:{} commit.type={} operation={}",
|
||||
|
||||
160
src/post.rs
Normal file
160
src/post.rs
Normal file
@@ -0,0 +1,160 @@
|
||||
use rand;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct Post {
|
||||
kind: Option<String>,
|
||||
#[serde(rename = "type")]
|
||||
type_: Option<String>,
|
||||
time_us: Option<u64>,
|
||||
did: Option<String>,
|
||||
commit: Option<CommitData>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct CommitData {
|
||||
#[serde(rename = "type")]
|
||||
type_: Option<String>,
|
||||
operation: Option<String>,
|
||||
record: Option<RecordData>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct RecordData {
|
||||
text: Option<String>,
|
||||
}
|
||||
|
||||
impl Post {
|
||||
/// Normalize the post by ensuring kind field is set
|
||||
pub fn normalize(&mut self) {
|
||||
if self.kind.is_none() {
|
||||
self.kind = self.type_.clone();
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the type of this post
|
||||
pub fn get_type(&self) -> Option<&str> {
|
||||
self.type_.as_deref()
|
||||
}
|
||||
|
||||
/// Get the kind of this post
|
||||
pub fn get_kind(&self) -> Option<&str> {
|
||||
self.kind.as_deref()
|
||||
}
|
||||
|
||||
/// Get the timestamp in microseconds
|
||||
pub fn get_time_us(&self) -> Option<u64> {
|
||||
self.time_us
|
||||
}
|
||||
|
||||
/// Get the DID or generate a random one
|
||||
pub fn get_post_id(&self) -> String {
|
||||
self.did
|
||||
.clone()
|
||||
.unwrap_or_else(|| format!("r:{}", rand::random::<f64>()))
|
||||
}
|
||||
|
||||
/// Check if this post matches the "only" filter
|
||||
pub fn matches_only_filter(&self, onlys: &[String]) -> bool {
|
||||
if onlys.is_empty() {
|
||||
return true;
|
||||
}
|
||||
|
||||
if let Some(ref kind) = self.kind {
|
||||
onlys.contains(kind)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if this post should be skipped
|
||||
pub fn should_skip(&self, skips: &[String]) -> bool {
|
||||
if let Some(ref kind) = self.kind {
|
||||
skips.contains(kind)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if this post matches commit type filters
|
||||
pub fn matches_commit_type_filters(&self, cfilters: &HashMap<String, Vec<String>>) -> bool {
|
||||
if self.kind.as_deref() != Some("commit") {
|
||||
return true; // Non-commit posts pass commit filters
|
||||
}
|
||||
|
||||
if let Some(ref commit) = self.commit {
|
||||
if let Some(ref commit_type) = commit.type_ {
|
||||
// Apply commit type filters
|
||||
if let Some(excludes) = cfilters.get("-") {
|
||||
if excludes.iter().any(|w| commit_type.contains(w)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if let Some(includes) = cfilters.get("+") {
|
||||
if !includes.iter().any(|w| commit_type.contains(w)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
/// Check if this post matches text filters and return the extracted text
|
||||
pub fn extract_and_filter_text(&self, fkeeps: &[String], fdrops: &[String]) -> Option<String> {
|
||||
if self.kind.as_deref() == Some("commit") {
|
||||
if let Some(ref commit) = self.commit {
|
||||
if let Some(ref record) = commit.record {
|
||||
if let Some(ref record_text) = record.text {
|
||||
// Apply text filters
|
||||
if !fdrops.is_empty() {
|
||||
if fdrops.iter().any(|w| record_text.contains(w)) {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
if !fkeeps.is_empty() {
|
||||
if !fkeeps.iter().any(|w| record_text.contains(w)) {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
return Some(record_text.clone());
|
||||
} else {
|
||||
return Some(format!("commit.record={:?}", record));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Some(self.extract_text());
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
/// Get commit information for display
|
||||
pub fn get_commit_info(&self) -> (Option<&str>, Option<&str>) {
|
||||
if let Some(ref commit) = self.commit {
|
||||
(commit.type_.as_deref(), commit.operation.as_deref())
|
||||
} else {
|
||||
(None, None)
|
||||
}
|
||||
}
|
||||
|
||||
/// Calculate color brightness based on text length
|
||||
pub fn calculate_text_brightness(&self, text: &str) -> f64 {
|
||||
1.0 - (text.len() as f64).ln().min(16.0 * 256.0_f64.ln()) / (16.0 * 256.0_f64.ln())
|
||||
}
|
||||
|
||||
pub fn extract_text(&self) -> String {
|
||||
if let Some(ref commit) = self.commit {
|
||||
if let Some(ref record) = commit.record {
|
||||
if let Some(ref text) = record.text {
|
||||
return text.chars().take(200).collect();
|
||||
}
|
||||
}
|
||||
}
|
||||
format!("{:?}", self)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user