qmanager.py 4.5 KB

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