NewsfeedPlugin.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. import time
  2. import re
  3. from Plugin import PluginManager
  4. from Db import DbQuery
  5. @PluginManager.registerTo("UiWebsocket")
  6. class UiWebsocketPlugin(object):
  7. def formatSiteInfo(self, site, create_user=True):
  8. site_info = super(UiWebsocketPlugin, self).formatSiteInfo(site, create_user=True)
  9. feed_following = self.user.sites[site.address].get("follow", None)
  10. if feed_following == None:
  11. site_info["feed_follow_num"] = None
  12. else:
  13. site_info["feed_follow_num"] = len(feed_following)
  14. return site_info
  15. def actionFeedFollow(self, to, feeds):
  16. self.user.setFeedFollow(self.site.address, feeds)
  17. self.user.save()
  18. self.response(to, "ok")
  19. def actionFeedListFollow(self, to):
  20. feeds = self.user.sites[self.site.address].get("follow", {})
  21. self.response(to, feeds)
  22. def actionFeedQuery(self, to, limit=10, day_limit=3):
  23. if "ADMIN" not in self.site.settings["permissions"]:
  24. return self.response(to, "FeedQuery not allowed")
  25. from Site import SiteManager
  26. rows = []
  27. for address, site_data in self.user.sites.iteritems():
  28. feeds = site_data.get("follow")
  29. if not feeds:
  30. continue
  31. if type(feeds) is not dict:
  32. self.log.debug("Invalid feed for site %s" % address)
  33. continue
  34. for name, query_set in feeds.iteritems():
  35. site = SiteManager.site_manager.get(address)
  36. try:
  37. query, params = query_set
  38. query_parts = query.split("UNION")
  39. for i, query_part in enumerate(query_parts):
  40. db_query = DbQuery(query_part)
  41. if day_limit:
  42. where = " WHERE %s > strftime('%%s', 'now', '-%s day')" % (db_query.fields.get("date_added", "date_added"), day_limit)
  43. if "WHERE" in query_part:
  44. query_part = re.sub("WHERE (.*?)(?=$| GROUP BY)", where+" AND (\\1)", query_part)
  45. else:
  46. query_part += where
  47. query_parts[i] = query_part
  48. query = " UNION ".join(query_parts)
  49. if ":params" in query:
  50. query = query.replace(":params", ",".join(["?"] * len(params)))
  51. res = site.storage.query(query + " ORDER BY date_added DESC LIMIT %s" % limit, params)
  52. else:
  53. res = site.storage.query(query + " ORDER BY date_added DESC LIMIT %s" % limit)
  54. except Exception, err: # Log error
  55. self.log.error("%s feed query %s error: %s" % (address, name, err))
  56. continue
  57. for row in res:
  58. row = dict(row)
  59. if row["date_added"] > 1000000000000: # Formatted as millseconds
  60. row["date_added"] = row["date_added"] / 1000
  61. if "date_added" not in row or row["date_added"] > time.time() + 120:
  62. self.log.debug("Newsfeed from the future from from site %s" % address)
  63. continue # Feed item is in the future, skip it
  64. row["site"] = address
  65. row["feed_name"] = name
  66. rows.append(row)
  67. return self.response(to, rows)
  68. def actionFeedSearch(self, to, search):
  69. if "ADMIN" not in self.site.settings["permissions"]:
  70. return self.response(to, "FeedSearch not allowed")
  71. from Site import SiteManager
  72. rows = []
  73. num_sites = 0
  74. s = time.time()
  75. for address, site in SiteManager.site_manager.list().iteritems():
  76. if not site.storage.has_db:
  77. continue
  78. if site.storage.db: # Database loaded
  79. feeds = site.storage.db.schema.get("feeds")
  80. else:
  81. try:
  82. feeds = site.storage.loadJson("dbschema.json").get("feeds")
  83. except:
  84. continue
  85. if not feeds:
  86. continue
  87. num_sites += 1
  88. for name, query in feeds.iteritems():
  89. try:
  90. db_query = DbQuery(query)
  91. db_query.wheres.append("%s LIKE ? OR %s LIKE ?" % (db_query.fields["body"], db_query.fields["title"]))
  92. db_query.parts["ORDER BY"] = "date_added DESC"
  93. db_query.parts["LIMIT"] = "30"
  94. search_like = "%" + search.replace(" ", "%") + "%"
  95. res = site.storage.query(str(db_query), [search_like, search_like])
  96. except Exception, err:
  97. self.log.error("%s feed query %s error: %s" % (address, name, err))
  98. continue
  99. for row in res:
  100. row = dict(row)
  101. if row["date_added"] > time.time() + 120:
  102. continue # Feed item is in the future, skip it
  103. row["site"] = address
  104. row["feed_name"] = name
  105. rows.append(row)
  106. return self.response(to, {"rows": rows, "num": len(rows), "sites": num_sites, "taken": time.time() - s})
  107. @PluginManager.registerTo("User")
  108. class UserPlugin(object):
  109. # Set queries that user follows
  110. def setFeedFollow(self, address, feeds):
  111. site_data = self.getSiteData(address)
  112. site_data["follow"] = feeds
  113. self.save()
  114. return site_data