A tool for adding anime to your anidb list.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

186 lignes
5.1KB

  1. #include <sys/stat.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <stdbool.h>
  5. #include <time.h>
  6. #include "cmd.h"
  7. #include "error.h"
  8. #include "uio.h"
  9. #include "api.h"
  10. #include "config.h"
  11. #include "ed2k_util.h"
  12. #include "cache.h"
  13. #include "util.h"
  14. static enum error cmd_add_update(uint64_t lid)
  15. {
  16. enum error err;
  17. struct api_result res;
  18. struct api_mylistadd_opts mods;
  19. err = api_cmd_mylist(lid, &res);
  20. if (err != NOERR)
  21. return err;
  22. mods.state = res.mylist.state;
  23. mods.state_set = true;
  24. mods.watched = res.mylist.viewdate != 0;
  25. mods.watched_set = true;
  26. if (mods.watched) {
  27. mods.wdate = res.mylist.viewdate;
  28. mods.wdate_set = true;
  29. }
  30. err = cache_update(lid, &mods);
  31. return err;
  32. }
  33. static enum error cmd_add_cachecheck(const char *path, const struct stat *st,
  34. void *data)
  35. {
  36. struct cache_entry ce;
  37. const char *bname = util_basename(path);
  38. enum error err;
  39. err = cache_get(bname, st->st_size,
  40. CACHE_S_LID | CACHE_S_WATCHDATE | CACHE_S_MODDATE, &ce);
  41. if (err == NOERR) {
  42. /* We could get the entry, so it exists already */
  43. uio_user("This file (%s) with size (%lu) already exists in cache."
  44. " Skipping hashing", bname, st->st_size);
  45. /* Update time is older than 5 days and it's not watched yet */
  46. if (ce.wdate == 0 && ce.moddate - time(NULL) > 5 * 24 * 60 * 60) {
  47. uio_debug("Updating entry with id: %lu", ce.lid);
  48. if (cmd_add_update(ce.lid) != NOERR) {
  49. uio_warning("Cannot update file that is in cache");
  50. }
  51. }
  52. return ED2KUTIL_DONTHASH;
  53. } else if (err != ERR_CACHE_NO_EXISTS) {
  54. uio_error("Some error when trying to get from cache: %s",
  55. error_to_string(err));
  56. return ED2KUTIL_DONTHASH;
  57. }
  58. uio_user("Hashing %s", path);
  59. return NOERR;
  60. }
  61. static enum error cmd_add_apisend(const char *path, const uint8_t *hash,
  62. const struct stat *st, void *data)
  63. {
  64. struct api_result r;
  65. struct api_mylistadd_opts *mopt = (struct api_mylistadd_opts *)data;
  66. if (api_cmd_mylistadd(st->st_size, hash, mopt, &r)
  67. != NOERR)
  68. return ERR_CMD_FAILED;
  69. if (r.code == APICODE_FILE_ALREADY_IN_MYLIST) {
  70. struct api_mylist_result *x = &r.mylist;
  71. uio_warning("File already added! Adding it to cache");
  72. uio_debug("File info: lid: %ld, fid: %ld, eid: %ld, aid: %ld,"
  73. " gid: %ld, date: %ld, viewdate: %ld, state: %d,"
  74. " filestate: %d\nstorage: %s\nsource: %s\nother: %s",
  75. x->lid, x->fid, x->eid, x->aid, x->gid, x->date, x->viewdate,
  76. x->state, x->filestate, x->storage, x->source, x->other);
  77. cache_add(x->lid, util_basename(path), st->st_size, hash, x->viewdate,
  78. x->state);
  79. if (x->storage)
  80. free(x->storage);
  81. if (x->source)
  82. free(x->source);
  83. if (x->other)
  84. free(x->other);
  85. return NOERR;
  86. }
  87. if (r.code == APICODE_NO_SUCH_FILE) {
  88. uio_error("This file does not exists in the AniDB databse: %s",
  89. path);
  90. return NOERR;
  91. }
  92. if (r.code != APICODE_MYLIST_ENTRY_ADDED) {
  93. uio_error("Mylistadd failure: %hu", r.code);
  94. return ERR_CMD_FAILED;
  95. }
  96. uio_user("Succesfully added!");
  97. uio_debug("New mylist id is: %ld", r.mylistadd.new_id);
  98. uint64_t wdate = 0;
  99. if (mopt->watched_set && mopt->watched) {
  100. if (mopt->wdate_set)
  101. wdate = mopt->wdate;
  102. else
  103. wdate = time(NULL);
  104. }
  105. cache_add(r.mylistadd.new_id, util_basename(path), st->st_size, hash,
  106. wdate, mopt->state_set ? mopt->state : MYLIST_STATE_INTERNAL);
  107. return NOERR;
  108. }
  109. enum error cmd_add(void *data)
  110. {
  111. struct api_mylistadd_opts mopt = {0};
  112. struct ed2k_util_opts ed2k_opts = {
  113. .pre_hash_fn = cmd_add_cachecheck,
  114. .post_hash_fn = cmd_add_apisend,
  115. .data = &mopt,
  116. };
  117. bool *watched;
  118. const char **wdate_str;
  119. enum error err = NOERR;
  120. int fcount;
  121. fcount = config_get_nonopt_count();
  122. if (fcount == 0) {
  123. uio_error("No files specified");
  124. return ERR_CMD_ARG;
  125. }
  126. if (config_get("watched", (void**)&watched) == NOERR && *watched) {
  127. mopt.watched = *watched;
  128. mopt.watched_set = true;
  129. if (config_get("wdate", (void**)&wdate_str) == NOERR) {
  130. uint64_t wdate = util_iso2unix(*wdate_str);
  131. if (wdate == 0) {
  132. uio_error("Invalid time value: '%s'", *wdate_str);
  133. return ERR_CMD_ARG;
  134. }
  135. mopt.wdate = wdate;
  136. mopt.wdate_set = true;
  137. }
  138. }
  139. mopt.state = MYLIST_STATE_INTERNAL;
  140. mopt.state_set = true;
  141. for (int i = 0; i < fcount; i++) {
  142. err = ed2k_util_iterpath(config_get_nonopt(i), &ed2k_opts);
  143. if (err != NOERR)
  144. break;
  145. }
  146. return err;
  147. }
  148. enum error cmd_add_argcheck()
  149. {
  150. if (config_get_nonopt_count() == 0) {
  151. uio_error("No files specified");
  152. return ERR_CMD_ARG;
  153. }
  154. return NOERR;
  155. }