| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- from threading import Thread
- from ircclient import IRCClient, MODE_SEARCH, MODE_BOOK
- import logging
- import queue
- import subprocess
- logging.basicConfig(level=logging.DEBUG)
- log = logging.getLogger(__name__)
- log.setLevel(logging.DEBUG)
- def get_books_from_list(filename):
- f = open(filename, "r")
- ret = []
- for line in f.readlines():
- line = line.lower().strip()
- if not line.startswith('!') or not any(_type in line for _type in ['epub', 'mobi']):
- continue
- ret.append(line)
- log.info("Book matches: %s", line)
- ret = list(set(ret)) # dedup
- return ret
- def mode_from_files(files):
- for f in files:
- f = f.lower()
- if 'searchbot' in f or 'searchook' in f.lower():
- return MODE_SEARCH
- return MODE_BOOK
- def handle_files(files):
- log.info("Unarchived files %s", files)
- out = []
- mode = mode_from_files(files)
- if mode == MODE_SEARCH:
- for f in files:
- if "searchbot" not in f.lower() and "searchook" not in f.lower():
- continue
- out.extend(get_books_from_list(f))
- return out
- for f in files:
- if f.lower().endswith(".epub"):
- log.info("EPUB %s", f)
- new_fname = f.replace("epub", "mobi")
- p = subprocess.Popen(["ebook-convert", f, new_fname], stdout=subprocess.DEVNULL)
- # TODO log to file?
- p.wait()
- out.append(new_fname)
- out.append(f)
- # TODO make paths absolute?
- return out
- def handle_results(q, cb):
- while True:
- try:
- item = q.get(timeout=1)
- if item is None:
- break
- except queue.Empty:
- continue
- log.info("Got a result! %s", item)
- if item['type'] == 'status':
- cb((item['key'], item['status']))
- elif item['type'] == 'files':
- cb(handle_files(item['files']))
- class BookClient:
- workers = []
- def __init__(self, cb):
- self.q = queue.Queue()
- self.rq = queue.Queue()
- self.results_t = Thread(target=handle_results, args=(self.rq, cb))
- self.results_t.daemon = True
- self.results_t.start()
- self.create_worker()
- def create_worker(self):
- print("Spawning a new worker")
- worker = IRCClient(command_queue=self.q, results_queue=self.rq)
- worker.start()
- self.workers.append(worker)
- def free_workers(self):
- return any([not worker.busy for worker in self.workers])
- def request(self, mode, query):
- if not self.free_workers():
- self.create_worker()
- if mode not in [MODE_SEARCH, MODE_BOOK]:
- print('Invalid mode')
- return
- self.q.put({'query': query, 'mode': mode})
- print("Command acknowledged")
- def __del__(self):
- print("Cleaning up workers")
- for worker in self.workers:
- worker.stop()
- worker.join(timeout=5)
- print("Cleaning up results")
- self.rq.put(None)
- self.results_t.join(timeout=5)
|