Compare commits
7 Commits
61fd417013
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d04017ff58 | ||
|
|
72886e5676 | ||
|
|
d2836b92eb | ||
|
|
f67346231d | ||
|
|
d368fb8bc0 | ||
|
|
aa95418b70 | ||
|
|
6f5302043d |
2
base.inc
2
base.inc
@@ -50,7 +50,7 @@
|
|||||||
</header>
|
</header>
|
||||||
<main>{% content() %}</main>
|
<main>{% content() %}</main>
|
||||||
<footer>
|
<footer>
|
||||||
<p>Running Ikibooru v0.1</p>
|
<p>Running <a href="https://mid.net.ua/ikibooru.html">Ikibooru</a> v0.0.0.1</p>
|
||||||
</footer>
|
</footer>
|
||||||
<script defer src="/static/datetimes.js"></script>
|
<script defer src="/static/datetimes.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
4
core.lua
4
core.lua
@@ -192,9 +192,9 @@ local handler = function(req, res)
|
|||||||
|
|
||||||
local succ, val
|
local succ, val
|
||||||
if _ENV then
|
if _ENV then
|
||||||
succ, val = xpcall(Lyre.render, debug.traceback, tmpl, env)
|
succ, val = xpcall(Lyre.render, debug.traceback, tmpl, env, true)
|
||||||
else
|
else
|
||||||
succ, val = pcall(Lyre.render, tmpl, env)
|
succ, val = pcall(Lyre.render, tmpl, env, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
if succ then
|
if succ then
|
||||||
|
|||||||
61
index.html.l
61
index.html.l
@@ -2,32 +2,38 @@
|
|||||||
|
|
||||||
{% function content() %}
|
{% function content() %}
|
||||||
<div style="text-align:center;height:50%;margin-top:25vh;">
|
<div style="text-align:center;height:50%;margin-top:25vh;">
|
||||||
<div style="max-width:15cm;display:inline-block;">
|
<div style="width:12cm;display:inline-block;">
|
||||||
<h1>{{ Escapes.htmlescape(BigGlobe.cfg.sitename) }}</h1>
|
<h1>{{ Escapes.htmlescape(BigGlobe.cfg.sitename) }}</h1>
|
||||||
<form action="/search" method="GET" id="searchform">
|
<form action="/search" method="GET" id="searchform">
|
||||||
<input type="text" name="n" placeholder="Filter by name..." style="position:relative;width:100%;" />
|
<input type="text" name="n" placeholder="Filter by name..." style="position:relative;width:100%;" />
|
||||||
|
|
||||||
{% if BigGlobe.cfg.enable18plus then %}
|
|
||||||
<ul class="over18">
|
|
||||||
<li>
|
|
||||||
<input type="radio" name="a" value="-1" id="o18h" onchange="upd(-1)" checked />
|
|
||||||
<label for="o18h">Hide 18+</label>
|
|
||||||
</li><li>
|
|
||||||
<input type="radio" name="a" value="0" id="o18s" onchange="upd(0)" />
|
|
||||||
<label for="o18s">Show 18+</label>
|
|
||||||
</li><li>
|
|
||||||
<input type="radio" name="a" value="1" id="o18o" onchange="upd(1)" />
|
|
||||||
<label for="o18o">Only 18+</label>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
{% end %}
|
|
||||||
|
|
||||||
<input type="hidden" id="tparam" name="t" value="" />
|
<input type="hidden" id="tparam" name="t" value="" />
|
||||||
<div data-formid="searchform" data-formparaminputid="tparam" style="position:relative;width:100%;margin-top:1em;" class="tagbox">
|
|
||||||
<p>Filter by tags...</p>
|
<div style="position: relative;">
|
||||||
<span style="position:relative;min-width:4px;left:0;" contenteditable></span>
|
<div data-formid="searchform" data-formparaminputid="tparam" style="position:relative;width:58%;margin-top:1em;display:inline-block;vertical-align:top;white-space:nowrap;overflow-x:scroll;" class="tagbox">
|
||||||
|
<p>Filter by tags...</p>
|
||||||
|
|
||||||
|
<!-- Firefox has a 10-year old bug where a contenteditable with 0 padding loses focus when you press the right arrow key to the end -->
|
||||||
|
<span style="position:relative;min-width:4px;left:0;padding-right:1px;" contenteditable autofocus></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% if BigGlobe.cfg.enable18plus then %}
|
||||||
|
<ul class="over18" style="width:40%;display:inline-block;vertical-align:middle;">
|
||||||
|
<li>
|
||||||
|
<input type="radio" name="a" value="-1" id="o18h" onchange="upd(-1)" checked />
|
||||||
|
<label for="o18h">🛇</label>
|
||||||
|
</li><li>
|
||||||
|
<input type="radio" name="a" value="0" id="o18s" onchange="upd(0)" />
|
||||||
|
<label for="o18s">18+?</label>
|
||||||
|
</li><li>
|
||||||
|
<input type="radio" name="a" value="1" id="o18o" onchange="upd(1)" />
|
||||||
|
<label for="o18o">✓</label>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
{% end %}
|
||||||
|
|
||||||
|
<div class="autocomplete" style="visibility:hidden;width:100%;position:absolute;top:70%;box-sizing:border-box;"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="autocomplete" style="visibility:hidden;width:100%;"></div>
|
|
||||||
|
|
||||||
<input type="submit" value="Search" style="margin-top:1em;" />
|
<input type="submit" value="Search" style="margin-top:1em;" />
|
||||||
|
|
||||||
@@ -61,22 +67,33 @@
|
|||||||
var box = document.getElementById("alltags")
|
var box = document.getElementById("alltags")
|
||||||
var datags = []
|
var datags = []
|
||||||
ajax.responseText.split("\n").slice(0, -1).forEach(function(line) {
|
ajax.responseText.split("\n").slice(0, -1).forEach(function(line) {
|
||||||
|
var tagID = line.split(",")[0]
|
||||||
|
|
||||||
var newtag = document.createElement("div")
|
var newtag = document.createElement("div")
|
||||||
newtag.classList.toggle("tag")
|
newtag.classList.toggle("tag")
|
||||||
newtag.classList.toggle("tc" + line.split(",")[2])
|
newtag.classList.toggle("tc" + line.split(",")[2])
|
||||||
newtag.setAttribute("data-tagid", line.split(",")[0])
|
newtag.setAttribute("data-tagid", tagID)
|
||||||
newtag.setAttribute("data-tc", line.split(",")[2])
|
newtag.setAttribute("data-tc", line.split(",")[2])
|
||||||
newtag.innerText = line.split(",")[1]
|
newtag.innerText = line.split(",")[1]
|
||||||
|
|
||||||
datags.push(newtag)
|
datags.push(newtag)
|
||||||
})
|
})
|
||||||
datags.sort(function(a, b) {return a.getAttribute("data-tc") - b.getAttribute("data-tc")})
|
datags.sort(function(a, b) {return a.getAttribute("data-tc") - b.getAttribute("data-tc")})
|
||||||
datags.forEach(function(x) { box.insertBefore(x, null) })
|
datags.forEach(function(x) {
|
||||||
|
var newa = document.createElement("a")
|
||||||
|
newa.setAttribute("href", "/search?n=&t=" + x.getAttribute("data-tagid") + "&h");
|
||||||
|
newa.appendChild(x);
|
||||||
|
|
||||||
|
box.insertBefore(newa, null)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ajax.send()
|
ajax.send()
|
||||||
|
|
||||||
showalltags = function() {}
|
showalltags = function() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.querySelector("[autofocus]").focus()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{% end %}
|
{% end %}
|
||||||
|
|||||||
22
install.lua
22
install.lua
@@ -75,9 +75,23 @@ if baad then
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if not os.execute"adduser --shell /bin/sh --disabled-password ikibooru" then
|
if select(3, os.execute"id ikibooru") == 0 then
|
||||||
print"Failed to create user ikibooru."
|
while true do
|
||||||
return
|
io.stdout:write"User ikibooru already exists. Can use? (y/n): "
|
||||||
|
local o = io.read"*l":lower()
|
||||||
|
if o == "y" then
|
||||||
|
break
|
||||||
|
elseif o == "n" then
|
||||||
|
print"Exiting."
|
||||||
|
return
|
||||||
|
end
|
||||||
|
print"Try again."
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if not os.execute"useradd -U -m -s /bin/sh ikibooru" then
|
||||||
|
print"Failed to create user ikibooru."
|
||||||
|
return
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
io.stdout:write"MySQL host: "
|
io.stdout:write"MySQL host: "
|
||||||
@@ -301,4 +315,4 @@ end
|
|||||||
|
|
||||||
print""
|
print""
|
||||||
|
|
||||||
print"Installation complete. Remember: Ikibooru is only an HTTP server. It must be used together with a relay or reverse proxy."
|
print"Installation complete. Reminder: Ikibooru is only an HTTP server. It must be used together with a relay or reverse proxy."
|
||||||
|
|||||||
24
login.html.l
24
login.html.l
@@ -19,9 +19,15 @@
|
|||||||
worked = false
|
worked = false
|
||||||
end
|
end
|
||||||
|
|
||||||
if worked and BigGlobe.cfg.anarchy == "ANARCHY" then
|
if BigGlobe.cfg.anarchy == "ANARCHY" then
|
||||||
response:addHeader("Refresh", "3;url=" .. zzz)
|
if u and u.privs > DB.USER_PRIVS_APPROVED then
|
||||||
response:statusCode(303)
|
worked = false
|
||||||
|
end
|
||||||
|
|
||||||
|
if worked then
|
||||||
|
response:addHeader("Refresh", "3;url=" .. zzz)
|
||||||
|
response:statusCode(303)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -30,9 +36,13 @@
|
|||||||
|
|
||||||
{% function content() %}
|
{% function content() %}
|
||||||
{% if BigGlobe.cfg.anarchy == "ANARCHY" then %}
|
{% if BigGlobe.cfg.anarchy == "ANARCHY" then %}
|
||||||
<p>In anarchy mode, anyone can be anything. Please wait..</p>
|
{% if worked and zzz then %}
|
||||||
|
<p>In anarchy mode, anyone can be anything. Please wait..</p>
|
||||||
<p>If that doesn't work, <a href="{{ Escapes.htmlescape(zzz) }}">click here</a>.</p>
|
|
||||||
|
<p>If that doesn't work, <a href="{{ Escapes.htmlescape(zzz) }}">click here</a>.</p>
|
||||||
|
{% else %}
|
||||||
|
<p>User doesn't exist.</p>
|
||||||
|
{% end %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% if worked then %}
|
{% if worked then %}
|
||||||
<p>Link has been sent to {{ em and Escapes.htmlescape(em) }}. This page may be closed.</p>
|
<p>Link has been sent to {{ em and Escapes.htmlescape(em) }}. This page may be closed.</p>
|
||||||
@@ -42,4 +52,4 @@
|
|||||||
{% end %}
|
{% end %}
|
||||||
{% end %}
|
{% end %}
|
||||||
|
|
||||||
{# base.inc
|
{# base.inc
|
||||||
|
|||||||
@@ -55,7 +55,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
<div>
|
<div>
|
||||||
{% for _,tag in pairs(DB.getobjtags(obj.id)) do %}
|
{% for _,tag in pairs(DB.getobjtags(obj.id)) do %}
|
||||||
<div class="tag tc{{ tag.category }}" data-tagid="{{ tag.id }}">{{ Escapes.htmlescape(tag.name) }}</div>
|
<a href="/search?n=&t={{ tag.id }}&o"><div class="tag tc{{ tag.category }}" data-tagid="{{ tag.id }}">{{ Escapes.htmlescape(tag.name) }}</div></a>
|
||||||
{% end %}
|
{% end %}
|
||||||
</div>
|
</div>
|
||||||
{% if verified and verified.privs >= DB.USER_PRIVS_APPROVED then %}
|
{% if verified and verified.privs >= DB.USER_PRIVS_APPROVED then %}
|
||||||
|
|||||||
14
smtpauth.lua
14
smtpauth.lua
@@ -9,21 +9,19 @@ assert(Rand.ready())
|
|||||||
local DB = require"db"
|
local DB = require"db"
|
||||||
|
|
||||||
local function sendeml(raw)
|
local function sendeml(raw)
|
||||||
--[[local fn = "/tmp/ikibooru" .. DB.b256toreadable(Rand.bytes(16)) .. ".eml"
|
local fn = "/tmp/ikibooru" .. DB.b256toreadable(Rand.bytes(16)) .. ".eml"
|
||||||
local f = io.open(fn, "wb")
|
local f = io.open(fn, "wb")
|
||||||
f:write(raw)
|
f:write(raw)
|
||||||
f:close()
|
f:close()
|
||||||
|
|
||||||
-- Send e-mail. Yes, this is crude.
|
-- Send e-mail. Yes, this is crude, but we have one thread.
|
||||||
io.popen("{ sendmail -t < " .. fn .. "; rm " .. fn .. "; } &", "r")]]
|
io.popen("{ sendmail -t < " .. fn .. "; rm " .. fn .. "; } &", "r")
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
sendauthinfo = function(user)
|
sendauthinfo = function(user)
|
||||||
local url = BigGlobe.cfg.domain .."/verif?q=" .. Escapes.urlescape(DB.userauth(user))
|
local url = BigGlobe.cfg.domain .."/verif?q=" .. Escapes.urlescape(DB.userauth(user))
|
||||||
|
|
||||||
-- print(url)
|
|
||||||
|
|
||||||
if BigGlobe.cfg.anarchy == "ANARCHY" then
|
if BigGlobe.cfg.anarchy == "ANARCHY" then
|
||||||
return url
|
return url
|
||||||
else
|
else
|
||||||
@@ -42,8 +40,6 @@ MIME-Version: 1.0
|
|||||||
sendregisterinfo = function(user)
|
sendregisterinfo = function(user)
|
||||||
local url = BigGlobe.cfg.domain .."/reg?q=" .. Escapes.urlescape(DB.userregcode(user))
|
local url = BigGlobe.cfg.domain .."/reg?q=" .. Escapes.urlescape(DB.userregcode(user))
|
||||||
|
|
||||||
print(url)
|
|
||||||
|
|
||||||
if BigGlobe.cfg.anarchy == "ANARCHY" then
|
if BigGlobe.cfg.anarchy == "ANARCHY" then
|
||||||
return url
|
return url
|
||||||
else
|
else
|
||||||
@@ -53,9 +49,9 @@ Content-Type: text/html; charset=UTF-8
|
|||||||
MIME-Version: 1.0
|
MIME-Version: 1.0
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html><body style="font-family:sans-serif;"><p>You have either registered or been invited to register at %s. Click on the below link to complete your registration.</p><p>If you have no idea what this is, consider whether your e-mail account has been compromised.</p><a href="%s"><div style="display:inline-block;font-size:1.2em;padding:0.5em 1em 0.5em 1em;border:1px solid gray;color:#C0C0C0;border-radius:6px;"><span>Complete</span></div></a></body></html>]], user.email, BigGlobe.cfg.sitename, BigGlobe.cfg.sitename, url))
|
<html><body style="font-family:sans-serif;"><p>You have either registered or been invited to register at %s. Click on the below link to complete your registration.</p><p>If you had not initiated a registration request, consider whether your e-mail account has been compromised.</p><a href="%s"><div style="display:inline-block;font-size:1.2em;padding:0.5em 1em 0.5em 1em;border:1px solid gray;color:#C0C0C0;border-radius:6px;"><span>Complete</span></div></a></body></html>]], user.email, BigGlobe.cfg.sitename, BigGlobe.cfg.sitename, url))
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ div.tag {
|
|||||||
border: 1px solid blue;
|
border: 1px solid blue;
|
||||||
padding: 0.1em;
|
padding: 0.1em;
|
||||||
margin: 0.1em;
|
margin: 0.1em;
|
||||||
|
color: black;
|
||||||
}
|
}
|
||||||
div.tag.selected {
|
div.tag.selected {
|
||||||
border-width: 2px;
|
border-width: 2px;
|
||||||
|
|||||||
@@ -47,25 +47,22 @@ document.querySelector("div.tagbox span").onkeydown = function(ev) {
|
|||||||
}
|
}
|
||||||
} else if(ev.keyCode == 40) {
|
} else if(ev.keyCode == 40) {
|
||||||
ev.preventDefault()
|
ev.preventDefault()
|
||||||
var sel = document.querySelector("div.autocomplete > div.tag.selected")
|
var alltags = Array.from(document.querySelectorAll("div.autocomplete div.tag"))
|
||||||
if(sel) {
|
var sel = alltags.findIndex(function(x) { return x.classList.contains("selected") })
|
||||||
sel.classList.toggle("selected")
|
if(sel != -1) alltags[sel].classList.toggle("selected")
|
||||||
sel = sel.nextElementSibling
|
sel = (sel + 1) % alltags.length
|
||||||
} else {
|
alltags[sel].classList.toggle("selected")
|
||||||
sel = document.querySelectorAll("div.autocomplete > div.tag")[0]
|
|
||||||
}
|
|
||||||
if(sel) sel.classList.toggle("selected")
|
|
||||||
} else if(ev.keyCode == 38) {
|
} else if(ev.keyCode == 38) {
|
||||||
ev.preventDefault()
|
ev.preventDefault()
|
||||||
var sel = document.querySelector("div.autocomplete > div.tag.selected")
|
var alltags = Array.from(document.querySelectorAll("div.autocomplete div.tag"))
|
||||||
if(sel) {
|
var sel = alltags.findIndex(function(x) { return x.classList.contains("selected") })
|
||||||
sel.classList.toggle("selected")
|
if(sel != -1) {
|
||||||
sel = sel.previousElementSibling
|
alltags[sel].classList.toggle("selected")
|
||||||
|
sel = (sel + alltags.length - 1) % alltags.length
|
||||||
} else {
|
} else {
|
||||||
var asdf = document.querySelectorAll("div.autocomplete > div.tag")
|
sel = alltags.length - 1
|
||||||
sel = asdf[asdf.length - 1]
|
|
||||||
}
|
}
|
||||||
if(sel) sel.classList.toggle("selected")
|
alltags[sel].classList.toggle("selected")
|
||||||
} else if(ev.keyCode == 8 && !document.querySelector("div.tagbox span").innerText.length) {
|
} else if(ev.keyCode == 8 && !document.querySelector("div.tagbox span").innerText.length) {
|
||||||
ev.preventDefault()
|
ev.preventDefault()
|
||||||
|
|
||||||
@@ -96,7 +93,16 @@ document.querySelector("div.tagbox span").oninput = function(ev) {
|
|||||||
ac.innerText = "No such tags found"
|
ac.innerText = "No such tags found"
|
||||||
} else {
|
} else {
|
||||||
ajax.responseText.split("\n").slice(0, -1).forEach(function(line) {
|
ajax.responseText.split("\n").slice(0, -1).forEach(function(line) {
|
||||||
ac.insertBefore(createtag(line.split(",")[1], line.split(",")[2], line.split(",")[0]), null)
|
var tag = createtag(line.split(",")[1], line.split(",")[2], line.split(",")[0])
|
||||||
|
tag.onclick = function() {
|
||||||
|
var sel = document.querySelector("div.tag.selected")
|
||||||
|
if(sel) sel.classList.toggle("selected")
|
||||||
|
this.classList.toggle("selected")
|
||||||
|
var span = document.querySelector("div.tagbox span")
|
||||||
|
span.focus()
|
||||||
|
span.dispatchEvent(new KeyboardEvent('keydown', {bubbles: true, cancelable: true, keyCode: 13}))
|
||||||
|
}
|
||||||
|
ac.insertBefore(tag, null)
|
||||||
})
|
})
|
||||||
|
|
||||||
if(UnknownTagsMode) {
|
if(UnknownTagsMode) {
|
||||||
|
|||||||
Reference in New Issue
Block a user