task.hpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. #ifndef __TASK_HPP__
  2. #define __TASK_HPP__
  3. #include <QQueue>
  4. #include <QString>
  5. #include <QVector>
  6. #include <memory>
  7. #include <variant>
  8. #include <vector>
  9. namespace Scheduler {
  10. enum TaskType { INSTAGRAM = 1, GENERIC = 2, OTHER = 3 };
  11. static constexpr const char* INSTAGRAM_NAME = "Instagram";
  12. /**
  13. * Files
  14. */
  15. enum FileType { VIDEO = 1, IMAGE = 2 };
  16. /**
  17. * KFileData
  18. *
  19. * Structure for holding file bytes and metadata
  20. */
  21. struct KFileData {
  22. QString name;
  23. FileType type;
  24. QString path;
  25. QByteArray bytes;
  26. // friend std::ostream &operator<<(std::ostream &out, const KFileData& file) {
  27. // out << "Name: " << file.name.toUtf8()
  28. // << "\nType: " << file.type;
  29. // return out;
  30. // }
  31. };
  32. /**
  33. * Type namespace
  34. *
  35. * Describes the types of task arguments available for use
  36. */
  37. namespace Type {
  38. static constexpr const char* TEXT = "Text";
  39. static constexpr const char* FILE = "File";
  40. static constexpr const char* STRINGVECTOR = "StringVector";
  41. static constexpr const char* FILEVECTOR = "FileVector";
  42. static constexpr const char* DATETIME = "DateTime";
  43. static constexpr const char* BOOLEAN = "Boolean";
  44. static constexpr const char* INTEGER = "Integer";
  45. } // namespace Type
  46. namespace VariantIndex {
  47. static const uint8_t BOOLEAN = 0;
  48. static const uint8_t INTEGER = 1;
  49. static const uint8_t STRVEC = 2;
  50. static const uint8_t QSTRING = 3;
  51. static const uint8_t FILEVEC = 4;
  52. } // namespace VariantIndex
  53. inline bool isIndex(uint8_t v, uint8_t i) { return v == i; }
  54. /**
  55. * Forward Declarations
  56. */
  57. class TaskArgumentBase;
  58. class Task;
  59. /**
  60. * Aliases
  61. */
  62. using TaskQueue = QQueue<Task*>;
  63. using ArgumentType = const char*;
  64. using ArgumentValues = QVector<QString>;
  65. using TypeVariant = std::variant<
  66. bool, int, QVector<QString>, QString, QVector<KFileData>
  67. >;
  68. using TaskIterator = std::vector<TaskArgumentBase*>::iterator;
  69. /**
  70. * The interface expected on our Task Arguments
  71. */
  72. class TaskArgumentBase {
  73. public:
  74. virtual const QString text() = 0;
  75. virtual const QString getStringValue() = 0;
  76. virtual uint8_t getTypeIndex() = 0;
  77. virtual TypeVariant getValue() = 0;
  78. virtual void insert(QString value) = 0;
  79. virtual void insert(KFileData file) = 0;
  80. virtual void remove(TypeVariant value) = 0;
  81. virtual void setValue(TypeVariant v) = 0;
  82. virtual bool isContainer() = 0;
  83. virtual void clear() = 0;
  84. };
  85. /**
  86. * TaskArgument
  87. *
  88. * A templated class providing a generic way for handling arguments whose types can be one from the set defined
  89. * by our TypeVariant alias
  90. */
  91. class TaskArgument : TaskArgumentBase {
  92. public:
  93. TaskArgument(QString n, ArgumentType t, TypeVariant _value) {
  94. name = n;
  95. type = t;
  96. value = _value;
  97. }
  98. /**
  99. * Move Constructor
  100. *
  101. * @constructor
  102. * @param [in] {TaskArgument&&} a The R-value reference to a TaskArgument
  103. */
  104. TaskArgument(TaskArgument&& a) :
  105. name(std::move(a.name)), type(std::move(a.type)), value(std::move(a.value)) {}
  106. /**
  107. * Copy Constructor
  108. *
  109. * @constructor
  110. * @param [in] {TaskArgument&&} a The const reference to a TaskArgument
  111. */
  112. TaskArgument(const TaskArgument& a) :
  113. name(std::move(a.name)), type(std::move(a.type)), value(std::move(a.value)) {}
  114. /**
  115. * text
  116. * @returns {QString} The name of the argument
  117. */
  118. virtual const QString text() override { return name; }
  119. /**
  120. * setValue
  121. * @param [in] {TypeVariant} new_value The new value for this argument
  122. */
  123. virtual void setValue(TypeVariant new_value) override {
  124. value = new_value;
  125. }
  126. /**
  127. * @brief getStringValue
  128. * @return [out] {QString}
  129. */
  130. virtual const QString getStringValue() override {
  131. if (isIndex(value.index(), VariantIndex::QSTRING)) {
  132. return std::get<VariantIndex::QSTRING>(value);
  133. } else if (isIndex(value.index(), VariantIndex::BOOLEAN)) {
  134. return QString::number(std::get<VariantIndex::BOOLEAN>(value));
  135. } else if (isIndex(value.index(), VariantIndex::INTEGER)) {
  136. return QString::number(std::get<VariantIndex::INTEGER>(value));
  137. }
  138. return ""; // Throw?
  139. }
  140. /**
  141. * @brief getValue
  142. * @return [out] {TypeVariant}
  143. */
  144. virtual TypeVariant getValue() override {
  145. if (isIndex(value.index(), VariantIndex::QSTRING)) {
  146. return std::get<VariantIndex::QSTRING>(value);
  147. } else if (isIndex(value.index(), VariantIndex::BOOLEAN)) {
  148. return std::get<VariantIndex::BOOLEAN>(value);
  149. } else if (isIndex(value.index(), VariantIndex::INTEGER)) {
  150. return std::get<VariantIndex::INTEGER>(value);
  151. } else if (isIndex(value.index(), VariantIndex::STRVEC)) {
  152. return std::get<VariantIndex::STRVEC>(value);
  153. } else if (isIndex(value.index(), VariantIndex::FILEVEC)) {
  154. return std::get<VariantIndex::FILEVEC>(value);
  155. }
  156. return ""; // Throw?
  157. }
  158. /**
  159. * @brief clear
  160. */
  161. virtual void clear() override {
  162. if (isIndex(value.index(), VariantIndex::STRVEC)) {
  163. std::get<VariantIndex::STRVEC>(value).clear();
  164. } else if (isIndex(value.index(), VariantIndex::FILEVEC)) {
  165. std::get<VariantIndex::FILEVEC>(value).clear();
  166. } else if (isIndex(value.index(), VariantIndex::QSTRING)) {
  167. std::get<VariantIndex::QSTRING>(value).clear();
  168. } else if (isIndex(value.index(), VariantIndex::INTEGER)) {
  169. std::get<VariantIndex::INTEGER>(value) = 0;
  170. } else if (isIndex(value.index(), VariantIndex::BOOLEAN)) {
  171. std::get<VariantIndex::BOOLEAN>(value) = false;
  172. }
  173. }
  174. /**
  175. * @brief isContainer
  176. * @return [out] {bool}
  177. */
  178. virtual bool isContainer() override {
  179. return (isIndex(value.index(), VariantIndex::STRVEC) || isIndex(value.index(), VariantIndex::FILEVEC));
  180. }
  181. /**
  182. * @brief insert
  183. * @param value
  184. */
  185. virtual void insert(QString string) override {
  186. if (isIndex(value.index(), VariantIndex::STRVEC)) {
  187. std::get<VariantIndex::STRVEC>(value).push_back(string);
  188. } else {
  189. // Unable to push. Throw?
  190. }
  191. }
  192. /**
  193. * @brief insert
  194. * @param file
  195. */
  196. virtual void insert(KFileData file) override {
  197. if (value.index() == VariantIndex::FILEVEC) {
  198. std::get<VariantIndex::FILEVEC>(value).push_back(file);
  199. } else {
  200. // Unable to push. Throw?
  201. }
  202. }
  203. /**
  204. * @brief remove
  205. * @param value
  206. */
  207. virtual void remove(TypeVariant unwanted_value) override {
  208. if (value.index() == VariantIndex::STRVEC && unwanted_value.index() == VariantIndex::QSTRING) {
  209. auto&& container = std::get<VariantIndex::STRVEC>(value);
  210. auto value_to_remove = std::get<VariantIndex::QSTRING>(unwanted_value);
  211. auto it = std::find_if(container.begin(), container.end(), [&value_to_remove](QString s) {
  212. return (s == value_to_remove);
  213. });
  214. if (it != container.end()) {
  215. container.erase(it);
  216. return;
  217. } else {
  218. throw std::out_of_range("Could not find value requested for removal");
  219. }
  220. } else if (value.index() == VariantIndex::FILEVEC && unwanted_value.index() == VariantIndex::QSTRING) {
  221. auto&& container = std::get<VariantIndex::FILEVEC>(value);
  222. auto file_to_remove = std::get<VariantIndex::QSTRING>(unwanted_value);
  223. auto it = std::find_if(container.begin(), container.end(), [&file_to_remove](Scheduler::KFileData f) {
  224. return (f.name == file_to_remove);
  225. });
  226. if (it != container.end()) {
  227. container.erase(it);
  228. return;
  229. } else {
  230. throw std::out_of_range("Could not find value requested for removal");
  231. }
  232. }
  233. throw std::invalid_argument("The value provided does not match any existing container");
  234. }
  235. /**
  236. * @brief getTypeIndex
  237. * @return
  238. */
  239. virtual uint8_t getTypeIndex() override {
  240. return value.index();
  241. }
  242. private:
  243. QString name;
  244. ArgumentType type;
  245. TypeVariant value;
  246. };
  247. using TaskArguments = std::vector<TaskArgument*>;
  248. /**
  249. * The interface expected to be implemented in all Task types
  250. */
  251. class Task {
  252. public:
  253. Task(){};
  254. Task(KFileData);
  255. Task(QVector<KFileData>);
  256. virtual void setArgument(QString name, TypeVariant arg) = 0;
  257. virtual void addArgument(QString name, Scheduler::KFileData file) = 0;
  258. virtual void addArgument(QString name, QString string) = 0;
  259. virtual void removeArgument(QString name, TypeVariant arg) = 0;
  260. virtual const TaskArguments&& getTaskArguments() = 0;
  261. virtual TaskArgument&& getTaskArgument(QString name) = 0;
  262. virtual const TypeVariant getTaskArgumentValue(QString name) = 0;
  263. virtual ArgumentValues getArgumentValues() = 0;
  264. virtual QVector<QString> getArgumentNames() = 0;
  265. virtual TaskType getType() = 0;
  266. virtual int getTaskCode() = 0;
  267. virtual void defineTaskArguments() = 0;
  268. virtual void setDefaultValues() = 0;
  269. virtual const QVector<KFileData> getFiles() = 0;
  270. virtual bool hasFiles() = 0;
  271. virtual bool isReady() = 0;
  272. virtual bool isEmpty() {
  273. bool empty = true;
  274. for (const auto& arg : getArgumentValues()) {
  275. if (!arg.isEmpty()) {
  276. empty = false;
  277. }
  278. }
  279. return empty;
  280. }
  281. virtual void clear() = 0;
  282. virtual ~Task(){};
  283. };
  284. } // namespace Scheduler
  285. #endif // __TASK_HPP__