aboutsummaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2020-07-15 06:09:50 +0200
committerdec05eba <dec05eba@protonmail.com>2020-07-15 07:46:57 +0200
commit35aca1f0582c43b5f6818c8fc00b924247e45881 (patch)
tree66d5e8f7954481863ba6d79db22a6df32f78af69 /src/main.c
parent5b20475c7faf89bbabc9eab43c7e5622317a18fc (diff)
Implement rss sync
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c156
1 files changed, 117 insertions, 39 deletions
diff --git a/src/main.c b/src/main.c
index 11fdc54..eabd755 100644
--- a/src/main.c
+++ b/src/main.c
@@ -4,6 +4,7 @@
#include "fileutils.h"
#include "stringutils.h"
#include "rss.h"
+#include "rss_html_common.h"
#include "html.h"
#include "json.h"
@@ -55,16 +56,6 @@ static void usage_sync(void) {
exit(1);
}
-static struct json_value_s* json_object_get_field_by_name(struct json_object_s *json_obj, const char *name) {
- struct json_object_element_s *obj_element = json_obj->start;
- while(obj_element) {
- if(strcmp(obj_element->name->string, name) == 0)
- return obj_element->value;
- obj_element = obj_element->next;
- }
- return NULL;
-}
-
typedef void (*DownloadedListCallback)(const char *title, double timestamp, void *userdata);
static void data_file_get_downloaded(const char *dir_name, const char *data_filepath, int is_html, DownloadedListCallback callback, void *userdata) {
@@ -163,21 +154,23 @@ static void downloaded_list_callback(const char *title, double timestamp, void *
static void get_downloaded_items(const char *tracked_dir, int is_html, void *userdata) {
struct dirent *dir;
DIR *d = opendir(tracked_dir);
- if(!d)
+ if(!d) {
+ fprintf(stderr, "Failed to open directory: %s\n", tracked_dir);
return;
+ }
- char data_filepath[PATH_MAX] = {0};
- strcat(data_filepath, tracked_dir);
+ char data_filepath[PATH_MAX];
+ strcpy(data_filepath, tracked_dir);
strcat(data_filepath, "/");
int data_filepath_length = strlen(data_filepath);
while((dir = readdir(d)) != NULL) {
- /* We dont want hidden files (and . ..) */
- if(dir->d_name[0] == '.')
+ int filename_len = strlen(dir->d_name);
+ if((filename_len == 1 && dir->d_name[0] == '.') || (filename_len == 2 && dir->d_name[0] == '.' && dir->d_name[1] == '.'))
continue;
strcpy(data_filepath + data_filepath_length, dir->d_name);
- strcpy(data_filepath + data_filepath_length + strlen(dir->d_name), "/data");
+ strcpy(data_filepath + data_filepath_length + filename_len, "/data");
data_file_get_downloaded(dir->d_name, data_filepath, is_html, downloaded_list_callback, userdata);
}
@@ -265,11 +258,98 @@ static void command_add(int argc, char **argv, char *rss_config_dir, char *html_
}
}
+sig_atomic_t running = 0;
+static void automedia_pid_signal_handler(int signum) {
+ (void)signum;
+ running = 0;
+}
+
+static void sync_tracked_rss(char *rss_config_dir) {
+ char rss_tracked_dir[PATH_MAX];
+ strcpy(rss_tracked_dir, rss_config_dir);
+ strcat(rss_tracked_dir, "/tracked");
+
+ struct dirent *dir;
+ DIR *d = opendir(rss_tracked_dir);
+ if(!d) {
+ fprintf(stderr, "Failed to open directory: %s\n", rss_tracked_dir);
+ return;
+ }
+
+ char *item_filepath = rss_tracked_dir;
+ strcat(item_filepath, "/");
+ int item_filepath_len = strlen(item_filepath);
+
+ while((dir = readdir(d)) != NULL && running) {
+ int title_len = strlen(dir->d_name);
+ if((title_len == 1 && dir->d_name[0] == '.') || (title_len == 2 && dir->d_name[0] == '.' && dir->d_name[1] == '.'))
+ continue;
+
+ strcpy(item_filepath + item_filepath_len, dir->d_name);
+
+ strcpy(item_filepath + item_filepath_len + title_len, "/.in_progress");
+ if(file_exists(item_filepath) == 0) {
+ fprintf(stderr, "Skipping in-progress rss %s\n", dir->d_name);
+ continue;
+ }
+
+ strcpy(item_filepath + item_filepath_len + title_len, "/link");
+ char *link_file_content = NULL;
+ long link_file_size = 0;
+ int has_link = file_get_content(item_filepath, &link_file_content, &link_file_size);
+
+ strcpy(item_filepath + item_filepath_len + title_len, "/data");
+ char *data_file_content = NULL;
+ long data_file_size = 0;
+ int has_data = file_get_content(item_filepath, &data_file_content, &data_file_size);
+
+ if(has_link != 0 || has_data != 0) {
+ free(link_file_content);
+ free(data_file_content);
+ fprintf(stderr, "Rss corrupt, link or data missing for rss %s\n", dir->d_name);
+ continue;
+ }
+
+ struct json_value_s *json_data = json_parse(data_file_content, data_file_size);
+ free(data_file_content);
+ if(!json_data || json_data->type != json_type_object) {
+ free(link_file_content);
+ free(json_data);
+ fprintf(stderr, "Rss corrupt for %s\n", dir->d_name);
+ continue;
+ }
+
+ TrackedRss tracked_rss;
+ tracked_rss.title = dir->d_name;
+ tracked_rss.link = link_file_content;
+ tracked_rss.json_data = json_value_as_object(json_data);
+ if(sync_rss(&tracked_rss, rss_config_dir) != 0)
+ fprintf(stderr, "Failed to sync %s\n", dir->d_name);
+
+ free(link_file_content);
+ free(json_data);
+ }
+
+ closedir(d);
+}
+
static void sync_rss_html(char *rss_config_dir, char *html_config_dir, const char *download_dir, int sync_rate_sec) {
- (void)rss_config_dir;
(void)html_config_dir;
- (void)download_dir;
- (void)sync_rate_sec;
+
+ if(transmission_is_daemon_running() != 0) {
+ if(transmission_start_daemon(download_dir) != 0) {
+ fprintf(stderr, "Failed to start torrent daemon\n");
+ exit(2);
+ }
+ }
+
+ running = 1;
+ /* running is set to 0 in SIGINT signal handler (ctrl+c) */
+ while(running) {
+ sync_tracked_rss(rss_config_dir);
+ if(running)
+ sleep(sync_rate_sec);
+ }
}
static int cmdline_contains_str(const char *cmdline, const char *str) {
@@ -285,24 +365,27 @@ static int cmdline_contains_str(const char *cmdline, const char *str) {
}
}
-static void automedia_pid_signal_handler(int signum) {
- (void)signum;
- unlink("/tmp/automedia.pid");
- exit(1);
-}
-
static void command_sync(int argc, char **argv, char *rss_config_dir, char *html_config_dir) {
if(argc < 1)
usage_sync();
- const char *download_dir = argv[0];
+ char *download_dir = argv[0];
const char automedia_pid_path[] = "/tmp/automedia.pid";
+
+ if(create_directory_recursive(download_dir) != 0) {
+ fprintf(stderr, "Failed to create download directory %s\n", download_dir);
+ exit(1);
+ }
- int pid_file = open(automedia_pid_path, O_CREAT | O_EXCL | O_RDWR);
+ int pid_file = open(automedia_pid_path, O_CREAT | O_EXCL | O_SYNC | O_RDWR, 0666);
if(pid_file == -1 && errno == EEXIST) {
char *running_automedia_pid;
long running_automedia_pid_size;
if(file_get_content(automedia_pid_path, &running_automedia_pid, &running_automedia_pid_size) == 0) {
+ /*
+ We have to check the cmdline because another process could theoretically receive the pid
+ that an old automedia process had
+ */
char cmdline_file_path[128];
sprintf(cmdline_file_path, "/proc/%s/cmdline", running_automedia_pid);
free(running_automedia_pid);
@@ -318,11 +401,14 @@ static void command_sync(int argc, char **argv, char *rss_config_dir, char *html
}
free(cmdline);
} else {
+ fprintf(stderr, "Failed to get content of %s\n", automedia_pid_path);
free(running_automedia_pid);
+ exit(1);
}
+ fprintf(stderr, "Overwriting existing %s\n", automedia_pid_path);
remove(automedia_pid_path);
- pid_file = open(automedia_pid_path, O_CREAT | O_EXCL | O_RDWR);
+ pid_file = open(automedia_pid_path, O_CREAT | O_EXCL | O_SYNC | O_RDWR, 0666);
}
if(pid_file == -1 && errno != EEXIST) {
@@ -337,14 +423,14 @@ static void command_sync(int argc, char **argv, char *rss_config_dir, char *html
int process_pid_str_len = strlen(process_pid_str);
if(write(pid_file, process_pid_str, process_pid_str_len) != process_pid_str_len) {
fprintf(stderr, "Failed to write pid to %s\n", automedia_pid_path);
- unlink(automedia_pid_path);
+ remove(automedia_pid_path);
exit(1);
}
close(pid_file);
const int sync_rate_sec = 15 * 60; /* every 15 min */
sync_rss_html(rss_config_dir, html_config_dir, download_dir, sync_rate_sec);
- unlink(automedia_pid_path);
+ remove(automedia_pid_path);
}
static void command_downloaded(const char *rss_config_dir, const char *html_config_dir) {
@@ -372,12 +458,7 @@ static void command_downloaded(const char *rss_config_dir, const char *html_conf
buffer_deinit(&downloaded_items);
}
-/*
-static void torrent_list_callback(int id, float percentage_finished, const char *name, void *userdata) {
- (void)userdata;
- fprintf(stderr, "id: |%d|, done: |%g|, name: |%s|\n", id, percentage_finished, name);
-}
-*/
+
int main(int argc, char **argv) {
if(argc < 2)
usage();
@@ -404,8 +485,5 @@ int main(int argc, char **argv) {
usage();
}
- /*transmission_get_all_torrents(torrent_list_callback, NULL);
- printf("is transmission daemon running? %s\n", transmission_is_daemon_running() == 0 ? "yes" : "no");*/
-
return 0;
}