Skip to content
Extraits de code Groupes Projets
Vérifiée Valider 2e0fb394 rédigé par Kubat's avatar Kubat
Parcourir les fichiers

Moving files around to reorganise things

parent 76d0f2cc
Branches
Étiquettes
1 requête de fusion!41lktadm
......@@ -38,3 +38,9 @@ struct kara_metadata {
/* Reads the .mkv file at `filename` and stores its metadata in `dst`.
* Returns 0 on success and -1 on error. */
int kara_metadata_read(struct kara_metadata *dst, const char *filename);
/* Set the metadata for the file according to its path. */
int metadata_set_file(char *karapath);
/* Set metadata for files under a given directory by their path. */
int metadata_set_directory(const char *kara_dir);
......@@ -17,14 +17,15 @@ libdl = cc.find_library('dl')
# Sources
## Sources for the server
core_sources = [ 'src/bufferfd.c'
core_sources = [ 'src/mkv/bufferfd.c'
, 'src/mkv/write.c'
, 'src/commands.c'
, 'src/database/queue.c'
, 'src/database/update.c'
, 'src/database/find.c'
, 'src/database/config.c'
, 'src/database/playlist.c'
, 'src/mkv.c'
, 'src/mkv/mkv.c'
, 'src/net/command.c'
, 'src/net/listen.c'
, 'src/net/message.c'
......
......@@ -6,7 +6,6 @@
#include <lektor/mkv.h>
#include <lektor/database.h>
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
......@@ -15,7 +14,6 @@
#include <regex.h>
#include <unistd.h>
#include <pwd.h>
#include <pcre.h>
#include <fcntl.h>
#include <linux/limits.h>
#include <sys/types.h>
......@@ -23,296 +21,6 @@
#include <sys/stat.h>
static const char *METADATA_TEMPLATE =
" <?xml version=\"1.0\" encoding=\"UTF-8\"?> "
" <Tags> "
" <Tag> "
" <Targets> "
" <TargetTypeValue>70</TargetTypeValue> "
" </Targets> "
" <Simple> "
" <Name>TITLE</Name> "
" <String>%s</String> "
" </Simple> "
" </Tag> "
" <Tag> "
" <Simple> "
" <Name>TITLE</Name> "
" <String>%s</String> "
" </Simple> "
" <Simple> "
" <Name>CONTENT_TYPE</Name> "
" <String>%s</String> "
" </Simple> "
" <Simple> "
" <Name>ADDRESS</Name> "
" <String>%s</String> "
" </Simple> "
" <Simple> "
" <Name>ARTIST</Name> "
" <String>%s</String> "
" </Simple> "
" <Simple> "
" <Name>GENRE</Name> "
" <String>%s</String> "
" </Simple> "
" <Simple> "
" <Name>TRACK</Name> "
" <String>%d</String> "
" </Simple> "
" </Tag> "
" </Tags> "
;
static bool
call_mkvpropedit(char *const args[])
{
pid_t pid;
int wstatus, status, fd;
if ((pid = fork()) == 0) {
if ((fd = open("/dev/null", O_WRONLY | O_TRUNC)) < 0) {
fprintf(stderr, " ! call_mkvpropedit: Failed to open /dev/null in O_WRONLY | O_TRUNC mode\n");
return false;
}
if (dup2(fd, 1) < 0) {
fprintf(stderr, " ! call_mkvpropedit: Failed to duplicate /dev/null to stdout\n");
return false;
}
execv("/usr/bin/mkvpropedit", args);
exit(EXIT_FAILURE);
} else if (pid < 0) {
fprintf(stderr, " ! metadata_write: Failed to fork: %s\n", strerror(errno));
return false;
} else {
do
if (waitpid(pid, &wstatus, WUNTRACED | WCONTINUED) == -1) {
fprintf(stderr, " ! metadata_write: Failed to wait children: %s\n", strerror(errno));
return false;
}
while (!WIFEXITED(wstatus) && !WIFSIGNALED(wstatus));
if ((status = WEXITSTATUS(wstatus))) {
fprintf(stderr, " ! metadata_write: Children failed with undexpected status %d", status);
return false;
}
}
return true;
}
static bool
metadata_write(char *const mkvfile, struct kara_metadata *meta, int num)
{
char tmpfilepath[PATH_MAX];
char *const metadafilepath = &tmpfilepath[4];
char *const args1[] = { "mkvpropedit", "-t", "all:", mkvfile, NULL };
char *const args2[] = { "mkvpropedit", "-t", tmpfilepath, mkvfile, NULL };
int fd;
bool sta = false;
memset(tmpfilepath, 0, PATH_MAX);
strncat(tmpfilepath, "all:/tmp/lektor.metadata.XXXXXX", PATH_MAX - 1);
if ((fd = mkstemp(metadafilepath)) < 0) {
fprintf(stderr, " ! metadata_write: Failed to create temporary file: %s\n", strerror(errno));
goto error;
}
if (dprintf(fd, METADATA_TEMPLATE, meta->source_name, meta->song_name, meta->category, meta->language,
meta->author_name, meta->song_type, num) < 0) {
fprintf(stderr, " ! metadata_write: Failed to write to temporary file: %s\n", metadafilepath);
goto error;
}
// First command //
if (!call_mkvpropedit(args1))
goto error;
// Second command //
if (!call_mkvpropedit(args2))
goto error;
sta = true;
error:
close(fd);
unlink(metadafilepath);
return sta;
}
static bool
metadata_read(char *const mkvfile, struct kara_metadata *meta, int *const num)
{
pcre *regex = NULL;
pcre_extra *pcre_extra = NULL;
bool sta = false;
const int sub_str_vec_len = 30;
int pcre_error_offset, pcre_exec_ret, sub_str_vec[sub_str_vec_len], i;
char num_str[LEKTOR_TAG_MAX];
const char *substr;
char *copy_to;
(void) meta;
(void) num;
static const char *rgx =
"^\\/(?:.+)\\/(vo|va|amv|cdg|autres|vocaloid)\\/(jp|fr|en|ru|sp|it|ch|latin|multi|undefined)\\/(.+)\\/(.+) - (OP|ED|IS|AMV|VOCA|PV|MV|LIVE)(\\d*) - (.+)\\.mkv$";
const char *pcre_error_str = NULL;
if ((regex = pcre_compile(rgx, 0, &pcre_error_str, &pcre_error_offset, NULL)) == NULL) {
fprintf(stderr, " ! metadata_read: failed to compile regex\n");
return false;
}
pcre_extra = pcre_study(regex, 0, &pcre_error_str);
if (pcre_error_str != NULL) {
fprintf(stderr, " ! metadata_read: failed to study regex: %s\n", pcre_error_str);
goto error;
}
memset(meta, 0, sizeof(struct kara_metadata));
memset(num_str, 0, LEKTOR_TAG_MAX * sizeof(char));
pcre_exec_ret = pcre_exec(regex, pcre_extra, mkvfile, strlen(mkvfile), 0, 0, sub_str_vec, sub_str_vec_len);
if (pcre_exec_ret < 0) {
// Error //
switch (pcre_exec_ret) {
case PCRE_ERROR_NOMATCH:
fprintf(stderr, " ! metadata_read: String did not match the pattern for file %s\n", mkvfile);
goto error;
case PCRE_ERROR_NULL:
fprintf(stderr, " ! metadata_read: Something was null for file %s\n", mkvfile);
goto error;
case PCRE_ERROR_BADOPTION:
fprintf(stderr, " ! metadata_read: A bad option was passed for file %s\n", mkvfile);
goto error;
case PCRE_ERROR_BADMAGIC:
fprintf(stderr, " ! metadata_read: Magic number bad (compiled re corrupt?) for file %s\n", mkvfile);
goto error;
case PCRE_ERROR_UNKNOWN_NODE:
fprintf(stderr, " ! metadata_read: Something kooky in the compiled re for file %s\n", mkvfile);
goto error;
case PCRE_ERROR_NOMEMORY:
fprintf(stderr, " ! metadata_read: Ran out of memory for file %s\n", mkvfile);
goto error;
default:
fprintf(stderr, " ! metadata_read: Unknown error for file %s\n", mkvfile);
goto error;
}
}
if (pcre_exec_ret == 0) {
// To much -> error in our case //
fprintf(stderr, " ! metadata_read: To much matches found for file: %s\n", mkvfile);
goto error;
}
for (i = 1; i < pcre_exec_ret; ++i) {
pcre_get_substring(mkvfile, sub_str_vec, pcre_exec_ret, i, &substr);
if (i == 1)
copy_to = meta->song_type;
else if (i == 2)
copy_to = meta->language;
else if (i == 3)
copy_to = meta->author_name;
else if (i == 4)
copy_to = meta->source_name;
else if (i == 5)
copy_to = meta->category;
else if (i == 6)
copy_to = num_str;
else if (i == 7)
copy_to = meta->song_name;
else {
pcre_free_substring(substr);
goto error;
}
snprintf(copy_to, LEKTOR_TAG_MAX, "%s", substr);
pcre_free_substring(substr);
}
if ((*num = atoi(num_str)) <= 0)
* num = 1;
sta = true;
error:
pcre_free(regex);
if (pcre_extra != NULL) {
#ifdef PCRE_CONFIG_JIT
pcre_free_study(pcre_extra);
#else
pcre_free(pcre_extra);
#endif
}
return sta;
}
static bool
walk_through(const char *kara_dir)
{
DIR *d;
struct dirent *dir;
char path[PATH_MAX];
struct kara_metadata meta;
int num;
memset(path, 0, PATH_MAX * sizeof(char));
d = opendir(kara_dir);
if (!d) {
fprintf(stderr, " ! walk_through: Failed to open directory '%s': %s\n", kara_dir, strerror(errno));
return false;
}
while (NULL != (dir = readdir(d))) {
strncpy(path, kara_dir, PATH_MAX);
strncat(path, "/", PATH_MAX - 1);
strncat(path, dir->d_name, PATH_MAX - 1);
if (dir->d_type == DT_REG &&
metadata_read(path, &meta, &num) &&
metadata_write(path, &meta, num))
continue;
else if (dir->d_type == DT_DIR &&
strcmp(dir->d_name, ".") != 0 &&
strcmp(dir->d_name, "..") != 0)
walk_through(path);
}
fprintf(stderr, " * walk_through: Passed directory '%s'\n", kara_dir);
closedir(d);
return true;
}
static bool
walk_single(char *karapath)
{
int num;
struct kara_metadata meta;
return metadata_read(karapath, &meta, &num) &&
metadata_write(karapath, &meta, num);
}
static bool
walk_prompt_single(char *karapath)
{
(void) karapath;
return false;
}
/* ----------------- *
* The main function *
* ----------------- */
......@@ -345,7 +53,7 @@ main(int argc, char *argv[])
return 10;
}
return walk_through(kara_dir);
return metadata_set_directory(kara_dir);
}
else if (strcmp(argv[1], "--populate-all") == 0) {
......@@ -372,20 +80,22 @@ end_populate:
}
else if (strcmp(argv[1], "--file") == 0) {
ret = 0;
for (i = 2; i < argc; ++i)
ret &= walk_single(argv[i]);
ret |= metadata_set_file(argv[i]);
return ret;
}
else if (strcmp(argv[1], "--prompt-file") == 0) {
ret = 0;
for (i = 2; i < argc; ++i)
ret &= walk_prompt_single(argv[i]);
ret |= metadata_set_file_prompt(argv[i]);
return ret;
}
else if (strcmp(argv[1], "--cat") == 0) {
for (i = 2; i < argc; ++i) {
if (kara_metadata_read(&data, argv[2]) != 0) {
if (kara_metadata_read(&data, argv[2])) {
printf("Failed to read metadata of file %s\n", argv[2]);
return 1;
}
......
Fichier déplacé
Fichier déplacé
#define _POSIX_C_SOURCE 200809L
#define _DEFAULT_SOURCE
#include <lektor/mkv.h>
#include <pcre.h>
#include <stdbool.h>
#include <stdio.h>
#include <unistd.h>
#include <limits.h>
#include <dirent.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/wait.h>
static const char *METADATA_TEMPLATE =
" <?xml version=\"1.0\" encoding=\"UTF-8\"?> "
" <Tags> "
" <Tag> "
" <Targets> "
" <TargetTypeValue>70</TargetTypeValue> "
" </Targets> "
" <Simple> "
" <Name>TITLE</Name> "
" <String>%s</String> "
" </Simple> "
" </Tag> "
" <Tag> "
" <Simple> "
" <Name>TITLE</Name> "
" <String>%s</String> "
" </Simple> "
" <Simple> "
" <Name>CONTENT_TYPE</Name> "
" <String>%s</String> "
" </Simple> "
" <Simple> "
" <Name>ADDRESS</Name> "
" <String>%s</String> "
" </Simple> "
" <Simple> "
" <Name>ARTIST</Name> "
" <String>%s</String> "
" </Simple> "
" <Simple> "
" <Name>GENRE</Name> "
" <String>%s</String> "
" </Simple> "
" <Simple> "
" <Name>TRACK</Name> "
" <String>%d</String> "
" </Simple> "
" </Tag> "
" </Tags> "
;
static bool
mkvpropedit__(char *const args[])
{
pid_t pid;
int wstatus, status, fd;
if ((pid = fork()) == 0) {
if ((fd = open("/dev/null", O_WRONLY | O_TRUNC)) < 0) {
fprintf(stderr, " ! call_mkvpropedit: can't to open /dev/null in O_WRONLY O_TRUNC\n");
return false;
}
if (dup2(fd, 1) < 0) {
fprintf(stderr, " ! call_mkvpropedit: failed to duplicate /dev/null to stdout\n");
return false;
}
execv("/usr/bin/mkvpropedit", args);
exit(EXIT_FAILURE);
} else if (pid < 0) {
fprintf(stderr, " ! metadata_write: failed to fork: %s\n", strerror(errno));
return false;
} else {
do {
if (waitpid(pid, &wstatus, WUNTRACED | WCONTINUED) == -1) {
fprintf(stderr, " ! metadata_write: Failed to wait children: %s\n",
strerror(errno));
return false;
}
} while (!WIFEXITED(wstatus) && !WIFSIGNALED(wstatus));
if ((status = WEXITSTATUS(wstatus))) {
fprintf(stderr, " ! metadata_write: children failed with status %d", status);
return false;
}
}
return true;
}
static bool
metadata_write(char *const mkvfile, struct kara_metadata *meta, int num)
{
char tmpfilepath[PATH_MAX];
char *const metadafilepath = &tmpfilepath[4];
char *const args1[] = { "mkvpropedit", "-t", "all:", mkvfile, NULL };
char *const args2[] = { "mkvpropedit", "-t", tmpfilepath, mkvfile, NULL };
int fd;
bool sta = false;
memset(tmpfilepath, 0, PATH_MAX);
strncat(tmpfilepath, "all:/tmp/lektor.metadata.XXXXXX", PATH_MAX - 1);
if ((fd = mkstemp(metadafilepath)) < 0) {
fprintf(stderr, " ! metadata_write: failed to create temporary file: %s\n",
strerror(errno));
goto error;
}
if (dprintf(fd, METADATA_TEMPLATE, meta->source_name, meta->song_name, meta->category,
meta->language, meta->author_name, meta->song_type, num) < 0) {
fprintf(stderr, " ! metadata_write: failed to write to temporary file: %s\n",
metadafilepath);
goto error;
}
// First command //
if (!mkvpropedit__(args1))
goto error;
// Second command //
if (!mkvpropedit__(args2))
goto error;
sta = true;
error:
close(fd);
unlink(metadafilepath);
return sta;
}
static bool
metadata_from_path(char *const mkvfile, struct kara_metadata *meta, int *const num)
{
pcre *regex = NULL;
pcre_extra *pcre_extra = NULL;
bool sta = false;
const int sub_str_vec_len = 30;
int pcre_error_offset, pcre_exec_ret, sub_str_vec[sub_str_vec_len], i;
char num_str[LEKTOR_TAG_MAX];
const char *substr;
char *copy_to;
static const char *rgx =
"^\\/(?:.+)\\/(vo|va|amv|cdg|autres|vocaloid)\\/"
"(jp|fr|en|ru|sp|it|ch|latin|multi|undefined)\\/(.+)\\/"
"(.+) - (OP|ED|IS|AMV|VOCA|PV|MV|LIVE)(\\d*) - (.+)\\.mkv$";
const char *pcre_error_str = NULL;
if ((regex = pcre_compile(rgx, 0, &pcre_error_str, &pcre_error_offset, NULL)) == NULL) {
fprintf(stderr, " ! metadata_from_path: failed to compile regex\n");
return false;
}
pcre_extra = pcre_study(regex, 0, &pcre_error_str);
if (pcre_error_str != NULL) {
fprintf(stderr, " ! metadata_from_path: failed to study regex: %s\n", pcre_error_str);
goto error;
}
memset(meta, 0, sizeof(struct kara_metadata));
memset(num_str, 0, LEKTOR_TAG_MAX * sizeof(char));
pcre_exec_ret = pcre_exec(regex, pcre_extra, mkvfile, strlen(mkvfile), 0, 0,
sub_str_vec, sub_str_vec_len);
if (pcre_exec_ret < 0) {
// Error //
switch (pcre_exec_ret) {
case PCRE_ERROR_NOMATCH:
fprintf(stderr, " ! metadata_from_path: No pattern match for file %s\n", mkvfile);
goto error;
case PCRE_ERROR_NULL:
fprintf(stderr, " ! metadata_from_path: Something was null for file %s\n", mkvfile);
goto error;
case PCRE_ERROR_BADOPTION:
fprintf(stderr, " ! metadata_from_path: Bad option passed for file %s\n", mkvfile);
goto error;
case PCRE_ERROR_BADMAGIC:
fprintf(stderr, " ! metadata_from_path: Magic number bad for file %s\n", mkvfile);
goto error;
case PCRE_ERROR_UNKNOWN_NODE:
fprintf(stderr, " ! metadata_from_path: Something kooky for file %s\n", mkvfile);
goto error;
case PCRE_ERROR_NOMEMORY:
fprintf(stderr, " ! metadata_from_path: Ran out of memory for file %s\n", mkvfile);
goto error;
default:
fprintf(stderr, " ! metadata_from_path: Unknown error for file %s\n", mkvfile);
goto error;
}
}
if (pcre_exec_ret == 0) {
// To much -> error in our case //
fprintf(stderr, " ! metadata_from_path: To much matches found for file: %s\n", mkvfile);
goto error;
}
for (i = 1; i < pcre_exec_ret; ++i) {
pcre_get_substring(mkvfile, sub_str_vec, pcre_exec_ret, i, &substr);
if (i == 1)
copy_to = meta->song_type;
else if (i == 2)
copy_to = meta->language;
else if (i == 3)
copy_to = meta->author_name;
else if (i == 4)
copy_to = meta->source_name;
else if (i == 5)
copy_to = meta->category;
else if (i == 6)
copy_to = num_str;
else if (i == 7)
copy_to = meta->song_name;
else {
pcre_free_substring(substr);
goto error;
}
snprintf(copy_to, LEKTOR_TAG_MAX, "%s", substr);
pcre_free_substring(substr);
}
if ((*num = atoi(num_str)) <= 0)
* num = 1;
sta = true;
error:
pcre_free(regex);
if (pcre_extra != NULL) {
#ifdef PCRE_CONFIG_JIT
pcre_free_study(pcre_extra);
#else
pcre_free(pcre_extra);
#endif
}
return sta;
}
int
metadata_set_directory(const char *kara_dir)
{
DIR *d;
struct dirent *dir;
char path[PATH_MAX];
struct kara_metadata meta;
int num;
memset(path, 0, PATH_MAX * sizeof(char));
d = opendir(kara_dir);
if (!d) {
fprintf(stderr, " ! metadata_set_directory: Failed to open directory '%s': %s\n",
kara_dir, strerror(errno));
return 1;
}
while (NULL != (dir = readdir(d))) {
strncpy(path, kara_dir, PATH_MAX);
strncat(path, "/", PATH_MAX - 1);
strncat(path, dir->d_name, PATH_MAX - 1);
if (dir->d_type == DT_REG &&
metadata_from_path(path, &meta, &num) &&
metadata_write(path, &meta, num))
continue;
else if (dir->d_type == DT_DIR &&
strcmp(dir->d_name, ".") != 0 &&
strcmp(dir->d_name, "..") != 0)
metadata_set_directory(path);
}
fprintf(stderr, " * metadata_set_directory: Passed directory '%s'\n", kara_dir);
closedir(d);
return false;
}
int
metadata_set_file(char *karapath)
{
int num;
struct kara_metadata meta;
return metadata_from_path(karapath, &meta, &num) &&
metadata_write(karapath, &meta, num);
}
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Veuillez vous inscrire ou vous pour commenter