feat: use paste.hep.gg:
All checks were successful
FanslySync Build & Test / FanslySync Test Runner (push) Successful in 13m13s
All checks were successful
FanslySync Build & Test / FanslySync Test Runner (push) Successful in 13m13s
This commit is contained in:
1
src-tauri/Cargo.lock
generated
1
src-tauri/Cargo.lock
generated
@ -109,6 +109,7 @@ dependencies = [
|
|||||||
"tauri-plugin-notification",
|
"tauri-plugin-notification",
|
||||||
"tauri-plugin-os",
|
"tauri-plugin-os",
|
||||||
"tauri-plugin-updater",
|
"tauri-plugin-updater",
|
||||||
|
"thiserror 2.0.12",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-macros",
|
"tokio-macros",
|
||||||
]
|
]
|
||||||
|
@ -30,6 +30,7 @@ tauri-plugin-notification = { version = "2.2.1" }
|
|||||||
tauri-plugin-updater = { version = "2.2.1" }
|
tauri-plugin-updater = { version = "2.2.1" }
|
||||||
tauri-plugin-log = { version = "2.2.1" }
|
tauri-plugin-log = { version = "2.2.1" }
|
||||||
log = "0.4.27"
|
log = "0.4.27"
|
||||||
|
thiserror = "2.0.12"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
# this feature is used for production builds or when `devPath` points to the filesystem and the built-in dev server is disabled.
|
# this feature is used for production builds or when `devPath` points to the filesystem and the built-in dev server is disabled.
|
||||||
|
@ -10,6 +10,7 @@ use reqwest::header::{HeaderMap, HeaderValue, USER_AGENT};
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
// Create a PROGRESS mutex to hold the current sync progress, lazy initialized
|
// Create a PROGRESS mutex to hold the current sync progress, lazy initialized
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
@ -26,11 +27,32 @@ pub struct SyncProgress {
|
|||||||
pub complete: bool,
|
pub complete: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct PasteData {
|
||||||
|
id: String,
|
||||||
|
content: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct PasteResponse {
|
||||||
|
error: Option<String>,
|
||||||
|
payload: PasteData,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Fansly {
|
pub struct Fansly {
|
||||||
client: reqwest::Client,
|
client: reqwest::Client,
|
||||||
token: Option<String>,
|
token: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum UploadError {
|
||||||
|
#[error("HTTP error: {0}")]
|
||||||
|
Http(#[from] reqwest::Error),
|
||||||
|
|
||||||
|
#[error("Failed to get UUID from paste.hep.gg URL")]
|
||||||
|
MissingUuid,
|
||||||
|
}
|
||||||
|
|
||||||
impl Fansly {
|
impl Fansly {
|
||||||
pub fn new(token: Option<String>) -> Self {
|
pub fn new(token: Option<String>) -> Self {
|
||||||
let mut headers = HeaderMap::new();
|
let mut headers = HeaderMap::new();
|
||||||
@ -38,7 +60,7 @@ impl Fansly {
|
|||||||
// Set the user agent to the FanslySync/0.1.0 tanner@fanslycreatorbot.com
|
// Set the user agent to the FanslySync/0.1.0 tanner@fanslycreatorbot.com
|
||||||
headers.insert(
|
headers.insert(
|
||||||
USER_AGENT,
|
USER_AGENT,
|
||||||
HeaderValue::from_static("FanslySync/0.1.0 tanner@fanslycreatorbot.com"),
|
HeaderValue::from_static("FanslySync/0.1.0 tanner@fanslycreatorbot.com"), // this sucks, oh well
|
||||||
);
|
);
|
||||||
|
|
||||||
// If we have a token, add it to the headers\
|
// If we have a token, add it to the headers\
|
||||||
@ -209,20 +231,14 @@ impl Fansly {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async fn upload_sync_data(&self, data: SyncDataResponse) -> Result<String, reqwest::Error> {
|
async fn upload_sync_data(&self, data: SyncDataResponse) -> Result<String, UploadError> {
|
||||||
let url = "https://paste.fanslycreatorbot.com";
|
let url = "https://paste.hep.gg/";
|
||||||
|
|
||||||
// Convert passed data to bytes
|
// Convert passed data to bytes
|
||||||
let json_string = serde_json::to_string(&data).unwrap();
|
let json_string = serde_json::to_string(&data).unwrap();
|
||||||
let data_as_bytes = json_string.as_bytes();
|
|
||||||
|
|
||||||
let form = reqwest::multipart::Form::new()
|
let form = reqwest::multipart::Form::new()
|
||||||
.part(
|
.text("content", json_string);
|
||||||
"file",
|
|
||||||
reqwest::multipart::Part::bytes(data_as_bytes.to_vec())
|
|
||||||
.file_name("sync_data.json")
|
|
||||||
.mime_str("application/json")?,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Create a new client and POST
|
// Create a new client and POST
|
||||||
let response = self
|
let response = self
|
||||||
@ -235,12 +251,23 @@ impl Fansly {
|
|||||||
if !response.status().is_success() {
|
if !response.status().is_success() {
|
||||||
log::error!("Failed to upload sync data...");
|
log::error!("Failed to upload sync data...");
|
||||||
log::info!("Response: {:?}", response);
|
log::info!("Response: {:?}", response);
|
||||||
return Err(response.error_for_status().unwrap_err());
|
return Err(UploadError::from(response.error_for_status().unwrap_err()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let reply = response.text().await?;
|
log::info!("Uploaded sync data successfully.");
|
||||||
log::info!("Uploaded sync data successfully. Response: {}", reply);
|
|
||||||
Ok(reply)
|
// Get the response URL from the response
|
||||||
|
let url = response.url();
|
||||||
|
|
||||||
|
// Grab the UUID from the URL
|
||||||
|
let uuid = url.path_segments()
|
||||||
|
.and_then(|segments| segments.last())
|
||||||
|
.ok_or(UploadError::MissingUuid)?;
|
||||||
|
|
||||||
|
log::info!("Sync data uploaded to paste.hep.gg with UUID: {}", uuid);
|
||||||
|
|
||||||
|
// Return the URL of the uploaded data
|
||||||
|
Ok(format!("https://paste.hep.gg/api/{}/raw", uuid))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn upload_auto_sync_data(
|
pub async fn upload_auto_sync_data(
|
||||||
|
@ -59,7 +59,7 @@
|
|||||||
"height": 650,
|
"height": 650,
|
||||||
"resizable": false,
|
"resizable": false,
|
||||||
"title": "FanslySync",
|
"title": "FanslySync",
|
||||||
"width": 600
|
"width": 630
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"security": {
|
"security": {
|
||||||
|
@ -837,13 +837,22 @@
|
|||||||
<!-- Create a Little bar that animates up when a sync is running -->
|
<!-- Create a Little bar that animates up when a sync is running -->
|
||||||
{#if syncState.show}
|
{#if syncState.show}
|
||||||
<div
|
<div
|
||||||
class={`fixed bottom-0 left-0 right-0 text-white p-4
|
class="fixed bottom-0 left-0 right-0 h-16 overflow-hidden"
|
||||||
${syncState.syncing ? 'bg-blue-500' : syncState.success ? 'bg-green-500' : 'bg-red-500'}
|
|
||||||
|
|
||||||
`}
|
|
||||||
transition:slide={{ duration: 500 }}
|
transition:slide={{ duration: 500 }}
|
||||||
>
|
>
|
||||||
<div class="flex items-center">
|
<div class="absolute inset-0 bg-blue-900"></div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class={`absolute inset-y-0 left-0 transition-all duration-500 ease-in-out
|
||||||
|
${syncState.syncing ? 'bg-blue-500'
|
||||||
|
: syncState.success ? 'bg-green-500'
|
||||||
|
: 'bg-red-500'}`}
|
||||||
|
style="width: {syncState.syncing
|
||||||
|
? `${syncProgress.percentage}%`
|
||||||
|
: '100%'};"
|
||||||
|
></div>
|
||||||
|
|
||||||
|
<div class="relative z-10 flex items-center h-full text-white">
|
||||||
{#if !syncState.success && !syncState.error}
|
{#if !syncState.success && !syncState.error}
|
||||||
<!-- Add loading spinner -->
|
<!-- Add loading spinner -->
|
||||||
<svg
|
<svg
|
||||||
@ -871,11 +880,10 @@
|
|||||||
</div>
|
</div>
|
||||||
{:else if syncState.success}
|
{:else if syncState.success}
|
||||||
<!-- Add Success title and status subtitle below it -->
|
<!-- Add Success title and status subtitle below it -->
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col px-2">
|
||||||
<h1 class="text-lg font-bold">Sync Successful!</h1>
|
<h1 class="text-lg font-bold">Sync Successful!</h1>
|
||||||
<p class="text-sm">
|
<p class="text-sm">
|
||||||
Data synced successfully. Please run the import with the following link {syncState.url}
|
Data synced successfully. Use the copy button to copy the sync URL to your clipboard.
|
||||||
to import the data.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -900,7 +908,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<!-- Add Error title and status subtitle below it -->
|
<!-- Add Error title and status subtitle below it -->
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col px-2">
|
||||||
<h1 class="text-lg font-bold">Sync Failed!</h1>
|
<h1 class="text-lg font-bold">Sync Failed!</h1>
|
||||||
<p class="text-sm">
|
<p class="text-sm">
|
||||||
An error occurred while syncing your data. Details: {syncState.message}
|
An error occurred while syncing your data. Details: {syncState.message}
|
||||||
|
Reference in New Issue
Block a user