db.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. from pymongo import MongoClient,errors,DESCENDING,ASCENDING
  2. from bson.objectid import ObjectId
  3. import datetime
  4. import re
  5. import news
  6. import pytz
  7. class db():
  8. DB="alexis"
  9. def __init__(self):
  10. self.client = MongoClient('localhost', 27017)
  11. self.c_sources=self.client[self.DB]["sources"]
  12. self.c_articles=self.client[self.DB]["articles"]
  13. def change_timezone(self,el):
  14. gmt = pytz.timezone("America/Buenos_Aires")
  15. est = pytz.timezone('US/Eastern')
  16. #est = pytz.timezone('America/Boston')
  17. fmt = '%Y-%m-%d %H:%M:%S %Z%z'
  18. #print(el["scrap_date"])
  19. el["scrap_date"]=gmt.localize(el["scrap_date"])
  20. #print(el["scrap_date"])
  21. el["scrap_date"]=el["scrap_date"].astimezone(est)
  22. #print(el["scrap_date"])
  23. el["scrap_date"]=el["scrap_date"].strftime(fmt)
  24. #print(el["scrap_date"])
  25. #el["scrap_date"]=est.astimezone(el["scrap_date" ])
  26. #est.localize(el["scrap_date"])
  27. return el
  28. def jsonable(self, el):
  29. if el is None or "_id" not in el:
  30. return el
  31. el["_id"]=str(el["_id"])
  32. return el
  33. def filter_articles(self, filter, limit=80):
  34. db_filter={}
  35. db_filter["matches"]=True
  36. db_filter["deleted"]=False
  37. db_filter["scrap_date"]={}
  38. if "maxdate" in filter and len(filter["maxdate"])>7:
  39. db_filter["scrap_date"]["$lt"]=datetime.datetime.strptime(filter["maxdate"],"%Y-%m-%d")
  40. if "mindate" in filter and len(filter["mindate"])>7:
  41. db_filter["scrap_date"]["$gt"]=datetime.datetime.strptime(filter["mindate"],"%Y-%m-%d")
  42. if db_filter["scrap_date"]=={}:
  43. del db_filter["scrap_date"]
  44. if "title" in filter and filter["title"] != "":
  45. filter["title"]=filter["title"].replace("(","\(").replace(")","\)")
  46. db_filter["title"]={"$regex":".*%s.*"%filter["title"], "$options": 'i'}
  47. if "site" in filter and filter["site"] != "":
  48. filter["site"]=filter["site"].replace("(","\(").replace(")","\)")
  49. db_filter["source_name"]={"$regex":".*%s.*"%filter["site"], "$options": 'i'}
  50. #db_filter["$or"]=[
  51. # {"source_name": {"$regex":".*%s.*"%filter["site"], "$options": 'i'}},
  52. # {"url": {"$regex":".*%s.*"%filter["site"], "$options": 'i' }}
  53. # ]
  54. if "minweight" not in filter or not isinstance(filter["minweight"],int):
  55. filter["minweight"]=1
  56. db_filter["weight"]={"$gt":int(filter["minweight"])}
  57. if "keyword" in filter and len(filter["keyword"]) >0:
  58. db_filter["kw"]={"$all": filter["keyword"]}
  59. #db_filter["kw.0"]={"$exists":False}
  60. pageNumber=0
  61. if "page" in filter:
  62. pageNumber=filter["page"]
  63. #print(db_filter)
  64. res = self.c_articles.find(db_filter,{"html":0,"text":0})
  65. if res is not None:
  66. toSkip=(((pageNumber-1)*limit) if pageNumber > 0 else 0)
  67. q = res.skip(toSkip).sort("scrap_date",DESCENDING).limit(limit)
  68. count = q.count()
  69. else:
  70. q = []
  71. count = 0
  72. return { 'articles': [ self.jsonable(self.change_timezone(p)) for p in q ],
  73. 'count' : count }
  74. def article(self, id):
  75. ret=self.c_articles.find_one({"_id":ObjectId(id)})
  76. return self.jsonable(ret)
  77. def delete_article(self,artid):
  78. return self.c_articles.update({"_id":ObjectId(artid)},{"$set":{"deleted":True}})
  79. def undelete_article(self,artid):
  80. return self.c_articles.update({"_id":ObjectId(artid)},{"$set":{"deleted":False}})
  81. def sources(self,id=None):
  82. if id is None:
  83. return [ self.jsonable(p) for p in self.c_sources.find() ]
  84. ret=self.c_sources.find_one({"_id":ObjectId(id)})
  85. return self.jsonable(ret)
  86. def rss_sources(self):
  87. return [ p for p in self.c_sources.find({"rss":1}) ]
  88. def insert_article(self,o):
  89. try:
  90. self.c_articles.insert_one(o)
  91. return True
  92. except errors.DuplicateKeyError:
  93. print("Dup")
  94. return False
  95. def purge_error(self):
  96. self.c_articles.remove({'error':True})
  97. def article_exists(self,url):
  98. ret=self.c_articles.find_one({'url':url})
  99. if ret is None:
  100. return False
  101. return True
  102. def lower_arr(self,arr):
  103. return [a.lower() for a in arr]
  104. def to_regex(self,arr): #"ACH" | "PAYMENT" | "EBAY"
  105. return [ re.compile('\\b'+w.lower()+'\\b') for w in arr ]
  106. def get_keywords_list(self):
  107. kw=self.client[self.DB]["keywords"]
  108. return [ k["keyword"] for k in kw.find({}) ]
  109. def get_keywords(self,category):
  110. kw=self.client[self.DB]["keywords"] #FIXME, split on "|" or regex
  111. ret = [ {"weight":k["weight"],
  112. "kw": k["keyword"],
  113. "pattern": self.to_regex(k["keyword"].split("|")) } for k in kw.find({}) ]#FIXME, categories
  114. return ret
  115. def add_source(self,url,rss,selector,name):
  116. self.c_sources.insert({"link":url,
  117. "rss":rss,
  118. "selector":selector,
  119. "name":name,
  120. "category":0})
  121. def reparse_articles(self,articles,kw):
  122. for a in articles:
  123. #print(a)
  124. art=self.c_articles.find_one({"url":a["url"]})
  125. res=news.match_keywords(kw,art["text"])
  126. #(matches,w_sum,matching)
  127. #if(res["matches"]):
  128. print(res)
  129. self.c_articles.update({"_id":ObjectId(a["_id"])}, {"$set": res })
  130. #matches, kw, weight