import time import json import os import re from Plugin import PluginManager from Translate import Translate from Config import config from util import helper if os.path.isfile("%s/mutes.json" % config.data_dir): try: data = json.load(open("%s/mutes.json" % config.data_dir)) mutes = data.get("mutes", {}) site_blacklist = data.get("site_blacklist", {}) except Exception as err: mutes = {} site_blacklist = {} else: open("%s/mutes.json" % config.data_dir, "w").write('{"mutes": {}, "site_blacklist": {}}') mutes = {} site_blacklist = {} if "_" not in locals(): _ = Translate("plugins/Mute/languages/") @PluginManager.registerTo("UiWebsocket") class UiWebsocketPlugin(object): # Search and remove or readd files of an user def changeDb(self, auth_address, action): self.log.debug("Mute action %s on user %s" % (action, auth_address)) res = self.site.content_manager.contents.db.execute( "SELECT * FROM content LEFT JOIN site USING (site_id) WHERE inner_path LIKE :inner_path", {"inner_path": "%%/%s/%%" % auth_address} ) for row in res: site = self.server.sites.get(row["address"]) if not site: continue dir_inner_path = helper.getDirname(row["inner_path"]) for file_name in site.storage.walk(dir_inner_path): if action == "remove": site.storage.onUpdated(dir_inner_path + file_name, False) else: site.storage.onUpdated(dir_inner_path + file_name) site.onFileDone(dir_inner_path + file_name) def cbMuteAdd(self, to, auth_address, cert_user_id, reason): mutes[auth_address] = {"cert_user_id": cert_user_id, "reason": reason, "source": self.site.address, "date_added": time.time()} self.saveMutes() self.changeDb(auth_address, "remove") self.response(to, "ok") def actionMuteAdd(self, to, auth_address, cert_user_id, reason): if "ADMIN" in self.getPermissions(to): self.cbMuteAdd(to, auth_address, cert_user_id, reason) else: self.cmd( "confirm", [_["Hide all content from %s?"] % cert_user_id, _["Mute"]], lambda (res): self.cbMuteAdd(to, auth_address, cert_user_id, reason) ) def cbMuteRemove(self, to, auth_address): del mutes[auth_address] self.saveMutes() self.changeDb(auth_address, "load") self.response(to, "ok") def actionMuteRemove(self, to, auth_address): if "ADMIN" in self.getPermissions(to): self.cbMuteRemove(to, auth_address) else: self.cmd( "confirm", [_["Unmute %s?"] % mutes[auth_address]["cert_user_id"], _["Unmute"]], lambda (res): self.cbMuteRemove(to, auth_address) ) def actionMuteList(self, to): if "ADMIN" in self.getPermissions(to): self.response(to, mutes) else: return self.response(to, {"error": "Only ADMIN sites can list mutes"}) # Blacklist def actionBlacklistAdd(self, to, site_address, reason=None): if "ADMIN" not in self.getPermissions(to): return self.response(to, {"error": "Forbidden, only admin sites can add to blacklist"}) site_blacklist[site_address] = {"date_added": time.time(), "reason": reason} self.saveMutes() self.response(to, "ok") def actionBlacklistRemove(self, to, site_address): if "ADMIN" not in self.getPermissions(to): return self.response(to, {"error": "Forbidden, only admin sites can remove from blacklist"}) del site_blacklist[site_address] self.saveMutes() self.response(to, "ok") def actionBlacklistList(self, to): if "ADMIN" in self.getPermissions(to): self.response(to, site_blacklist) else: return self.response(to, {"error": "Only ADMIN sites can list blacklists"}) # Write mutes and blacklist to json file def saveMutes(self): helper.atomicWrite("%s/mutes.json" % config.data_dir, json.dumps({"mutes": mutes, "site_blacklist": site_blacklist}, indent=2, sort_keys=True)) @PluginManager.registerTo("SiteStorage") class SiteStoragePlugin(object): def updateDbFile(self, inner_path, file=None, cur=None): if file is not False: # File deletion always allowed # Find for bitcoin addresses in file path matches = re.findall("/(1[A-Za-z0-9]{26,35})/", inner_path) # Check if any of the adresses are in the mute list for auth_address in matches: if auth_address in mutes: self.log.debug("Mute match: %s, ignoring %s" % (auth_address, inner_path)) return False return super(SiteStoragePlugin, self).updateDbFile(inner_path, file=file, cur=cur) @PluginManager.registerTo("UiRequest") class UiRequestPlugin(object): def actionWrapper(self, path, extra_headers=None): match = re.match("/(?P
[A-Za-z0-9\._-]+)(?P/.*|$)", path) if not match: return False address = match.group("address") if self.server.site_manager.get(address): # Site already exists return super(UiRequestPlugin, self).actionWrapper(path, extra_headers) if self.server.site_manager.isDomain(address): address = self.server.site_manager.resolveDomain(address) if address in site_blacklist: site = self.server.site_manager.get(config.homepage) if not extra_headers: extra_headers = {} self.sendHeader(extra_headers=extra_headers) return iter([super(UiRequestPlugin, self).renderWrapper( site, path, "uimedia/plugins/mute/blacklisted.html?address=" + address, "Blacklisted site", extra_headers, show_loadingscreen=False )]) else: return super(UiRequestPlugin, self).actionWrapper(path, extra_headers) def actionUiMedia(self, path, *args, **kwargs): if path.startswith("/uimedia/plugins/mute/"): file_path = path.replace("/uimedia/plugins/mute/", "plugins/Mute/media/") return self.actionFile(file_path) else: return super(UiRequestPlugin, self).actionUiMedia(path)