OptionalManagerPlugin.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import time
  2. import collections
  3. from util import helper
  4. from Plugin import PluginManager
  5. import ContentDbPlugin
  6. def processAccessLog():
  7. if access_log:
  8. content_db = ContentDbPlugin.content_db
  9. now = int(time.time())
  10. num = 0
  11. for site_id in access_log:
  12. content_db.execute(
  13. "UPDATE file_optional SET time_accessed = %s WHERE ?" % now,
  14. {"site_id": site_id, "inner_path": access_log[site_id].keys()}
  15. )
  16. num += len(access_log[site_id])
  17. access_log.clear()
  18. def processRequestLog():
  19. if request_log:
  20. content_db = ContentDbPlugin.content_db
  21. cur = content_db.getCursor()
  22. num = 0
  23. cur.execute("BEGIN")
  24. for site_id in request_log:
  25. for inner_path, uploaded in request_log[site_id].iteritems():
  26. content_db.execute(
  27. "UPDATE file_optional SET uploaded = uploaded + %s WHERE ?" % uploaded,
  28. {"site_id": site_id, "inner_path": inner_path}
  29. )
  30. num += 1
  31. cur.execute("END")
  32. request_log.clear()
  33. if "access_log" not in locals().keys(): # To keep between module reloads
  34. access_log = collections.defaultdict(dict) # {site_id: {inner_path1: 1, inner_path2: 1...}}
  35. request_log = collections.defaultdict(lambda: collections.defaultdict(int)) # {site_id: {inner_path1: 1, inner_path2: 1...}}
  36. helper.timer(61, processAccessLog)
  37. helper.timer(60, processRequestLog)
  38. @PluginManager.registerTo("WorkerManager")
  39. class WorkerManagerPlugin(object):
  40. def doneTask(self, task):
  41. if task["optional_hash_id"]:
  42. content_db = self.site.content_manager.contents.db
  43. content_db.executeDelayed(
  44. "UPDATE file_optional SET time_downloaded = :now, is_downloaded = 1, peer = peer + 1 WHERE site_id = :site_id AND inner_path = :inner_path",
  45. {"now": int(time.time()), "site_id": content_db.site_ids[self.site.address], "inner_path": task["inner_path"]}
  46. )
  47. super(WorkerManagerPlugin, self).doneTask(task)
  48. if task["optional_hash_id"] and not self.tasks:
  49. content_db.processDelayed()
  50. @PluginManager.registerTo("UiRequest")
  51. class UiRequestPlugin(object):
  52. def parsePath(self, path):
  53. global access_log
  54. path_parts = super(UiRequestPlugin, self).parsePath(path)
  55. if path_parts:
  56. site_id = ContentDbPlugin.content_db.site_ids.get(path_parts["request_address"])
  57. if site_id:
  58. if ContentDbPlugin.content_db.isOptionalFile(site_id, path_parts["inner_path"]):
  59. access_log[site_id][path_parts["inner_path"]] = 1
  60. return path_parts
  61. @PluginManager.registerTo("FileRequest")
  62. class FileRequestPlugin(object):
  63. def actionGetFile(self, params):
  64. stats = super(FileRequestPlugin, self).actionGetFile(params)
  65. self.recordFileRequest(params["site"], params["inner_path"], stats)
  66. return stats
  67. def actionStreamFile(self, params):
  68. stats = super(FileRequestPlugin, self).actionStreamFile(params)
  69. self.recordFileRequest(params["site"], params["inner_path"], stats)
  70. return stats
  71. def recordFileRequest(self, site_address, inner_path, stats):
  72. if not stats:
  73. # Only track the last request of files
  74. return False
  75. site_id = ContentDbPlugin.content_db.site_ids[site_address]
  76. if site_id and ContentDbPlugin.content_db.isOptionalFile(site_id, inner_path):
  77. request_log[site_id][inner_path] += stats["bytes_sent"]
  78. @PluginManager.registerTo("Site")
  79. class SitePlugin(object):
  80. def isDownloadable(self, inner_path):
  81. is_downloadable = super(SitePlugin, self).isDownloadable(inner_path)
  82. if is_downloadable:
  83. return is_downloadable
  84. for path in self.settings.get("optional_help", {}).iterkeys():
  85. if inner_path.startswith(path):
  86. return True
  87. return False
  88. @PluginManager.registerTo("ConfigPlugin")
  89. class ConfigPlugin(object):
  90. def createArguments(self):
  91. group = self.parser.add_argument_group("OptionalManager plugin")
  92. group.add_argument('--optional_limit', help='Limit total size of optional files', default="10%", metavar="GB or free space %")
  93. return super(ConfigPlugin, self).createArguments()