Changeable watched time + modify mylist entries
This commit is contained in:
parent
5a670733d0
commit
54017d0971
64
src/api.c
64
src/api.c
@ -677,18 +677,12 @@ static enum error api_cmd_base_errorc(long code, char buffer[API_BUFSIZE])
|
|||||||
* error code handers, like 505, 555, 604...
|
* error code handers, like 505, 555, 604...
|
||||||
* If success, res.code will be filled out
|
* If success, res.code will be filled out
|
||||||
*/
|
*/
|
||||||
static enum error api_cmd_base(char buffer[API_BUFSIZE], struct api_result *res,
|
static enum error api_cmd_base_pref(char buffer[API_BUFSIZE], int send_len,
|
||||||
const char *fmt, ...)
|
struct api_result *res)
|
||||||
{
|
{
|
||||||
int send_len;
|
|
||||||
enum error err = NOERR;
|
enum error err = NOERR;
|
||||||
va_list ap;
|
|
||||||
int retry_count = 0;
|
int retry_count = 0;
|
||||||
|
|
||||||
va_start(ap, fmt);
|
|
||||||
send_len = vsnprintf(buffer, API_BUFSIZE, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
pthread_mutex_lock(&api_work_mx);
|
pthread_mutex_lock(&api_work_mx);
|
||||||
api_g_retry_count = 0;
|
api_g_retry_count = 0;
|
||||||
|
|
||||||
@ -754,6 +748,18 @@ end:
|
|||||||
pthread_mutex_unlock(&api_work_mx);
|
pthread_mutex_unlock(&api_work_mx);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
static enum error api_cmd_base(char buffer[API_BUFSIZE], struct api_result *res,
|
||||||
|
const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
int send_len;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
send_len = vsnprintf(buffer, API_BUFSIZE, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
return api_cmd_base_pref(buffer, send_len, res);
|
||||||
|
}
|
||||||
|
|
||||||
static enum error api_cmd_encrypt(const char *uname, struct api_result *res)
|
static enum error api_cmd_encrypt(const char *uname, struct api_result *res)
|
||||||
{
|
{
|
||||||
@ -875,17 +881,28 @@ enum error api_cmd_uptime(struct api_result *res)
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum error api_cmd_mylistadd(int64_t size, const uint8_t *hash,
|
enum error api_cmd_mylistadd(int64_t size, const uint8_t *hash,
|
||||||
enum mylist_state ml_state, bool watched, struct api_result *res)
|
struct api_mylistadd_opts *opts, struct api_result *res)
|
||||||
{
|
{
|
||||||
char buffer[API_BUFSIZE];
|
char buffer[API_BUFSIZE];
|
||||||
char hash_str[ED2K_HASH_SIZE * 2 + 1];
|
char hash_str[ED2K_HASH_SIZE * 2 + 1];
|
||||||
enum error err = NOERR;
|
enum error err = NOERR;
|
||||||
|
int send_len;
|
||||||
|
|
||||||
util_byte2hex(hash, ED2K_HASH_SIZE, false, hash_str);
|
util_byte2hex(hash, ED2K_HASH_SIZE, false, hash_str);
|
||||||
/* Wiki says file size is 4 bytes, but no way that's true lol */
|
/* Wiki says file size is 4 bytes, but no way that's true lol */
|
||||||
err = api_cmd_base(buffer, res,
|
send_len = snprintf(buffer, sizeof(buffer),
|
||||||
"MYLISTADD s=%s&size=%ld&ed2k=%s&state=%hu&viewed=%d",
|
"MYLISTADD s=%s&size=%ld&ed2k=%s",
|
||||||
api_session, size, hash_str, ml_state, watched);
|
api_session, size, hash_str);
|
||||||
|
if (opts->state_set)
|
||||||
|
send_len += snprintf(buffer + send_len, sizeof(buffer) - send_len,
|
||||||
|
"&state=%hu", opts->state);
|
||||||
|
if (opts->watched_set)
|
||||||
|
send_len += snprintf(buffer + send_len, sizeof(buffer) - send_len,
|
||||||
|
"&viewed=%d", opts->watched);
|
||||||
|
if (opts->wdate_set)
|
||||||
|
send_len += snprintf(buffer + send_len, sizeof(buffer) - send_len,
|
||||||
|
"&viewdate=%ld", opts->wdate);
|
||||||
|
err = api_cmd_base_pref(buffer, send_len, res);
|
||||||
if (err != NOERR)
|
if (err != NOERR)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@ -939,4 +956,27 @@ enum error api_cmd_mylistadd(int64_t size, const uint8_t *hash,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum error api_cmd_mylistmod(uint64_t lid, struct api_mylistadd_opts *opts,
|
||||||
|
struct api_result *res)
|
||||||
|
{
|
||||||
|
char buffer[API_BUFSIZE];
|
||||||
|
enum error err = NOERR;
|
||||||
|
int send_len;
|
||||||
|
|
||||||
|
send_len = snprintf(buffer, sizeof(buffer),
|
||||||
|
"MYLISTADD s=%s&lid=%lu&edit=1", api_session, lid);
|
||||||
|
if (opts->state_set)
|
||||||
|
send_len += snprintf(buffer + send_len, sizeof(buffer) - send_len,
|
||||||
|
"&state=%hu", opts->state);
|
||||||
|
if (opts->watched_set)
|
||||||
|
send_len += snprintf(buffer + send_len, sizeof(buffer) - send_len,
|
||||||
|
"&viewed=%d", opts->watched);
|
||||||
|
if (opts->wdate_set)
|
||||||
|
send_len += snprintf(buffer + send_len, sizeof(buffer) - send_len,
|
||||||
|
"&viewdate=%ld", opts->wdate);
|
||||||
|
err = api_cmd_base_pref(buffer, send_len, res);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
19
src/api.h
19
src/api.h
@ -203,6 +203,17 @@ enum file_state {
|
|||||||
FILE_STATE_OTHER = 100,
|
FILE_STATE_OTHER = 100,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct api_mylistadd_opts {
|
||||||
|
enum mylist_state state;
|
||||||
|
bool watched;
|
||||||
|
uint64_t wdate;
|
||||||
|
struct {
|
||||||
|
bool state_set : 1;
|
||||||
|
bool watched_set : 1;
|
||||||
|
bool wdate_set : 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
struct api_version_result {
|
struct api_version_result {
|
||||||
char version_str[40];
|
char version_str[40];
|
||||||
};
|
};
|
||||||
@ -231,6 +242,9 @@ struct api_mylistadd_result {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
struct api_mylistmod_result {
|
||||||
|
uint32_t n_edits;
|
||||||
|
};
|
||||||
|
|
||||||
#define e(n) struct api_##n##_result n
|
#define e(n) struct api_##n##_result n
|
||||||
struct api_result {
|
struct api_result {
|
||||||
@ -241,6 +255,7 @@ struct api_result {
|
|||||||
struct api_uptime_result uptime;
|
struct api_uptime_result uptime;
|
||||||
e(mylistadd);
|
e(mylistadd);
|
||||||
e(encrypt);
|
e(encrypt);
|
||||||
|
e(mylistmod);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
#undef e
|
#undef e
|
||||||
@ -251,6 +266,8 @@ void api_free();
|
|||||||
enum error api_cmd_version(struct api_result *res);
|
enum error api_cmd_version(struct api_result *res);
|
||||||
enum error api_cmd_uptime(struct api_result *res);
|
enum error api_cmd_uptime(struct api_result *res);
|
||||||
enum error api_cmd_mylistadd(int64_t size, const uint8_t *hash,
|
enum error api_cmd_mylistadd(int64_t size, const uint8_t *hash,
|
||||||
enum mylist_state fstate, bool watched, struct api_result *res);
|
struct api_mylistadd_opts *opts, struct api_result *res);
|
||||||
|
enum error api_cmd_mylistmod(uint64_t lid, struct api_mylistadd_opts *opts,
|
||||||
|
struct api_result *res);
|
||||||
|
|
||||||
#endif /* _API_H */
|
#endif /* _API_H */
|
||||||
|
@ -23,6 +23,7 @@ static const struct cmd_entry ents[] = {
|
|||||||
{ .arg_name = "uptime", .fn = cmd_server_uptime, .need_auth = true },
|
{ .arg_name = "uptime", .fn = cmd_server_uptime, .need_auth = true },
|
||||||
{ .arg_name = "ed2k", .fn = cmd_ed2k, },
|
{ .arg_name = "ed2k", .fn = cmd_ed2k, },
|
||||||
{ .arg_name = "add", .fn = cmd_add, .need_auth = true, .need_cache = true, },
|
{ .arg_name = "add", .fn = cmd_add, .need_auth = true, .need_cache = true, },
|
||||||
|
{ .arg_name = "modify", .fn = cmd_modify, .need_auth = true, .need_cache = false, },
|
||||||
};
|
};
|
||||||
static const int32_t ents_len = sizeof(ents)/sizeof(*ents);
|
static const int32_t ents_len = sizeof(ents)/sizeof(*ents);
|
||||||
|
|
||||||
|
@ -35,4 +35,9 @@ enum error cmd_server_uptime(void *);
|
|||||||
*/
|
*/
|
||||||
enum error cmd_prog_version(void *);
|
enum error cmd_prog_version(void *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Modifies a mylist entry
|
||||||
|
*/
|
||||||
|
enum error cmd_modify(void *data);
|
||||||
|
|
||||||
#endif /* _CMD_H */
|
#endif /* _CMD_H */
|
||||||
|
@ -12,11 +12,6 @@
|
|||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
struct add_opts {
|
|
||||||
enum mylist_state ao_state;
|
|
||||||
bool ao_watched;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum error cmd_add_cachecheck(const char *path, const struct stat *st,
|
enum error cmd_add_cachecheck(const char *path, const struct stat *st,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
@ -43,9 +38,9 @@ enum error cmd_add_apisend(const char *path, const uint8_t *hash,
|
|||||||
const struct stat *st, void *data)
|
const struct stat *st, void *data)
|
||||||
{
|
{
|
||||||
struct api_result r;
|
struct api_result r;
|
||||||
struct add_opts* ao = (struct add_opts*)data;
|
struct api_mylistadd_opts *mopt = (struct api_mylistadd_opts *)data;
|
||||||
|
|
||||||
if (api_cmd_mylistadd(st->st_size, hash, ao->ao_state, ao->ao_watched, &r)
|
if (api_cmd_mylistadd(st->st_size, hash, mopt, &r)
|
||||||
!= NOERR)
|
!= NOERR)
|
||||||
return ERR_CMD_FAILED;
|
return ERR_CMD_FAILED;
|
||||||
|
|
||||||
@ -83,13 +78,14 @@ enum error cmd_add_apisend(const char *path, const uint8_t *hash,
|
|||||||
|
|
||||||
enum error cmd_add(void *data)
|
enum error cmd_add(void *data)
|
||||||
{
|
{
|
||||||
struct add_opts add_opts = {0};
|
struct api_mylistadd_opts mopt = {0};
|
||||||
struct ed2k_util_opts ed2k_opts = {
|
struct ed2k_util_opts ed2k_opts = {
|
||||||
.pre_hash_fn = cmd_add_cachecheck,
|
.pre_hash_fn = cmd_add_cachecheck,
|
||||||
.post_hash_fn = cmd_add_apisend,
|
.post_hash_fn = cmd_add_apisend,
|
||||||
.data = &add_opts,
|
.data = &mopt,
|
||||||
};
|
};
|
||||||
bool *watched;
|
bool *watched;
|
||||||
|
const char **wdate_str;
|
||||||
enum error err = NOERR;
|
enum error err = NOERR;
|
||||||
int fcount;
|
int fcount;
|
||||||
|
|
||||||
@ -99,10 +95,23 @@ enum error cmd_add(void *data)
|
|||||||
return ERR_CMD_ARG;
|
return ERR_CMD_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config_get("watched", (void**)&watched) == NOERR) {
|
if (config_get("watched", (void**)&watched) == NOERR && *watched) {
|
||||||
add_opts.ao_watched = *watched;
|
mopt.watched = *watched;
|
||||||
|
mopt.watched_set = true;
|
||||||
|
|
||||||
|
if (config_get("wdate", (void**)&wdate_str) == NOERR) {
|
||||||
|
uint64_t wdate = util_iso2unix(*wdate_str);
|
||||||
|
|
||||||
|
if (wdate == 0) {
|
||||||
|
uio_error("Invalid time value: '%s'", *wdate_str);
|
||||||
|
return ERR_CMD_ARG;
|
||||||
|
}
|
||||||
|
mopt.wdate = wdate;
|
||||||
|
mopt.wdate_set = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
add_opts.ao_state = MYLIST_STATE_INTERNAL;
|
mopt.state = MYLIST_STATE_INTERNAL;
|
||||||
|
mopt.state_set = true;
|
||||||
|
|
||||||
for (int i = 0; i < fcount; i++) {
|
for (int i = 0; i < fcount; i++) {
|
||||||
err = ed2k_util_iterpath(config_get_nonopt(i), &ed2k_opts);
|
err = ed2k_util_iterpath(config_get_nonopt(i), &ed2k_opts);
|
||||||
|
65
src/cmd_modify.c
Normal file
65
src/cmd_modify.c
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
#include <sys/stat.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "cmd.h"
|
||||||
|
#include "error.h"
|
||||||
|
#include "uio.h"
|
||||||
|
#include "api.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "ed2k_util.h"
|
||||||
|
#include "cache.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
enum error cmd_modify(void *data)
|
||||||
|
{
|
||||||
|
struct api_mylistadd_opts mopt = {0};
|
||||||
|
bool *watched;
|
||||||
|
const char **wdate_str;
|
||||||
|
enum error err = NOERR;
|
||||||
|
int fcount;
|
||||||
|
|
||||||
|
fcount = config_get_nonopt_count();
|
||||||
|
if (fcount == 0) {
|
||||||
|
uio_error("No mylist ids specified");
|
||||||
|
return ERR_CMD_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config_get("watched", (void**)&watched) == NOERR && *watched) {
|
||||||
|
mopt.watched = *watched;
|
||||||
|
mopt.watched_set = true;
|
||||||
|
|
||||||
|
if (config_get("wdate", (void**)&wdate_str) == NOERR) {
|
||||||
|
uint64_t wdate = util_iso2unix(*wdate_str);
|
||||||
|
|
||||||
|
if (wdate == 0) {
|
||||||
|
uio_error("Invalid time value: '%s'", *wdate_str);
|
||||||
|
return ERR_CMD_ARG;
|
||||||
|
}
|
||||||
|
mopt.wdate = wdate;
|
||||||
|
mopt.wdate_set = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < fcount; i++) {
|
||||||
|
struct api_result res;
|
||||||
|
uint64_t lid;
|
||||||
|
const char *arg = config_get_nonopt(i);
|
||||||
|
|
||||||
|
if (sscanf(arg, "%lu", &lid) != 1) {
|
||||||
|
uio_error("Argument '%s' is not an integer. Skipping", arg);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = api_cmd_mylistmod(lid, &mopt, &res);
|
||||||
|
if (err != NOERR)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (res.code == APICODE_NO_SUCH_MYLIST_ENTRY) {
|
||||||
|
uio_error("No mylist entry with id: '%lu'", lid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
10
src/config.c
10
src/config.c
@ -110,6 +110,10 @@ static struct conf_entry options[] = {
|
|||||||
.set_func = config_set_bool, .in_args = true, .in_file = true,
|
.set_func = config_set_bool, .in_args = true, .in_file = true,
|
||||||
.type = OTYPE_B, .handle_order = 1, .value_is_set = true, },
|
.type = OTYPE_B, .handle_order = 1, .value_is_set = true, },
|
||||||
|
|
||||||
|
{ .l_name = "wdate", .s_name = UCHAR_MAX + 4, .has_arg = required_argument,
|
||||||
|
.set_func = config_set_str, .in_args = true,
|
||||||
|
.type = OTYPE_S, .handle_order = 1, },
|
||||||
|
|
||||||
/*### cmd ###*/
|
/*### cmd ###*/
|
||||||
|
|
||||||
{ .l_name = "server-version", .s_name = UCHAR_MAX + 2,
|
{ .l_name = "server-version", .s_name = UCHAR_MAX + 2,
|
||||||
@ -132,7 +136,11 @@ static struct conf_entry options[] = {
|
|||||||
.has_arg = no_argument, .set_func = config_set_bool, .in_args = true,
|
.has_arg = no_argument, .set_func = config_set_bool, .in_args = true,
|
||||||
.type = OTYPE_B, .handle_order = 1 },
|
.type = OTYPE_B, .handle_order = 1 },
|
||||||
|
|
||||||
/*{ .l_name = "stats", .s_name = UCHAR_MAX + 4,
|
{ .l_name = "modify", .s_name = 'W',
|
||||||
|
.has_arg = no_argument, .set_func = config_set_bool, .in_args = true,
|
||||||
|
.type = OTYPE_B, .handle_order = 1 },
|
||||||
|
|
||||||
|
/*{ .l_name = "stats", .s_name = UCHAR_MAX + 5,
|
||||||
.has_arg = no_argument, .set_func = config_set_bool, .in_args = true,
|
.has_arg = no_argument, .set_func = config_set_bool, .in_args = true,
|
||||||
.type = OTYPE_B, .handle_order = 1, .value_is_set = true },*/
|
.type = OTYPE_B, .handle_order = 1, .value_is_set = true },*/
|
||||||
|
|
||||||
|
25
src/util.c
25
src/util.c
@ -1,5 +1,7 @@
|
|||||||
|
#define _XOPEN_SOURCE
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
@ -37,3 +39,26 @@ uint64_t util_timespec_diff(const struct timespec *past,
|
|||||||
int64_t nsdiff = future->tv_nsec - past->tv_nsec;
|
int64_t nsdiff = future->tv_nsec - past->tv_nsec;
|
||||||
return sdiff * 1000 + (nsdiff / 1000000);
|
return sdiff * 1000 + (nsdiff / 1000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t util_iso2unix(const char *isotime)
|
||||||
|
{
|
||||||
|
struct tm tm = {0};
|
||||||
|
char *ms = strptime(isotime, "%Y-%m-%d", &tm);
|
||||||
|
|
||||||
|
if (!ms || (*ms != '\0' && *ms != ' ' && *ms != 'T'))
|
||||||
|
return 0;
|
||||||
|
if (*ms == '\0')
|
||||||
|
ms = "T00:00:00";
|
||||||
|
|
||||||
|
ms = strptime(ms + 1, "%H:%M", &tm);
|
||||||
|
if (!ms || (*ms != '\0' && *ms != ':'))
|
||||||
|
return 0;
|
||||||
|
if (*ms == '\0')
|
||||||
|
ms = ":00";
|
||||||
|
|
||||||
|
ms = strptime(ms + 1, "%S", &tm);
|
||||||
|
if (!ms)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return mktime(&tm);
|
||||||
|
}
|
||||||
|
@ -42,4 +42,10 @@ char *util_basename(const char *fullpath);
|
|||||||
uint64_t util_timespec_diff(const struct timespec *past,
|
uint64_t util_timespec_diff(const struct timespec *past,
|
||||||
const struct timespec *future);
|
const struct timespec *future);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert a date and optionally time string into unix time
|
||||||
|
* Returns 0 on error
|
||||||
|
*/
|
||||||
|
uint64_t util_iso2unix(const char *isotime);
|
||||||
|
|
||||||
#endif /* _UTIL_H */
|
#endif /* _UTIL_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user