Site blacklist to Mute plugin
This commit is contained in:
parent
bf042ce7a3
commit
9ec050341b
3 changed files with 220 additions and 3 deletions
|
@ -11,12 +11,16 @@ from util import helper
|
||||||
|
|
||||||
if os.path.isfile("%s/mutes.json" % config.data_dir):
|
if os.path.isfile("%s/mutes.json" % config.data_dir):
|
||||||
try:
|
try:
|
||||||
mutes = json.load(open("%s/mutes.json" % config.data_dir))["mutes"]
|
data = json.load(open("%s/mutes.json" % config.data_dir))
|
||||||
|
mutes = data.get("mutes", {})
|
||||||
|
site_blacklist = data.get("site_blacklist", {})
|
||||||
except Exception, err:
|
except Exception, err:
|
||||||
mutes = {}
|
mutes = {}
|
||||||
|
site_blacklist = {}
|
||||||
else:
|
else:
|
||||||
open("%s/mutes.json" % config.data_dir, "w").write('{"mutes": {}}')
|
open("%s/mutes.json" % config.data_dir, "w").write('{"mutes": {}, "site_blacklist": {}}')
|
||||||
mutes = {}
|
mutes = {}
|
||||||
|
site_blacklist = {}
|
||||||
|
|
||||||
if "_" not in locals():
|
if "_" not in locals():
|
||||||
_ = Translate("plugins/Mute/languages/")
|
_ = Translate("plugins/Mute/languages/")
|
||||||
|
@ -81,8 +85,30 @@ class UiWebsocketPlugin(object):
|
||||||
else:
|
else:
|
||||||
return self.response(to, {"error": "Only ADMIN sites can list mutes"})
|
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):
|
def saveMutes(self):
|
||||||
helper.atomicWrite("%s/mutes.json" % config.data_dir, json.dumps({"mutes": mutes}, indent=2, sort_keys=True))
|
helper.atomicWrite("%s/mutes.json" % config.data_dir, json.dumps({"mutes": mutes, "site_blacklist": site_blacklist}, indent=2, sort_keys=True))
|
||||||
|
|
||||||
|
|
||||||
@PluginManager.registerTo("SiteStorage")
|
@PluginManager.registerTo("SiteStorage")
|
||||||
|
@ -98,3 +124,37 @@ class SiteStoragePlugin(object):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return super(SiteStoragePlugin, self).updateDbFile(inner_path, file=file, cur=cur)
|
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<address>[A-Za-z0-9\._-]+)(?P<inner_path>/.*|$)", 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, site.address + "//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)
|
||||||
|
|
64
plugins/Mute/media/blacklisted.html
Normal file
64
plugins/Mute/media/blacklisted.html
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.content { line-height: 24px; font-family: monospace; font-size: 14px; color: #636363; text-transform: uppercase; top: 38%; position: relative; text-align: center; perspective: 1000px }
|
||||||
|
.content h1, .content h2 { font-weight: normal; letter-spacing: 1px; }
|
||||||
|
.content h2 { font-size: 15px; }
|
||||||
|
.content #details {
|
||||||
|
text-align: left; display: inline-block; width: 350px; background-color: white; padding: 17px 27px; border-radius: 0px;
|
||||||
|
box-shadow: 0px 2px 7px -1px #d8d8d8; text-transform: none; margin: 15px; transform: scale(0) rotateX(90deg); transition: all 0.6s cubic-bezier(0.785, 0.135, 0.15, 0.86);
|
||||||
|
}
|
||||||
|
.content #details #added { font-size: 12px; text-align: right; color: #a9a9a9; }
|
||||||
|
|
||||||
|
#button { transition: all 1s cubic-bezier(0.075, 0.82, 0.165, 1); opacity: 0; transform: translateY(50px); transition-delay: 0.5s }
|
||||||
|
.button {
|
||||||
|
padding: 8px 20px; background-color: #FFF85F; border-bottom: 2px solid #CDBD1E; border-radius: 2px;
|
||||||
|
text-decoration: none; transition: all 0.5s; background-position: left center; display: inline-block; margin-top: 10px; color: black;
|
||||||
|
}
|
||||||
|
.button:hover { background-color: #FFF400; border-bottom: 2px solid #4D4D4C; transition: none; }
|
||||||
|
.button:active { position: relative; top: 1px; }
|
||||||
|
.button:focus { outline: none; }
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
<h1>Site blocked</h1>
|
||||||
|
<h2>This site is on your blacklist:</h2>
|
||||||
|
<div id="details">
|
||||||
|
<div id="reason">Too much image</div>
|
||||||
|
<div id="added">on 2015-01-25 12:32:11</div>
|
||||||
|
</div>
|
||||||
|
<div><a href="#Visit+Site" class="button button-submit" id="button">Remove from blacklist</a></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="js/ZeroFrame.js"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
class Page extends ZeroFrame {
|
||||||
|
onOpenWebsocket () {
|
||||||
|
this.cmd("wrapperSetTitle", "Blacklisted site - ZeroNet")
|
||||||
|
this.cmd("siteInfo", {}, (site_info) => {
|
||||||
|
this.site_info = site_info
|
||||||
|
})
|
||||||
|
this.cmd("blacklistList", {}, (blacklists) => {
|
||||||
|
this.blacklists = blacklists
|
||||||
|
var address = document.location.search.match(/address=(.*?)[&\?]/)[1]
|
||||||
|
var reason = blacklists[address]["reason"]
|
||||||
|
if (!reason) reason = "Unknown reason"
|
||||||
|
var date = new Date(blacklists[address]["date_added"] * 1000)
|
||||||
|
document.getElementById("reason").innerText = reason
|
||||||
|
document.getElementById("added").innerText = "at " + date.toLocaleDateString() + " " + date.toLocaleTimeString()
|
||||||
|
document.getElementById("details").style.transform = "scale(1) rotateX(0deg)"
|
||||||
|
document.getElementById("button").style.transform = "translateY(0)"
|
||||||
|
document.getElementById("button").style.opacity = "1"
|
||||||
|
document.getElementById("button").onclick = () => {
|
||||||
|
this.cmd("blacklistRemove", address, () => { this.cmd("wrapperReload") })
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
page = new Page()
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
93
plugins/Mute/media/js/ZeroFrame.js
Normal file
93
plugins/Mute/media/js/ZeroFrame.js
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
const CMD_INNER_READY = 'innerReady'
|
||||||
|
const CMD_RESPONSE = 'response'
|
||||||
|
const CMD_WRAPPER_READY = 'wrapperReady'
|
||||||
|
const CMD_PING = 'ping'
|
||||||
|
const CMD_PONG = 'pong'
|
||||||
|
const CMD_WRAPPER_OPENED_WEBSOCKET = 'wrapperOpenedWebsocket'
|
||||||
|
const CMD_WRAPPER_CLOSE_WEBSOCKET = 'wrapperClosedWebsocket'
|
||||||
|
|
||||||
|
class ZeroFrame {
|
||||||
|
constructor(url) {
|
||||||
|
this.url = url
|
||||||
|
this.waiting_cb = {}
|
||||||
|
this.wrapper_nonce = document.location.href.replace(/.*wrapper_nonce=([A-Za-z0-9]+).*/, "$1")
|
||||||
|
this.connect()
|
||||||
|
this.next_message_id = 1
|
||||||
|
this.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
connect() {
|
||||||
|
this.target = window.parent
|
||||||
|
window.addEventListener('message', e => this.onMessage(e), false)
|
||||||
|
this.cmd(CMD_INNER_READY)
|
||||||
|
}
|
||||||
|
|
||||||
|
onMessage(e) {
|
||||||
|
let message = e.data
|
||||||
|
let cmd = message.cmd
|
||||||
|
if (cmd === CMD_RESPONSE) {
|
||||||
|
if (this.waiting_cb[message.to] !== undefined) {
|
||||||
|
this.waiting_cb[message.to](message.result)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.log("Websocket callback not found:", message)
|
||||||
|
}
|
||||||
|
} else if (cmd === CMD_WRAPPER_READY) {
|
||||||
|
this.cmd(CMD_INNER_READY)
|
||||||
|
} else if (cmd === CMD_PING) {
|
||||||
|
this.response(message.id, CMD_PONG)
|
||||||
|
} else if (cmd === CMD_WRAPPER_OPENED_WEBSOCKET) {
|
||||||
|
this.onOpenWebsocket()
|
||||||
|
} else if (cmd === CMD_WRAPPER_CLOSE_WEBSOCKET) {
|
||||||
|
this.onCloseWebsocket()
|
||||||
|
} else {
|
||||||
|
this.onRequest(cmd, message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onRequest(cmd, message) {
|
||||||
|
this.log("Unknown request", message)
|
||||||
|
}
|
||||||
|
|
||||||
|
response(to, result) {
|
||||||
|
this.send({
|
||||||
|
cmd: CMD_RESPONSE,
|
||||||
|
to: to,
|
||||||
|
result: result
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd(cmd, params={}, cb=null) {
|
||||||
|
this.send({
|
||||||
|
cmd: cmd,
|
||||||
|
params: params
|
||||||
|
}, cb)
|
||||||
|
}
|
||||||
|
|
||||||
|
send(message, cb=null) {
|
||||||
|
message.wrapper_nonce = this.wrapper_nonce
|
||||||
|
message.id = this.next_message_id
|
||||||
|
this.next_message_id++
|
||||||
|
this.target.postMessage(message, '*')
|
||||||
|
if (cb) {
|
||||||
|
this.waiting_cb[message.id] = cb
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log(...args) {
|
||||||
|
console.log.apply(console, ['[ZeroFrame]'].concat(args))
|
||||||
|
}
|
||||||
|
|
||||||
|
onOpenWebsocket() {
|
||||||
|
this.log('Websocket open')
|
||||||
|
}
|
||||||
|
|
||||||
|
onCloseWebsocket() {
|
||||||
|
this.log('Websocket close')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue