Compare commits

7 Commits
master ... main

Author SHA1 Message Date
081515365d fix: typo
All checks were successful
continuous-integration/drone/push Build is passing
2025-05-31 20:16:46 +01:00
be62b3a867 fix: imports
All checks were successful
continuous-integration/drone/push Build is passing
2025-05-31 20:13:28 +01:00
0f893a004c chore: build with cache
Some checks failed
continuous-integration/drone/push Build is failing
2025-05-31 20:08:07 +01:00
a4ab530ade fix: handle more tiktok domains
feat: accept post_short param (default true)
2025-05-31 20:06:54 +01:00
c8097d18bb fix: remove trigger
All checks were successful
continuous-integration/drone/push Build is passing
2025-02-27 13:50:05 +00:00
4ae98658b7 feat: build docker 2025-02-27 13:45:19 +00:00
d28d6637f8 fix: include title in content 2025-02-27 13:42:12 +00:00
5 changed files with 731 additions and 386 deletions

26
.drone.yml Normal file
View File

@ -0,0 +1,26 @@
kind: pipeline
type: kubernetes
name: default
metadata:
namespace: git
concurrency:
limit: 1
volumes:
- name: cache
claim:
name: storage2
steps:
- name: build
image: docker
privileged: true
volumes:
- name: cache
path: /cache
environment:
TOKEN_DOCKER:
from_secret: docker_hub
commands:
- dockerd --data-root /cache/dockerd &
- docker login -u voidic -p $TOKEN_DOCKER
- docker buildx build --push -t voidic/tiktok-dvm:latest .
- kill $(cat /var/run/docker.pid)

1016
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
[package]
name = "rust_dvm"
name = "tiktok_dvm"
version = "0.1.0"
edition = "2021"

17
Dockerfile Normal file
View File

@ -0,0 +1,17 @@
ARG IMAGE=rust:bookworm
ARG FEATURES
FROM $IMAGE AS build
WORKDIR /app/src
COPY src src
COPY Cargo.lock Cargo.lock
COPY Cargo.toml Cargo.toml
RUN cargo install --path . --root /app/build --features "${FEATURES}"
FROM $IMAGE AS runner
LABEL org.opencontainers.image.source="https://git.v0l.io/Kieran/tiktok-dvm"
LABEL org.opencontainers.image.licenses="MIT"
LABEL org.opencontainers.image.authors="Kieran"
WORKDIR /app
COPY --from=build /app/build .
ENTRYPOINT ["./bin/tiktok_dvm"]

View File

@ -6,15 +6,13 @@ use nostr_sdk::prelude::DataVendingMachineStatus;
use nostr_sdk::{serde_json, Client, EventBuilder, Kind, Tag};
use serde::{Deserialize, Serialize};
use std::env::temp_dir;
use std::fmt::format;
use std::fs::create_dir_all;
use std::future::Future;
use std::path::{Path, PathBuf};
use std::path::Path;
use std::pin::Pin;
use std::time::Duration;
use yt_dlp::executor::Executor;
use yt_dlp::fetcher::deps::Libraries;
use yt_dlp::utils::executor::Executor;
use yt_dlp::Youtube;
/// Basic DVM which clones videos from TikTok and posts them as kind 22 shorts
pub struct TikTokDvm {
@ -49,7 +47,12 @@ impl DVMHandler for TikTokDvm {
bail!("Only URL inputs are accepted")
};
if input.host_str() != Some("www.tiktok.com") {
if !input
.host_str()
.as_ref()
.map(|h| h.ends_with("tiktok.com"))
.unwrap_or(false)
{
bail!("Only tiktok urls are accepted");
}
@ -94,17 +97,32 @@ impl DVMHandler for TikTokDvm {
imeta.push(format!("{} {}", k, v));
}
let ev = EventBuilder::new(Kind::Custom(22), "")
.tag(Tag::parse(imeta)?)
.tags([
Tag::parse(["title", &info.full_title])?,
Tag::parse(["r", input.as_str()])?,
]);
let should_post = if let Some(ps) = request.params.get("post_short") {
ps.to_ascii_lowercase() == "true"
} else {
true
};
let event_posted = client.send_event_builder(ev).await?;
let job_data = NoviaVideoData {
event_id: event_posted.val.to_hex(),
video: res.sha256,
let job_data = if should_post {
let ev = EventBuilder::new(Kind::Custom(22), &info.full_title)
.tag(Tag::parse(imeta)?)
.tags([
Tag::parse(["title", &info.full_title])?,
Tag::parse(["r", input.as_str()])?,
]);
let event_posted = client.send_event_builder(ev).await?;
NoviaVideoData {
event_id: Some(event_posted.val.to_hex()),
video: Some(res.sha256),
url: None,
}
} else {
NoviaVideoData {
event_id: None,
video: Some(res.sha256),
url: Some(res.url),
}
};
let status = build_status_for_job(
@ -164,6 +182,10 @@ struct TikTokVideo {
#[derive(Deserialize, Serialize)]
struct NoviaVideoData {
event_id: String,
video: String,
#[serde(skip_serializing_if = "Option::is_none")]
event_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
video: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
url: Option<String>,
}