refactor: reorganize into subdirs (config/ util/ http/ notifs/ queue/ integrations/ static/)
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
#include "discord.h"
|
||||
#include "config.h"
|
||||
#include <curl/curl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
void discord_notify(const char *msg) {
|
||||
if (!g_cfg.discord_webhook[0]) return;
|
||||
CURL *c = curl_easy_init();
|
||||
if (!c) return;
|
||||
char payload[1024];
|
||||
snprintf(payload, sizeof(payload),
|
||||
"{\"username\":\"IPTV Downloader\","
|
||||
"\"avatar_url\":\"https://i.imgur.com/ryNVNoI.png\","
|
||||
"\"content\":\"%s\"}", msg);
|
||||
struct curl_slist *hdrs = curl_slist_append(NULL, "Content-Type: application/json");
|
||||
curl_easy_setopt(c, CURLOPT_URL, g_cfg.discord_webhook);
|
||||
curl_easy_setopt(c, CURLOPT_POSTFIELDS, payload);
|
||||
curl_easy_setopt(c, CURLOPT_HTTPHEADER, hdrs);
|
||||
curl_easy_setopt(c, CURLOPT_TIMEOUT, 10L);
|
||||
curl_easy_setopt(c, CURLOPT_WRITEFUNCTION, NULL);
|
||||
curl_easy_perform(c);
|
||||
curl_slist_free_all(hdrs);
|
||||
curl_easy_cleanup(c);
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
#pragma once
|
||||
void discord_notify(const char *msg);
|
||||
@@ -0,0 +1,74 @@
|
||||
#include "jellyfin.h"
|
||||
#include "config.h"
|
||||
#include <curl/curl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
|
||||
void trigger_jellyfin_scan(void) {
|
||||
if (!g_cfg.jellyfin_url[0]) return;
|
||||
CURL *c = curl_easy_init();
|
||||
if (!c) return;
|
||||
curl_easy_setopt(c, CURLOPT_URL, g_cfg.jellyfin_url);
|
||||
curl_easy_setopt(c, CURLOPT_POST, 1L);
|
||||
curl_easy_setopt(c, CURLOPT_POSTFIELDSIZE, 0L);
|
||||
curl_easy_setopt(c, CURLOPT_TIMEOUT, 10L);
|
||||
curl_easy_setopt(c, CURLOPT_WRITEFUNCTION, NULL);
|
||||
curl_easy_perform(c);
|
||||
curl_easy_cleanup(c);
|
||||
}
|
||||
|
||||
static int cmp_str(const void *a, const void *b) { return strcmp(*(const char **)a, *(const char **)b); }
|
||||
|
||||
void update_show_manifest(const char *season_dir, const char *title_hint) {
|
||||
(void)title_hint;
|
||||
char show_dir[512];
|
||||
strncpy(show_dir, season_dir, sizeof(show_dir)-1); show_dir[sizeof(show_dir)-1] = 0;
|
||||
char *slash = strrchr(show_dir, '/');
|
||||
if (!slash) return;
|
||||
*slash = 0;
|
||||
const char *title = strrchr(show_dir, '/');
|
||||
title = title ? title+1 : show_dir;
|
||||
|
||||
char manifest[640]; snprintf(manifest, sizeof(manifest), "%s/show.json", show_dir);
|
||||
|
||||
char **files = NULL; int fc = 0, fcap = 0;
|
||||
DIR *sd = opendir(show_dir);
|
||||
if (!sd) return;
|
||||
struct dirent *se;
|
||||
while ((se = readdir(sd))) {
|
||||
if (strncmp(se->d_name, "Season ", 7) != 0) continue;
|
||||
char sdir[640]; snprintf(sdir, sizeof(sdir), "%s/%s", show_dir, se->d_name);
|
||||
DIR *ed = opendir(sdir);
|
||||
if (!ed) continue;
|
||||
struct dirent *ee;
|
||||
while ((ee = readdir(ed))) {
|
||||
if (ee->d_name[0] == '.') continue;
|
||||
char fpath[768]; snprintf(fpath, sizeof(fpath), "%s/%s", sdir, ee->d_name);
|
||||
struct stat st; if (stat(fpath, &st) != 0 || !S_ISREG(st.st_mode)) continue;
|
||||
char entry[900];
|
||||
snprintf(entry, sizeof(entry), "{\"file\":\"%s/%s\",\"size\":%lld}",
|
||||
se->d_name, ee->d_name, (long long)st.st_size);
|
||||
if (fc >= fcap) { fcap = fcap ? fcap*2 : 32; files = realloc(files, fcap*sizeof(char*)); }
|
||||
files[fc++] = strdup(entry);
|
||||
}
|
||||
closedir(ed);
|
||||
}
|
||||
closedir(sd);
|
||||
|
||||
if (fc > 1) qsort(files, fc, sizeof(char*), cmp_str);
|
||||
|
||||
FILE *f = fopen(manifest, "w");
|
||||
if (f) {
|
||||
fprintf(f, "{\"title\":\"%s\",\"updated\":%ld,\"count\":%d,\"episodes\":[",
|
||||
title, (long)time(NULL), fc);
|
||||
for (int i = 0; i < fc; i++) { if (i) fputc(',', f); fputs(files[i], f); }
|
||||
fputs("]}", f);
|
||||
fclose(f);
|
||||
}
|
||||
for (int i = 0; i < fc; i++) free(files[i]);
|
||||
free(files);
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
void trigger_jellyfin_scan(void);
|
||||
void update_show_manifest(const char *season_dir, const char *title_hint);
|
||||
Reference in New Issue
Block a user