task.hpp 10.0 KB

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