qmanager.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. #!/usr/bin/env python3
  2. """Manage a list of book-jobs,
  3. return a description list for the website"""
  4. import os
  5. import shlex
  6. import re
  7. from time import time
  8. from bot import IRCClient
  9. class qManager:
  10. """Main module class"""
  11. tasks = []
  12. last_id = 0
  13. PATH = ""
  14. def __init__(self, update_cb, path="/tmp/books/"):
  15. """Init the manager. Set output path"""
  16. if not os.path.isdir(path):
  17. os.makedirs(path, exist_ok=True)
  18. self.PATH = path
  19. self.update_cb = update_cb
  20. def new_dl(self, string):
  21. """Download a book"""
  22. irc_client = IRCClient(
  23. string, "", "BOOK",
  24. cb=self.update_cb,
  25. logging=False,
  26. path=self.PATH)
  27. self.new_task(string, irc_client)
  28. def new_search(self, keywords, fmt):
  29. """Search for a book"""
  30. irc_client = IRCClient(
  31. keywords,
  32. fmt,
  33. "SEARCH",
  34. cb=self.update_cb,
  35. logging=False,
  36. path=self.PATH)
  37. self.new_task(keywords, irc_client)
  38. def new_task(self, query, t):
  39. """ Add a new 'task' to the list """
  40. nt = task(query, t, self.last_id)
  41. self.last_id += 1
  42. self.tasks.append(nt)
  43. def search_status(self):
  44. return [ t for t in self.task_status() if t["TYPE"]=='SEARCH' ]
  45. def books_status(self):
  46. return [ t for t in self.task_status() if t["TYPE"]=='BOOK' ]
  47. def task_status(self):
  48. """ Return a dict with the status of each 'task' """
  49. ret = []
  50. for t in self.tasks:
  51. elapsed = time() - t.START_TIME
  52. ret.append({"ID": t.ID,
  53. "STATUS": t.get_status(),
  54. "PROGRESS": t.get_progress(),
  55. "OUT": t.get_output(),
  56. "ELAPSED": int(elapsed),
  57. "QUERY": t.QUERY,
  58. "EXTRA": t.get_extra(),
  59. "TYPE": t.get_type()})
  60. return ret
  61. class task:
  62. """ Task class. Only returns a status"""
  63. CUR_STATUS = ""
  64. OUTPUT = ""
  65. ID = 0
  66. CLIENT = None
  67. START_TIME = None
  68. QUERY = ""
  69. def __init__(self, query, c, _id):
  70. """Initialize the task"""
  71. self.QUERY = query
  72. self.CLIENT = c
  73. self.ID = _id
  74. self.START_TIME = time()
  75. def get_progress(self):
  76. """ Return progress."""
  77. return self.CLIENT.PROGRESS
  78. def get_extra(self):
  79. """ Return extra output."""
  80. return self.CLIENT.EXTRA_OUTPUT
  81. def get_status(self):
  82. """ Return status. If timed out since last call, stop task """
  83. if time() - self.START_TIME > 600:
  84. self.CLIENT.do_timeout()
  85. self.OUTPUT = self.CLIENT.OUTPUT
  86. return self.CLIENT.STATUS
  87. def get_type(self):
  88. """ Return type """
  89. return self.CLIENT.TYPE
  90. def get_output(self):
  91. """Return output:
  92. If it's just a string, return it (Books).
  93. If it's a list, parse it and return a representative dict.
  94. Should cache this or something, doesn't make sense to
  95. calculate on each call.
  96. """
  97. if isinstance(self.OUTPUT, str) or self.OUTPUT is None:
  98. return self.OUTPUT
  99. TAGS_R = re.compile(r'[\[(].*?[\])]|\.rar|v\d.*?\s')
  100. books = self.OUTPUT
  101. ret = []
  102. for book in books:
  103. book = book.replace("---", "")
  104. groups = re.search(
  105. r"(?P<BOT>^!\w+)(?P<BOOK>.*?)(?P<INFO>::INFO.*)?$", book)
  106. if groups is None:
  107. #print("[No groups] %s" % book)
  108. return books
  109. groups = groups.groupdict()
  110. # remove tags from book
  111. groups["BOOK"] = re.sub(TAGS_R, "", groups["BOOK"])
  112. groups["TAGS"] = [r.strip("()[]")
  113. for r in re.findall(TAGS_R, book)]
  114. groups["TEXT"] = book
  115. ret.append(groups)
  116. return ret
  117. # BASIC CLI INTERFACE
  118. if __name__ == "__main__":
  119. q = qManager()
  120. while True:
  121. line = input()
  122. words = shlex.split(line)
  123. print(q.task_status())
  124. if len(words) < 2:
  125. continue
  126. comm = words[0]
  127. if comm.lower() == "quit":
  128. break
  129. if comm.lower() == "search":
  130. if len(words) < 3:
  131. continue
  132. q.new_search(words[1], words[2])
  133. continue
  134. if comm.lower() == "dl":
  135. q.new_dl(words[1])
  136. continue
  137. print("search <'multiple keywords'> <format>|dl <line>|quit")