| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- #!/usr/bin/python3
- import threading
- from queue import Queue
- from db import db
- from source import Source
- from linklist import LinkList
- from news import News
- from paid_parser import PaidParser
- from time import strftime,time
- from multiprocessing import Pool
- import sys
- from analytics import post_data
- def parseSource(s):
- init = time()
- q = Queue()
- sel = None
- rss = False
- if "selector" in s:
- sel = s["selector"]
- if "rss" in s:
- rss = bool(s["rss"])
- l = LinkList(s["link"], sel, rss=rss)
- d = db()
- kw = d.get_keywords(s["category"])
- new_articles = 0
- if l is not None:
- for a in l.links:
- if not d.article_exists(a.lower(), s["_id"]):
- q.put(a)
- # print("[%s][Source] %s: %d/%d new/total articles" %
- # (strftime("%H:%M:%S"), s["name"], q.qsize(), len(l.links)))
- new_articles = q.qsize()
- if not q.empty():
- num_worker_threads = min(5, q.qsize())
- threads = []
- for _ in range(num_worker_threads):
- t = threading.Thread(target=news_worker, args=[s, kw, d, q])
- # source, keywords, db, queue
- t.daemon = True
- t.start()
- threads.append(t)
- q.join() # block until all tasks are done
- for _ in range(num_worker_threads):
- # put num_worker empty jobs so
- # each worker can work once
- q.put(None)
- for t in threads:
- t.join(10)
- ex_time = time()-init
- print("[%s][Source] %s => Finished parsing, %d/%d new articles, in %0.3fsec" %
- (strftime("%H:%M:%S"),
- s["name"], new_articles, len(l.links), ex_time))
- sys.stdout.flush()
- return (ex_time, len(l.links), s["name"], new_articles)
- def news_worker(source, kw, d, q):
- source_id = source["_id"]
- source_name = source["name"]
- source_category = source["category"]
- paid = False
- if "paid" in source and source["paid"]:
- paid = True
- # tname = threading.current_thread().name
- while True:
- try:
- item = q.get(timeout=5)
- except:
- # print("Failed to get item")
- q.task_done()
- break
- if item is None:
- q.task_done()
- break
- # print("[Thread %s] %s" % (tname,item))
- try:
- html = None
- if paid:
- p = PaidParser(item)
- html = p.html
- n = News(item, source_id, source_name,
- source_category, kw, html=html)
- # print("[Thread %s] Finished" % tname)
- d.insert_article(n.get())
- except Exception as e:
- print("#### EXCEPTION ########")
- print(e)
- print(item)
- print("#### END EXCEPTION ####")
- finally:
- q.task_done()
- post_data('event', {}, '"start"')
- start = time()
- print("init db")
- d = db()
- print("init sources")
- sources = d.sources()
- print("cnt error")
- post_data('value', {'type': 'error'}, d.count_error())
- post_data('event', {}, '"purge_error_finish"')
- d.purge_error()
- post_data('event', {}, '"purge_error_finish"')
- pool = Pool(processes=4)
- ret = pool.map(parseSource, sources)
- new = sum([r[3] for r in ret])
- tot = sum([r[1] for r in ret])
- post_data('value', {'type': 'new'}, new)
- post_data('value', {'type': 'total'}, tot)
- # n = sum(ret)
- # sret = sorted(ret, key=lambda tup: tup[0])
- # print(sret)
- print("[%s] %d/%d new articles, total time %d sec" %
- (strftime("%H:%M:%S"), new, tot, time()-start))
- post_data('time', {'type': 'total'}, time()-start)
- print("#" * 75)
- post_data('value', {'type': 'error'}, d.count_error())
- post_data('event', {}, '"end"')
|