feat: add sync progress, break loops once we get 0 users back

This commit is contained in:
Sticks
2025-04-22 18:56:27 -04:00
parent ba25e5d485
commit 5a7c3155ac
13 changed files with 292 additions and 40 deletions

View File

@ -5,6 +5,7 @@ use crate::{
use lazy_static::lazy_static;
use serde_json::Value;
use tokio::sync::Mutex;
use crate::handlers::fansly::{SyncProgress, PROGRESS};
lazy_static! {
static ref FANSLY: Mutex<Fansly> = Mutex::new(Fansly::new(None));
@ -28,7 +29,7 @@ pub async fn fansly_get_me() -> Result<FanslyBaseResponse<FanslyAccountResponse>
#[tauri::command]
pub async fn fansly_sync(auto: bool) -> Result<SyncDataResponse, String> {
let fansly = FANSLY.lock().await;
let mut fansly = FANSLY.lock().await;
let response = fansly.sync(auto).await;
match response {
@ -37,6 +38,11 @@ pub async fn fansly_sync(auto: bool) -> Result<SyncDataResponse, String> {
}
}
#[tauri::command]
pub async fn fansly_get_sync_status() -> SyncProgress {
PROGRESS.lock().await.clone()
}
#[tauri::command]
pub async fn fansly_upload_auto_sync_data(
data: SyncDataResponse,

View File

@ -1,3 +1,5 @@
use lazy_static::lazy::Lazy;
use lazy_static::lazy_static;
// Create a simple module for handling the Fansly API, using reqwest to make requests to the API.
// This module will contain a struct Fansly, which will have a method to get the user's profile information.
use crate::structs::{
@ -5,7 +7,24 @@ use crate::structs::{
FanslySubscriptionsResponse, Subscription, SyncDataResponse,
};
use reqwest::header::{HeaderMap, HeaderValue, USER_AGENT};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use tokio::sync::Mutex;
// Create a PROGRESS mutex to hold the current sync progress, lazy initialized
lazy_static! {
pub static ref PROGRESS: Mutex<SyncProgress> = Mutex::new(SyncProgress::default());
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SyncProgress {
// Should contain the current progress of the sync operation
pub current_step: String,
pub percentage_done: u32,
pub current_count: u32,
pub total_count: u32,
pub complete: bool,
}
pub struct Fansly {
client: reqwest::Client,
@ -170,6 +189,26 @@ impl Fansly {
Ok(subscriptions.response.subscriptions)
}
async fn update_progress(
&self,
current_step: impl Into<String>,
curr_count: u32,
total_count: u32,
complete: bool,
) {
let mut p = PROGRESS.lock().await;
p.current_step = current_step.into();
p.current_count = curr_count;
p.total_count = total_count;
p.percentage_done = if total_count > 0 {
curr_count * 100 / total_count
} else {
0
};
p.complete = complete;
}
async fn upload_sync_data(&self, data: SyncDataResponse) -> Result<String, reqwest::Error> {
let url = "https://paste.fanslycreatorbot.com";
@ -273,7 +312,10 @@ impl Fansly {
}
}
pub async fn sync(&self, auto: bool) -> Result<SyncDataResponse, String> {
pub async fn sync(&mut self, auto: bool) -> Result<SyncDataResponse, String> {
// Reset progress
self.update_progress("Starting Sync".to_string(), 0, 100, false).await;
// Fetch profile
log::info!("[sync::process] Fetching profile...");
let profile = self.get_profile().await.map_err(|e| e.to_string())?;
@ -313,14 +355,28 @@ impl Fansly {
"[sync::process] Got {} followers from API.",
response.response.len()
);
followers.extend(response.response);
followers.extend(response.response.clone());
offset += 100;
total_requests += 1;
// Update progress
self.update_progress(
"Fetching Followers".to_string(),
followers.len() as u32,
total_followers as u32,
false
).await;
// Every 10 requests, sleep for a bit to avoid rate limiting
if total_requests % 10 == 0 {
tokio::time::sleep(tokio::time::Duration::from_secs(5)).await;
}
// If we've received no followers, break the loop
if response.response.is_empty() {
log::info!("[sync::process] No more followers found, breaking the loop.");
break;
}
}
// Fetch subscribers until we have all of them
@ -336,14 +392,28 @@ impl Fansly {
.await
.map_err(|e| e.to_string())?;
subscribers.extend(response);
subscribers.extend(response.clone());
offset += 100;
total_requests += 1;
// Update progress
self.update_progress(
"Fetching Subscribers".to_string(),
subscribers.len() as u32,
total_subscribers as u32,
false
).await;
// Every 10 requests, sleep for a bit to avoid rate limiting
if total_requests % 10 == 0 {
tokio::time::sleep(tokio::time::Duration::from_secs(5)).await;
}
// If we've received no subscribers, break the loop
if response.is_empty() {
log::info!("[sync::process] No more subscribers found, breaking the loop.");
break;
}
}
log::info!(
@ -353,6 +423,10 @@ impl Fansly {
);
log::info!("[sync::process] Sync complete.");
// Reset progress
self.update_progress("Sync Complete".to_string(), 100, 100, true).await;
log::info!("[sync::process] Uploading sync data to paste.hep.gg for processing...");
// Upload sync data to paste.hep.gg

View File

@ -11,7 +11,7 @@ use std::io;
use commands::config::{get_config, init_config, save_config};
use commands::fansly::{
fansly_check_sync_token, fansly_get_me, fansly_set_token, fansly_sync,
fansly_upload_auto_sync_data,
fansly_upload_auto_sync_data, fansly_get_sync_status
};
use commands::utils::quit;
use tauri_plugin_autostart::MacosLauncher;
@ -66,7 +66,8 @@ async fn main() {
fansly_get_me,
fansly_sync,
fansly_upload_auto_sync_data,
fansly_check_sync_token
fansly_check_sync_token,
fansly_get_sync_status
])
.run(tauri::generate_context!())
.expect("error while running tauri application");