get rid of useless tabs and spaces
parent
b0b70d2f0f
commit
044664a25e
|
@ -4,7 +4,7 @@ ARG DEBIAN_FRONTEND=noninteractive
|
|||
|
||||
RUN apt update
|
||||
RUN apt -y upgrade
|
||||
RUN apt install -y supervisor
|
||||
RUN apt install -y supervisor
|
||||
RUN apt install -y python3-pip
|
||||
RUN apt install -y ffmpeg
|
||||
RUN apt install -y postgresql
|
||||
|
|
|
@ -174,7 +174,7 @@ blockquote {
|
|||
}
|
||||
|
||||
blockquote a {
|
||||
color: skyblue;
|
||||
color: skyblue;
|
||||
}
|
||||
|
||||
.unread {
|
||||
|
|
|
@ -106,7 +106,7 @@ blockquote {
|
|||
}
|
||||
|
||||
.comment-collapse-icon::before {
|
||||
color: var(--gray-500) !important
|
||||
color: var(--gray-500) !important
|
||||
}
|
||||
|
||||
.text-admin {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
--secondary: #c7c7c7;
|
||||
--gray: #c7c7c7;
|
||||
--gray-300: #c7c7c7;
|
||||
--gray-400: #cfcfcf;
|
||||
--gray-400: #cfcfcf;
|
||||
--gray-500: #ffffff;
|
||||
--gray-600: #ffffff;
|
||||
--gray-700: #ffffff;
|
||||
|
|
|
@ -6574,7 +6574,7 @@ body > .container {
|
|||
|
||||
.emoji2 {
|
||||
/*background: None!important;*/
|
||||
width:60px;
|
||||
width:60px;
|
||||
height: 85px;
|
||||
overflow: hidden;
|
||||
border: none
|
||||
|
|
|
@ -35,7 +35,7 @@ body, .navbar-light, .navbar-dark, .card, .modal-content, .comment-write textare
|
|||
}
|
||||
|
||||
.modal .comment-actions .list-group-item {
|
||||
background-color: var(--gray-600)!important;
|
||||
background-color: var(--gray-600)!important;
|
||||
}
|
||||
|
||||
.page-link {
|
||||
|
|
|
@ -33,7 +33,7 @@ h1, h2, h3, h4, h5, h6 {
|
|||
}
|
||||
|
||||
.button {
|
||||
background-color: rgb(var(--background))!important;
|
||||
background-color: rgb(var(--background))!important;
|
||||
background: 0 0;
|
||||
font-weight: 600;
|
||||
font-size: 1rem;
|
||||
|
|
|
@ -133,7 +133,7 @@
|
|||
{"name":"oplus", "class":"Marsey Alphabet", "tags": ["⊕","xor","circled","sum"]},
|
||||
{"name":"otimes", "class":"Marsey Alphabet", "tags": ["⊗","tensor","circled","product"]},
|
||||
{"name":"trianglelefteq", "class":"Marsey Alphabet", "tags": ["⊴"]},
|
||||
|
||||
|
||||
{"name":"marseyflagmaryland","class":"Marsey Flags"},
|
||||
{"name":"marseyflagcalifornia","class":"Marsey Flags"},
|
||||
{"name":"marseyflagtexas","class":"Marsey Flags"},
|
||||
|
|
|
@ -213,40 +213,40 @@ body {
|
|||
background-color: #1f1f1f;
|
||||
background-blend-mode: soft-light;
|
||||
}
|
||||
|
||||
|
||||
.color {
|
||||
width: 20%;
|
||||
height: 100%;
|
||||
float: left
|
||||
}
|
||||
|
||||
|
||||
.color p {
|
||||
position: relative;
|
||||
z-index: 1231231;
|
||||
text-align: center;
|
||||
line-height: 90vh;
|
||||
}
|
||||
|
||||
|
||||
.color:nth-child(1){
|
||||
background-color: #F5624D;
|
||||
}
|
||||
|
||||
|
||||
.color:nth-child(2){
|
||||
background-color: #CC231E;
|
||||
}
|
||||
|
||||
|
||||
.color:nth-child(3){
|
||||
background-color: #34A65F;
|
||||
}
|
||||
|
||||
|
||||
.color:nth-child(4){
|
||||
background-color: #0F8A5F;
|
||||
}
|
||||
|
||||
|
||||
.color:nth-child(5){
|
||||
background-color: #235E6F;
|
||||
}
|
||||
|
||||
|
||||
#snow:not([data-nonce]) {
|
||||
height: 100%;
|
||||
color: #FFF;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
function snow(flakesMax) {
|
||||
// --- common properties ---
|
||||
|
||||
|
||||
this.autoStart = true; // Whether the snow should start automatically or not.
|
||||
this.excludeMobile = false; // Snow is likely to be bad news for mobile phones' CPUs (and batteries.) Enable at your own risk.
|
||||
this.flakesMax = flakesMax; // Limit total amount of snow made (falling + sticking)
|
||||
|
@ -32,9 +32,9 @@ function snow(flakesMax) {
|
|||
this.useTwinkleEffect = false; // Allow snow to randomly "flicker" in and out of view while falling
|
||||
this.usePositionFixed = false; // true = snow does not shift vertically when scrolling. May increase CPU load, disabled by default - if enabled, used only where supported
|
||||
this.usePixelPosition = false; // Whether to use pixel values for snow top/left vs. percentages. Auto-enabled if body is position:relative or targetElement is specified.
|
||||
|
||||
|
||||
// --- less-used bits ---
|
||||
|
||||
|
||||
this.freezeOnBlur = true; // Only snow when the window is in focus (foreground.) Saves CPU.
|
||||
this.flakeLeftOffset = 0; // Left margin/gutter space on edge of container (eg. browser window.) Bump up these values if seeing horizontal scrollbars.
|
||||
this.flakeRightOffset = 0; // Right margin/gutter space on edge of container
|
||||
|
@ -43,9 +43,9 @@ function snow(flakesMax) {
|
|||
this.vMaxX = 5; // Maximum X velocity range for snow
|
||||
this.vMaxY = 4; // Maximum Y velocity range for snow
|
||||
this.zIndex = 0; // CSS stacking order applied to each snowflake
|
||||
|
||||
|
||||
// --- "No user-serviceable parts inside" past this point, yadda yadda ---
|
||||
|
||||
|
||||
var storm = this,
|
||||
features,
|
||||
// UA sniffing and backCompat rendering mode checks for fixed position, etc.
|
||||
|
@ -76,20 +76,20 @@ function snow(flakesMax) {
|
|||
})(),
|
||||
didInit = false,
|
||||
docFrag = document.createDocumentFragment();
|
||||
|
||||
|
||||
features = (function () {
|
||||
var getAnimationFrame;
|
||||
|
||||
|
||||
/**
|
||||
* hat tip: paul irish
|
||||
* http://paulirish.com/2011/requestanimationframe-for-smart-animating/
|
||||
* https://gist.github.com/838785
|
||||
*/
|
||||
|
||||
|
||||
function timeoutShim(callback) {
|
||||
window.setTimeout(callback, 1000 / (storm.animationInterval || 20));
|
||||
}
|
||||
|
||||
|
||||
var _animationFrame =
|
||||
window.requestAnimationFrame ||
|
||||
window.webkitRequestAnimationFrame ||
|
||||
|
@ -97,24 +97,24 @@ function snow(flakesMax) {
|
|||
window.oRequestAnimationFrame ||
|
||||
window.msRequestAnimationFrame ||
|
||||
timeoutShim;
|
||||
|
||||
|
||||
// apply to window, avoid "illegal invocation" errors in Chrome
|
||||
getAnimationFrame = _animationFrame
|
||||
? function () {
|
||||
return _animationFrame.apply(window, arguments);
|
||||
}
|
||||
: null;
|
||||
|
||||
|
||||
var testDiv;
|
||||
|
||||
|
||||
testDiv = document.createElement("div");
|
||||
|
||||
|
||||
function has(prop) {
|
||||
// test for feature support
|
||||
var result = testDiv.style[prop];
|
||||
return result !== undefined ? prop : null;
|
||||
}
|
||||
|
||||
|
||||
// note local scope.
|
||||
var localFeatures = {
|
||||
transform: {
|
||||
|
@ -125,34 +125,34 @@ function snow(flakesMax) {
|
|||
w3: has("transform"),
|
||||
prop: null // the normalized property value
|
||||
},
|
||||
|
||||
|
||||
getAnimationFrame: getAnimationFrame
|
||||
};
|
||||
|
||||
|
||||
localFeatures.transform.prop =
|
||||
localFeatures.transform.w3 ||
|
||||
localFeatures.transform.moz ||
|
||||
localFeatures.transform.webkit ||
|
||||
localFeatures.transform.ie ||
|
||||
localFeatures.transform.opera;
|
||||
|
||||
|
||||
testDiv = null;
|
||||
|
||||
|
||||
return localFeatures;
|
||||
})();
|
||||
|
||||
|
||||
this.timer = null;
|
||||
this.flakes = [];
|
||||
this.disabled = false;
|
||||
this.active = false;
|
||||
this.meltFrameCount = 20;
|
||||
this.meltFrames = [];
|
||||
|
||||
|
||||
this.setXY = function (o, x, y) {
|
||||
if (!o) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (storm.usePixelPosition || targetElementIsRelative) {
|
||||
o.style.left = x - storm.flakeWidth + "px";
|
||||
o.style.top = y - storm.flakeHeight + "px";
|
||||
|
@ -172,7 +172,7 @@ function snow(flakesMax) {
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
this.events = (function () {
|
||||
var old = !window.addEventListener && window.attachEvent,
|
||||
slice = Array.prototype.slice,
|
||||
|
@ -180,7 +180,7 @@ function snow(flakesMax) {
|
|||
add: old ? "attachEvent" : "addEventListener",
|
||||
remove: old ? "detachEvent" : "removeEventListener"
|
||||
};
|
||||
|
||||
|
||||
function getArgs(oArgs) {
|
||||
var args = slice.call(oArgs),
|
||||
len = args.length;
|
||||
|
@ -194,7 +194,7 @@ function snow(flakesMax) {
|
|||
}
|
||||
return args;
|
||||
}
|
||||
|
||||
|
||||
function apply(args, sType) {
|
||||
var element = args.shift(),
|
||||
method = [evt[sType]];
|
||||
|
@ -204,32 +204,32 @@ function snow(flakesMax) {
|
|||
element[method].apply(element, args);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function addEvent() {
|
||||
apply(getArgs(arguments), "add");
|
||||
}
|
||||
|
||||
|
||||
function removeEvent() {
|
||||
apply(getArgs(arguments), "remove");
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
add: addEvent,
|
||||
remove: removeEvent
|
||||
};
|
||||
})();
|
||||
|
||||
|
||||
function rnd(n, min) {
|
||||
if (isNaN(min)) {
|
||||
min = 0;
|
||||
}
|
||||
return Math.random() * n + min;
|
||||
}
|
||||
|
||||
|
||||
function plusMinus(n) {
|
||||
return parseInt(rnd(2), 10) === 1 ? n * -1 : n;
|
||||
}
|
||||
|
||||
|
||||
this.randomizeWind = function () {
|
||||
var i;
|
||||
vRndX = plusMinus(rnd(storm.vMaxX, 0.2));
|
||||
|
@ -242,7 +242,7 @@ function snow(flakesMax) {
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
this.scrollHandler = function () {
|
||||
var i;
|
||||
// "attach" snowflakes to bottom of window if no absolute bottom value was given
|
||||
|
@ -265,7 +265,7 @@ function snow(flakesMax) {
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
this.resizeHandler = function () {
|
||||
if (window.innerWidth || window.innerHeight) {
|
||||
screenX = window.innerWidth - 16 - storm.flakeRightOffset;
|
||||
|
@ -286,14 +286,14 @@ function snow(flakesMax) {
|
|||
docHeight = document.body.offsetHeight;
|
||||
screenX2 = parseInt(screenX / 2, 10);
|
||||
};
|
||||
|
||||
|
||||
this.resizeHandlerAlt = function () {
|
||||
screenX = storm.targetElement.offsetWidth - storm.flakeRightOffset;
|
||||
screenY = storm.flakeBottom || storm.targetElement.offsetHeight;
|
||||
screenX2 = parseInt(screenX / 2, 10);
|
||||
docHeight = document.body.offsetHeight;
|
||||
};
|
||||
|
||||
|
||||
this.freeze = function () {
|
||||
// pause animation
|
||||
if (!storm.disabled) {
|
||||
|
@ -303,7 +303,7 @@ function snow(flakesMax) {
|
|||
}
|
||||
storm.timer = null;
|
||||
};
|
||||
|
||||
|
||||
this.resume = function () {
|
||||
if (storm.disabled) {
|
||||
storm.disabled = 0;
|
||||
|
@ -312,7 +312,7 @@ function snow(flakesMax) {
|
|||
}
|
||||
storm.timerInit();
|
||||
};
|
||||
|
||||
|
||||
this.toggleSnow = function () {
|
||||
if (!storm.flakes.length) {
|
||||
// first run
|
||||
|
@ -328,7 +328,7 @@ function snow(flakesMax) {
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
this.stop = function () {
|
||||
var i;
|
||||
this.freeze();
|
||||
|
@ -347,14 +347,14 @@ function snow(flakesMax) {
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
this.show = function () {
|
||||
var i;
|
||||
for (i = 0; i < this.flakes.length; i++) {
|
||||
this.flakes[i].o.style.display = "block";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
this.SnowFlake = function (type, x, y) {
|
||||
var s = this;
|
||||
this.type = type;
|
||||
|
@ -390,7 +390,7 @@ function snow(flakesMax) {
|
|||
this.o.style.fontWeight = "normal";
|
||||
this.o.style.zIndex = storm.zIndex;
|
||||
docFrag.appendChild(this.o);
|
||||
|
||||
|
||||
this.refresh = function () {
|
||||
if (isNaN(s.x) || isNaN(s.y)) {
|
||||
// safety check
|
||||
|
@ -398,7 +398,7 @@ function snow(flakesMax) {
|
|||
}
|
||||
storm.setXY(s.o, s.x, s.y);
|
||||
};
|
||||
|
||||
|
||||
this.stick = function () {
|
||||
if (
|
||||
noFixed ||
|
||||
|
@ -415,7 +415,7 @@ function snow(flakesMax) {
|
|||
s.o.style.display = "block";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
this.vCheck = function () {
|
||||
if (s.vX >= 0 && s.vX < 0.2) {
|
||||
s.vX = 0.2;
|
||||
|
@ -426,7 +426,7 @@ function snow(flakesMax) {
|
|||
s.vY = 0.2;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
this.move = function () {
|
||||
var vX = s.vX * windOffset,
|
||||
yDiff;
|
||||
|
@ -481,25 +481,25 @@ function snow(flakesMax) {
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
this.animate = function () {
|
||||
// main animation loop
|
||||
// move, check status, die etc.
|
||||
s.move();
|
||||
};
|
||||
|
||||
|
||||
this.setVelocities = function () {
|
||||
s.vX = vRndX + rnd(storm.vMaxX * 0.12, 0.1);
|
||||
s.vY = vRndY + rnd(storm.vMaxY * 0.12, 0.1);
|
||||
};
|
||||
|
||||
|
||||
this.setOpacity = function (o, opacity) {
|
||||
if (!opacitySupported) {
|
||||
return false;
|
||||
}
|
||||
o.style.opacity = opacity;
|
||||
};
|
||||
|
||||
|
||||
this.melt = function () {
|
||||
if (!storm.useMeltEffect || !s.melting) {
|
||||
s.recycle();
|
||||
|
@ -519,7 +519,7 @@ function snow(flakesMax) {
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
this.recycle = function () {
|
||||
s.o.style.display = "none";
|
||||
s.o.style.position = fixedForEverything ? "fixed" : "absolute";
|
||||
|
@ -541,11 +541,11 @@ function snow(flakesMax) {
|
|||
s.o.style.display = "block";
|
||||
s.active = 1;
|
||||
};
|
||||
|
||||
|
||||
this.recycle(); // set up x/y coords etc.
|
||||
this.refresh();
|
||||
};
|
||||
|
||||
|
||||
this.snow = function () {
|
||||
var active = 0,
|
||||
flake = null,
|
||||
|
@ -570,7 +570,7 @@ function snow(flakesMax) {
|
|||
features.getAnimationFrame(storm.snow);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
this.mouseMove = function (e) {
|
||||
if (!storm.followMouse) {
|
||||
return true;
|
||||
|
@ -583,7 +583,7 @@ function snow(flakesMax) {
|
|||
windOffset = (x / screenX2) * windMultiplier;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
this.createSnow = function (limit, allowInactive) {
|
||||
var i;
|
||||
for (i = 0; i < limit; i++) {
|
||||
|
@ -596,12 +596,12 @@ function snow(flakesMax) {
|
|||
}
|
||||
storm.targetElement.appendChild(docFrag);
|
||||
};
|
||||
|
||||
|
||||
this.timerInit = function () {
|
||||
storm.timer = true;
|
||||
storm.snow();
|
||||
};
|
||||
|
||||
|
||||
this.init = function () {
|
||||
var i;
|
||||
for (i = 0; i < storm.meltFrameCount; i++) {
|
||||
|
@ -628,7 +628,7 @@ function snow(flakesMax) {
|
|||
storm.animationInterval = Math.max(20, storm.animationInterval);
|
||||
storm.timerInit();
|
||||
};
|
||||
|
||||
|
||||
this.start = function (bFromOnLoad) {
|
||||
if (!didInit) {
|
||||
didInit = true;
|
||||
|
@ -678,7 +678,7 @@ function snow(flakesMax) {
|
|||
storm.active = true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
function doDelayedStart() {
|
||||
window.setTimeout(function () {
|
||||
storm.start(true);
|
||||
|
@ -686,7 +686,7 @@ function snow(flakesMax) {
|
|||
// event cleanup
|
||||
storm.events.remove(isIE ? document : window, "mousemove", doDelayedStart);
|
||||
}
|
||||
|
||||
|
||||
function doStart() {
|
||||
if (!storm.excludeMobile || !isMobile) {
|
||||
doDelayedStart();
|
||||
|
@ -694,12 +694,12 @@ function snow(flakesMax) {
|
|||
// event cleanup
|
||||
storm.events.remove(window, "load", doStart);
|
||||
}
|
||||
|
||||
|
||||
// hooks for starting the snow
|
||||
if (storm.autoStart) {
|
||||
storm.events.add(window, "load", doStart, false);
|
||||
}
|
||||
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ function vote(type, id, dir) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const xhr = createXhrWithFormKey("/vote/" + type.replace('-mobile','') + "/" + id + "/" + votedirection);
|
||||
xhr[0].send(xhr[1]);
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ function buy(mb) {
|
|||
document.getElementById('giveaward').disabled=false;
|
||||
let owned = document.getElementById(`${kind}-owned`)
|
||||
let ownednum = Number(owned.textContent) + 1;
|
||||
owned.textContent = ownednum
|
||||
owned.textContent = ownednum
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -166,7 +166,7 @@ function giveaward(t) {
|
|||
owned.textContent = ownednum
|
||||
if (ownednum == 0)
|
||||
document.getElementById('giveaward').disabled=true;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -108,7 +108,7 @@ function buildRouletteTable() {
|
|||
for (let i = 25; i < 37; i++) {
|
||||
const correctNumber = CELL_TO_NUMBER_LOOKUP[i];
|
||||
const isRed = reds.includes(correctNumber);
|
||||
|
||||
|
||||
html += `<div
|
||||
id="STRAIGHT_UP_BET#${correctNumber}"
|
||||
data-nonce="${nonce}"
|
||||
|
@ -238,7 +238,7 @@ function buildRouletteBets(bets) {
|
|||
data-bs-placement="bottom"
|
||||
title=""
|
||||
aria-label="Marseybux"
|
||||
width="32" class="mr-1 ml-1"
|
||||
width="32" class="mr-1 ml-1"
|
||||
data-bs-original-title="Marseybux">
|
||||
`;
|
||||
const { participants, coin, marseybux } = flatBets.reduce((prev, next) => {
|
||||
|
|
|
@ -98,7 +98,7 @@ function delete_commentModal(t, id) {
|
|||
document.getElementById("comment-"+id).remove()
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
document.getElementsByClassName(`comment-${id}-only`)[0].classList.add('deleted');
|
||||
document.getElementById(`delete-${id}`).classList.add('d-none');
|
||||
document.getElementById(`undelete-${id}`).classList.remove('d-none');
|
||||
|
@ -123,7 +123,7 @@ function post_reply(id){
|
|||
form.append('file', e);
|
||||
}
|
||||
catch(e) {}
|
||||
|
||||
|
||||
const xhr = createXhrWithFormKey("/reply", "POST", form);
|
||||
xhr[0].onload=function(){
|
||||
let data
|
||||
|
|
|
@ -63,7 +63,7 @@ function postToast(t, url, data, extraActionsOnSuccess, method="POST") {
|
|||
showToast(success, message);
|
||||
if (!isShopConfirm) {
|
||||
t.disabled = false;
|
||||
t.classList.remove("disabled");
|
||||
t.classList.remove("disabled");
|
||||
}
|
||||
return success;
|
||||
};
|
||||
|
|
|
@ -4,6 +4,6 @@ let audio = new Audio(`/assets/images/${fart}.webp`);
|
|||
audio.play();
|
||||
if (audio.paused) {
|
||||
document.addEventListener('click', () => {
|
||||
if (audio.paused) audio.play();
|
||||
if (audio.paused) audio.play();
|
||||
}, {once : true})
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ async function getGifs(form) {
|
|||
noGIFs.innerHTML = null;
|
||||
loadGIFs.innerHTML = null;
|
||||
|
||||
container.innerHTML = `
|
||||
container.innerHTML = `
|
||||
<div class="card">
|
||||
<div class="gif-cat-overlay"><div>Agree</div></div>
|
||||
<img loading="lazy" src="https://media.giphy.com/media/wGhYz3FHaRJgk/200w.webp">
|
||||
|
|
|
@ -65,7 +65,7 @@ function registerServiceWorker(serviceWorkerUrl, applicationServerPublicKey, api
|
|||
.catch(function() {
|
||||
});
|
||||
} else {
|
||||
}
|
||||
}
|
||||
return swRegistration;
|
||||
}
|
||||
|
||||
|
|
|
@ -75,4 +75,4 @@ self.addEventListener('notificationclick', (e) => {
|
|||
const hadWindowToFocus = clientsArr.some((windowClient) => windowClient.url === e.notification.data.url ? (windowClient.focus(), true) : false);
|
||||
if (!hadWindowToFocus) clients.openWindow(e.notification.data.url).then((windowClient) => windowClient ? windowClient.focus() : null);
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -13,7 +13,7 @@ function updatebgselection(){
|
|||
const backgrounds = [
|
||||
{
|
||||
folder: "glitter",
|
||||
backgrounds:
|
||||
backgrounds:
|
||||
[
|
||||
"1.webp",
|
||||
"2.webp",
|
||||
|
@ -109,7 +109,7 @@ document.onpaste = function(event) {
|
|||
alert("You can't upload more than 4 files at one time!")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
if (files.length)
|
||||
{
|
||||
f=document.getElementById('file-upload');
|
||||
|
|
|
@ -38,7 +38,7 @@ function unblock_user(t, url) {
|
|||
},
|
||||
() => {
|
||||
t.parentElement.parentElement.remove();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,12 +12,12 @@ function highlight_unread(localstoragevar) {
|
|||
catch(e) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
highlight_unread("comment-counts")
|
||||
|
||||
if (!location.href.includes("?context")) {
|
||||
if (!location.href.includes("?context")) {
|
||||
localStorage.setItem("old-comment-counts", localStorage.getItem("comment-counts"))
|
||||
|
||||
const comments = JSON.parse(localStorage.getItem("comment-counts")) || {}
|
||||
|
|
|
@ -82,7 +82,7 @@ class Badge(Base):
|
|||
text = self.badge.description
|
||||
else:
|
||||
return self.name
|
||||
|
||||
|
||||
return f'{self.name} - {text}'
|
||||
|
||||
@property
|
||||
|
|
|
@ -285,7 +285,7 @@ class Comment(Base):
|
|||
body += f''' data-nonce="{{g.nonce}}" data-onclick="poll_vote_no_v()"'''
|
||||
|
||||
body += f'''><label class="custom-control-label" for="comment-{o.id}">{o.body_html}<span class="presult-{self.id}'''
|
||||
if not self.total_poll_voted(v): body += ' d-none'
|
||||
if not self.total_poll_voted(v): body += ' d-none'
|
||||
body += f'"> - <a href="/votes/comment/option/{o.id}"><span id="score-comment-{o.id}">{o.upvotes}</span> votes</a></label></div>'''
|
||||
|
||||
if not self.ghost and self.author.show_sig(v):
|
||||
|
@ -322,15 +322,15 @@ class Comment(Base):
|
|||
if self.author.shadowbanned and not (v and v.shadowbanned): return True
|
||||
|
||||
if (self.wordle_result) and (not self.body or len(self.body_html) <= 100) and 9 > self.level > 1: return True
|
||||
|
||||
|
||||
if v and v.filter_words and self.body and any(x in self.body for x in v.filter_words): return True
|
||||
|
||||
|
||||
return False
|
||||
|
||||
@property
|
||||
@lazy
|
||||
def is_op(self): return self.author_id==self.post.author_id
|
||||
|
||||
|
||||
@lazy
|
||||
def filtered_flags(self, v):
|
||||
return [f for f in self.flags if (v and v.shadowbanned) or not f.user.shadowbanned]
|
||||
|
@ -356,7 +356,7 @@ class Comment(Base):
|
|||
body += "<strong class='ml-2'>Correct!</strong>"
|
||||
elif wordle_status == 'lost':
|
||||
body += f"<strong class='ml-2'>Lost. The answer was: {wordle_answer}</strong>"
|
||||
|
||||
|
||||
body += '</span>'
|
||||
return body
|
||||
|
||||
|
|
|
@ -22,8 +22,8 @@ class Leaderboard:
|
|||
user_func = None
|
||||
value_func = None
|
||||
|
||||
def __init__(self, header_name:str, table_header_name:str, html_id:str, table_column_name:str,
|
||||
user_relative_url:Optional[str], query_function:Callable[..., Tuple[Any, Any, Any]],
|
||||
def __init__(self, header_name:str, table_header_name:str, html_id:str, table_column_name:str,
|
||||
user_relative_url:Optional[str], query_function:Callable[..., Tuple[Any, Any, Any]],
|
||||
criteria, v:User, value_func:Optional[Callable[[User], Union[int, Column]]], db:scoped_session, users, limit=LEADERBOARD_LIMIT):
|
||||
self.header_name = header_name
|
||||
self.table_header_name = table_header_name
|
||||
|
@ -52,11 +52,11 @@ class Leaderboard:
|
|||
sq = db.query(User.id, func.rank().over(order_by=order_by.desc()).label("rank")).subquery()
|
||||
position = db.query(sq.c.id, sq.c.rank).filter(sq.c.id == v.id).limit(1).one()[1]
|
||||
return (leaderboard, position, None)
|
||||
|
||||
|
||||
@classmethod
|
||||
def count_and_label(cls, criteria):
|
||||
return func.count(criteria).label("count")
|
||||
|
||||
|
||||
@classmethod
|
||||
def rank_filtered_rank_label_by_desc(cls, criteria):
|
||||
return func.rank().over(order_by=func.count(criteria).desc()).label("rank")
|
||||
|
@ -71,27 +71,27 @@ class Leaderboard:
|
|||
sq_criteria = User.id == sq.c.author_id
|
||||
else:
|
||||
raise ValueError("This leaderboard function only supports Badge.user_id and Marsey.author_id")
|
||||
|
||||
|
||||
leaderboard = db.query(User, sq.c.count).join(sq, sq_criteria).order_by(sq.c.count.desc())
|
||||
position = db.query(User.id, sq.c.rank, sq.c.count).join(sq, sq_criteria).filter(User.id == v.id).one_or_none()
|
||||
if position: position = (position[1], position[2])
|
||||
else: position = (leaderboard.count() + 1, 0)
|
||||
leaderboard = leaderboard.limit(limit).all()
|
||||
return (leaderboard, position[0], position[1])
|
||||
|
||||
|
||||
@classmethod
|
||||
def get_blockers_lb(cls, lb_criteria, v:User, db:scoped_session, users:Any, limit):
|
||||
if lb_criteria != UserBlock.target_id:
|
||||
raise ValueError("This leaderboard function only supports UserBlock.target_id")
|
||||
sq = db.query(lb_criteria, cls.count_and_label(lb_criteria)).group_by(lb_criteria).subquery()
|
||||
leaderboard = db.query(User, sq.c.count).join(User, User.id == sq.c.target_id).order_by(sq.c.count.desc())
|
||||
|
||||
|
||||
sq = db.query(lb_criteria, cls.count_and_label(lb_criteria), cls.rank_filtered_rank_label_by_desc(lb_criteria)).group_by(lb_criteria).subquery()
|
||||
position = db.query(sq.c.rank, sq.c.count).join(User, User.id == sq.c.target_id).filter(sq.c.target_id == v.id).limit(1).one_or_none()
|
||||
if not position: position = (leaderboard.count() + 1, 0)
|
||||
leaderboard = leaderboard.limit(limit).all()
|
||||
return (leaderboard, position[0], position[1])
|
||||
|
||||
|
||||
@classmethod
|
||||
def get_hat_lb(cls, lb_criteria, v:User, db:scoped_session, users:Any, limit):
|
||||
leaderboard = db.query(User, func.count(lb_criteria)).join(lb_criteria).group_by(User).order_by(func.count(lb_criteria).desc())
|
||||
|
|
|
@ -13,7 +13,7 @@ class SubRelationship(Base):
|
|||
@declared_attr
|
||||
def user_id(self):
|
||||
return Column(Integer, ForeignKey("users.id"), primary_key=True)
|
||||
|
||||
|
||||
@declared_attr
|
||||
def sub(self):
|
||||
return Column(String(20), ForeignKey("subs.name"), primary_key=True)
|
||||
|
@ -28,7 +28,7 @@ class SubRelationship(Base):
|
|||
|
||||
def __repr__(self):
|
||||
return f"<{self.__class__.__name__}(user_id={self.user_id}, sub={self.sub})>"
|
||||
|
||||
|
||||
class SubJoin(SubRelationship):
|
||||
__tablename__ = "sub_joins"
|
||||
|
||||
|
|
|
@ -145,14 +145,14 @@ class Submission(Base):
|
|||
@property
|
||||
@lazy
|
||||
def is_youtube(self):
|
||||
return self.domain == "youtube.com" and self.embed_url and self.embed_url.startswith('<lite-youtube')
|
||||
return self.domain == "youtube.com" and self.embed_url and self.embed_url.startswith('<lite-youtube')
|
||||
|
||||
@property
|
||||
@lazy
|
||||
def thumb_url(self):
|
||||
if self.over_18: return f"{SITE_FULL}/i/nsfw.webp?v=1"
|
||||
elif not self.url: return f"{SITE_FULL}/i/{SITE_NAME}/default_text.webp?v=2"
|
||||
elif self.thumburl:
|
||||
elif self.thumburl:
|
||||
if self.thumburl.startswith('/'): return SITE_FULL + self.thumburl
|
||||
return self.thumburl
|
||||
elif self.is_youtube or self.is_video: return f"{SITE_FULL}/i/default_thumb_video.webp?v=2"
|
||||
|
@ -171,7 +171,7 @@ class Submission(Base):
|
|||
'title': self.title,
|
||||
'permalink': self.permalink,
|
||||
}
|
||||
|
||||
|
||||
if self.deleted_utc:
|
||||
return {'is_banned': bool(self.is_banned),
|
||||
'deleted_utc': True,
|
||||
|
@ -240,7 +240,7 @@ class Submission(Base):
|
|||
url = normalize_urls_runtime(url, v)
|
||||
|
||||
if url.startswith("https://old.reddit.com/r/") and '/comments/' in url and "sort=" not in url:
|
||||
if "?" in url: url += "&context=9"
|
||||
if "?" in url: url += "&context=9"
|
||||
else: url += "?context=8"
|
||||
if not v or v.controversial: url += "&sort=controversial"
|
||||
elif url.startswith("https://watchpeopledie.tv/videos/"):
|
||||
|
@ -249,7 +249,7 @@ class Submission(Base):
|
|||
"https://videos.watchpeopledie.tv/", 1)
|
||||
|
||||
return url
|
||||
|
||||
|
||||
@lazy
|
||||
def total_bet_voted(self, v):
|
||||
if "closed" in self.body.lower(): return True
|
||||
|
@ -297,7 +297,7 @@ class Submission(Base):
|
|||
|
||||
if o.exclusive == 3:
|
||||
body += " - <b>WINNER!</b>"
|
||||
|
||||
|
||||
if not winner and v and v.admin_level >= PERMS['POST_BETS_DISTRIBUTE']:
|
||||
body += f'''<button class="btn btn-primary distribute" data-areyousure="postToastReload(this,'/distribute/{o.id}')" data-nonce="{{g.nonce}}" data-onclick="areyousure(this)">Declare winner</button>'''
|
||||
body += "</div>"
|
||||
|
@ -314,7 +314,7 @@ class Submission(Base):
|
|||
body += f''' data-nonce="{{g.nonce}}" data-onclick="poll_vote_no_v()"'''
|
||||
|
||||
body += f'''><label class="custom-control-label" for="post-{o.id}">{o.body_html}<span class="presult-{self.id}'''
|
||||
if not self.total_poll_voted(v): body += ' d-none'
|
||||
if not self.total_poll_voted(v): body += ' d-none'
|
||||
body += f'"> - <a href="/votes/post/option/{o.id}"><span id="score-post-{o.id}">{o.upvotes}</span> votes</a></label></div>'''
|
||||
|
||||
|
||||
|
|
|
@ -204,7 +204,7 @@ class User(Base):
|
|||
g.db.query(User).filter(User.id == self.id).update({ User.marseybux: User.marseybux + amount })
|
||||
|
||||
g.db.flush()
|
||||
|
||||
|
||||
|
||||
def charge_account(self, currency, amount, **kwargs):
|
||||
in_db = g.db.query(User).filter(User.id == self.id).with_for_update().one()
|
||||
|
@ -214,19 +214,19 @@ class User(Base):
|
|||
|
||||
if currency == 'coins':
|
||||
account_balance = in_db.coins
|
||||
|
||||
|
||||
if not should_check_balance or account_balance >= amount:
|
||||
g.db.query(User).filter(User.id == self.id).update({ User.coins: User.coins - amount })
|
||||
succeeded = True
|
||||
elif currency == 'marseybux':
|
||||
account_balance = in_db.marseybux
|
||||
|
||||
|
||||
if not should_check_balance or account_balance >= amount:
|
||||
g.db.query(User).filter(User.id == self.id).update({ User.marseybux: User.marseybux - amount })
|
||||
succeeded = True
|
||||
|
||||
if succeeded: g.db.flush()
|
||||
|
||||
|
||||
return succeeded
|
||||
|
||||
@property
|
||||
|
@ -417,7 +417,7 @@ class User(Base):
|
|||
if badge in owned_badges: discount -= discounts[badge]
|
||||
|
||||
return discount
|
||||
|
||||
|
||||
@property
|
||||
@lazy
|
||||
def can_view_offsitementions(self):
|
||||
|
@ -586,14 +586,14 @@ class User(Base):
|
|||
Notification.user_id == self.id,
|
||||
not_(and_(Comment.sentto != None, Comment.sentto == MODMAIL_ID, User.is_muted)),
|
||||
))
|
||||
|
||||
|
||||
if not self.can_see_shadowbanned:
|
||||
notifs = notifs.filter(
|
||||
User.shadowbanned == None,
|
||||
Comment.is_banned == False,
|
||||
Comment.deleted_utc == 0,
|
||||
)
|
||||
|
||||
|
||||
return notifs.count() + self.post_notifications_count + self.modaction_notifications_count + self.reddit_notifications_count
|
||||
|
||||
@property
|
||||
|
@ -603,7 +603,7 @@ class User(Base):
|
|||
- self.message_notifications_count \
|
||||
- self.post_notifications_count \
|
||||
- self.modaction_notifications_count \
|
||||
- self.reddit_notifications_count
|
||||
- self.reddit_notifications_count
|
||||
|
||||
@property
|
||||
@lazy
|
||||
|
@ -659,7 +659,7 @@ class User(Base):
|
|||
SubAction.user_id != self.id,
|
||||
SubAction.sub.in_(self.moderated_subs),
|
||||
).count()
|
||||
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
|
@ -669,8 +669,8 @@ class User(Base):
|
|||
if not self.can_view_offsitementions or self.id == AEVANN_ID: return 0
|
||||
return g.db.query(Comment).filter(
|
||||
Comment.created_utc > self.last_viewed_reddit_notifs,
|
||||
Comment.is_banned == False, Comment.deleted_utc == 0,
|
||||
Comment.body_html.like('%<p>New site mention%<a href="https://old.reddit.com/r/%'),
|
||||
Comment.is_banned == False, Comment.deleted_utc == 0,
|
||||
Comment.body_html.like('%<p>New site mention%<a href="https://old.reddit.com/r/%'),
|
||||
Comment.parent_submission == None, Comment.author_id == AUTOJANNY_ID).count()
|
||||
|
||||
@property
|
||||
|
@ -730,7 +730,7 @@ class User(Base):
|
|||
def has_follower(self, user):
|
||||
if not user or self.id == user.id: return False # users can't follow themselves
|
||||
return g.db.query(Follow).filter_by(target_id=self.id, user_id=user.id).one_or_none()
|
||||
|
||||
|
||||
@lazy
|
||||
def is_visible_to(self, user) -> bool:
|
||||
if not self.is_private: return True
|
||||
|
@ -752,7 +752,7 @@ class User(Base):
|
|||
return f"{SITE_FULL}/e/chudsey.webp"
|
||||
if self.rainbow:
|
||||
return f"{SITE_FULL}/e/marseysalutepride.webp"
|
||||
if self.profileurl:
|
||||
if self.profileurl:
|
||||
if self.profileurl.startswith('/'): return SITE_FULL + self.profileurl
|
||||
return self.profileurl
|
||||
return f"{SITE_FULL}/i/default-profile-pic.webp?v=1008"
|
||||
|
@ -927,7 +927,7 @@ class User(Base):
|
|||
if self.patron == 6:
|
||||
return 'Contributed at least $200'
|
||||
return ''
|
||||
|
||||
|
||||
@classmethod
|
||||
def can_see_content(cls, user:Optional["User"], other:Union[Submission, Comment, Sub]) -> bool:
|
||||
'''
|
||||
|
|
|
@ -35,7 +35,7 @@ def _archiveorg(url):
|
|||
except: pass
|
||||
|
||||
|
||||
def archive_url(url):
|
||||
def archive_url(url):
|
||||
gevent.spawn(_archiveorg, url)
|
||||
if url.startswith('https://twitter.com/'):
|
||||
url = url.replace('https://twitter.com/', 'https://nitter.lacontrevoie.fr/')
|
||||
|
@ -64,7 +64,7 @@ def execute_snappy(post:Submission, v:User):
|
|||
if SNAPPY_MARSEYS and SNAPPY_QUOTES:
|
||||
if IS_FISTMAS() or random.random() > 0.5:
|
||||
SNAPPY_CHOICES = SNAPPY_QUOTES
|
||||
else:
|
||||
else:
|
||||
SNAPPY_CHOICES = SNAPPY_MARSEYS
|
||||
elif SNAPPY_MARSEYS: SNAPPY_CHOICES = SNAPPY_MARSEYS
|
||||
elif SNAPPY_QUOTES: SNAPPY_CHOICES = SNAPPY_QUOTES
|
||||
|
@ -350,7 +350,7 @@ def execute_blackjack_custom(v, target, body, type):
|
|||
def execute_blackjack(v, target, body, type):
|
||||
if not execute_blackjack_custom(v, target, body, type):
|
||||
return False
|
||||
|
||||
|
||||
if not body: return True
|
||||
|
||||
execute = False
|
||||
|
@ -510,8 +510,8 @@ def execute_lawlz_actions(v:User, p:Submission):
|
|||
g.db.add(ma_2)
|
||||
g.db.add(ma_3)
|
||||
|
||||
def process_poll_options(target:Union[Submission, Comment],
|
||||
cls:Union[Type[SubmissionOption], Type[CommentOption]],
|
||||
def process_poll_options(target:Union[Submission, Comment],
|
||||
cls:Union[Type[SubmissionOption], Type[CommentOption]],
|
||||
options:Iterable[str], exclusive:int, friendly_name:str,
|
||||
db:scoped_session) -> None:
|
||||
for option in options:
|
||||
|
|
|
@ -66,7 +66,7 @@ def notif_comment2(p):
|
|||
search_html = f'%</a> has mentioned you: <a href="/post/{p.id}">%'
|
||||
|
||||
existing = g.db.query(Comment.id).filter(Comment.author_id == AUTOJANNY_ID, Comment.parent_submission == None, Comment.body_html.like(search_html)).first()
|
||||
|
||||
|
||||
if existing: return existing[0]
|
||||
else:
|
||||
text = f"@{p.author.username} has mentioned you: [{p.title}](/post/{p.id})"
|
||||
|
|
|
@ -85,7 +85,7 @@ CASINO_RELEASE_DAY = 1662825600
|
|||
|
||||
AJ_REPLACEMENTS = {
|
||||
' your ': " you're ",
|
||||
' to ': " too ",
|
||||
' to ': " too ",
|
||||
|
||||
' Your ': " You're ",
|
||||
' To ': " Too ",
|
||||
|
@ -986,7 +986,7 @@ forced_hats = {
|
|||
"earlylife": ("The Merchant", "SHUT IT DOWN, the goys know!"),
|
||||
"marsify": ("Marsified", "I can't pick my own Marseys, help!"),
|
||||
"is_suspended": ("Behind Bars", "This user is banned and needs to do better!"),
|
||||
"agendaposter": (("Egg_irl", "This user is getting in touch with xir identity!"),
|
||||
"agendaposter": (("Egg_irl", "This user is getting in touch with xir identity!"),
|
||||
("Trans Flag", "Just in case you forgot, trans lives matter."),
|
||||
("Trans Flag II", "Your egg is cracked; wear it with pride!"),
|
||||
("Pride Flag", "Never forget that this is a primarily gay community. Dude bussy lmao."),
|
||||
|
|
|
@ -2,78 +2,78 @@ from copy import deepcopy
|
|||
|
||||
MODACTION_TYPES = {
|
||||
'chud': {
|
||||
"str": 'chudded {self.target_link}',
|
||||
"icon": 'fa-snooze',
|
||||
"str": 'chudded {self.target_link}',
|
||||
"icon": 'fa-snooze',
|
||||
"color": 'bg-danger'
|
||||
},
|
||||
'approve_app': {
|
||||
"str": 'approved an application by {self.target_link}',
|
||||
"icon": 'fa-robot',
|
||||
"str": 'approved an application by {self.target_link}',
|
||||
"icon": 'fa-robot',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'badge_grant': {
|
||||
"str": 'granted badge to {self.target_link}',
|
||||
"icon": 'fa-badge',
|
||||
"str": 'granted badge to {self.target_link}',
|
||||
"icon": 'fa-badge',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'badge_remove': {
|
||||
"str": 'removed badge from {self.target_link}',
|
||||
"icon": 'fa-badge',
|
||||
"str": 'removed badge from {self.target_link}',
|
||||
"icon": 'fa-badge',
|
||||
"color": 'bg-danger'
|
||||
},
|
||||
'ban_comment': {
|
||||
"str": 'removed {self.target_link}',
|
||||
"icon": 'fa-comment',
|
||||
"str": 'removed {self.target_link}',
|
||||
"icon": 'fa-comment',
|
||||
"color": 'bg-danger'
|
||||
},
|
||||
'ban_domain': {
|
||||
"str": 'banned a domain',
|
||||
"icon": 'fa-globe',
|
||||
"str": 'banned a domain',
|
||||
"icon": 'fa-globe',
|
||||
"color": 'bg-danger'
|
||||
},
|
||||
'ban_post': {
|
||||
"str": 'removed post {self.target_link}',
|
||||
"icon": 'fa-feather-alt',
|
||||
"str": 'removed post {self.target_link}',
|
||||
"icon": 'fa-feather-alt',
|
||||
"color": 'bg-danger'
|
||||
},
|
||||
'ban_user': {
|
||||
"str": 'banned user {self.target_link}',
|
||||
"icon": 'fa-user-slash',
|
||||
"str": 'banned user {self.target_link}',
|
||||
"icon": 'fa-user-slash',
|
||||
"color": 'bg-danger'
|
||||
},
|
||||
'delete_report': {
|
||||
"str": 'deleted report on {self.target_link}',
|
||||
"icon": 'fa-flag',
|
||||
"str": 'deleted report on {self.target_link}',
|
||||
"icon": 'fa-flag',
|
||||
"color": 'bg-danger'
|
||||
},
|
||||
'disable_bots': {
|
||||
"str": 'disabled bots',
|
||||
"icon": 'fa-robot',
|
||||
"str": 'disabled bots',
|
||||
"icon": 'fa-robot',
|
||||
"color": 'bg-danger'
|
||||
},
|
||||
'disable_fart_mode': {
|
||||
"str": 'disabled fart mode',
|
||||
"icon": 'fa-gas-pump-slash',
|
||||
"str": 'disabled fart mode',
|
||||
"icon": 'fa-gas-pump-slash',
|
||||
"color": 'bg-danger'
|
||||
},
|
||||
'disable_read_only_mode': {
|
||||
"str": 'disabled read only mode',
|
||||
"icon": 'fa-book',
|
||||
"str": 'disabled read only mode',
|
||||
"icon": 'fa-book',
|
||||
"color": 'bg-danger'
|
||||
},
|
||||
'disable_signups': {
|
||||
"str": 'disabled signups',
|
||||
"icon": 'fa-users',
|
||||
"str": 'disabled signups',
|
||||
"icon": 'fa-users',
|
||||
"color": 'bg-danger'
|
||||
},
|
||||
'disable_login_required': {
|
||||
"str": 'disabled login required',
|
||||
"icon": 'fa-users',
|
||||
"str": 'disabled login required',
|
||||
"icon": 'fa-users',
|
||||
"color": 'bg-danger'
|
||||
},
|
||||
'disable_under_attack': {
|
||||
"str": 'disabled under attack mode',
|
||||
"icon": 'fa-shield',
|
||||
"str": 'disabled under attack mode',
|
||||
"icon": 'fa-shield',
|
||||
"color": 'bg-muted'
|
||||
},
|
||||
'disable_under_siege': {
|
||||
|
@ -82,58 +82,58 @@ MODACTION_TYPES = {
|
|||
"color": 'bg-muted'
|
||||
},
|
||||
'distinguish_comment': {
|
||||
"str": 'distinguished {self.target_link}',
|
||||
"icon": 'fa-crown',
|
||||
"str": 'distinguished {self.target_link}',
|
||||
"icon": 'fa-crown',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'distinguish_post': {
|
||||
"str": 'distinguished {self.target_link}',
|
||||
"icon": 'fa-crown',
|
||||
"str": 'distinguished {self.target_link}',
|
||||
"icon": 'fa-crown',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'distribute': {
|
||||
"str": 'distributed bet winnings to voters on {self.target_link}',
|
||||
"icon": 'fa-dollar-sign',
|
||||
"str": 'distributed bet winnings to voters on {self.target_link}',
|
||||
"icon": 'fa-dollar-sign',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'edit_post': {
|
||||
"str": 'edited {self.target_link}',
|
||||
"icon": 'fa-edit',
|
||||
"str": 'edited {self.target_link}',
|
||||
"icon": 'fa-edit',
|
||||
"color": 'bg-primary'
|
||||
},
|
||||
'edit_rules': {
|
||||
"str": 'edited the rules',
|
||||
"icon": 'fa-columns',
|
||||
"str": 'edited the rules',
|
||||
"icon": 'fa-columns',
|
||||
"color": 'bg-primary'
|
||||
},
|
||||
'enable_bots': {
|
||||
"str": 'enabled bots',
|
||||
"icon": 'fa-robot',
|
||||
"str": 'enabled bots',
|
||||
"icon": 'fa-robot',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'enable_fart_mode': {
|
||||
"str": 'enabled fart mode',
|
||||
"icon": 'fa-gas-pump',
|
||||
"str": 'enabled fart mode',
|
||||
"icon": 'fa-gas-pump',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'enable_read_only_mode': {
|
||||
"str": 'enabled read only mode',
|
||||
"icon": 'fa-book',
|
||||
"str": 'enabled read only mode',
|
||||
"icon": 'fa-book',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'enable_signups': {
|
||||
"str": 'enabled signups',
|
||||
"icon": 'fa-users',
|
||||
"str": 'enabled signups',
|
||||
"icon": 'fa-users',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'enable_login_required': {
|
||||
"str": 'enabled login required',
|
||||
"icon": 'fa-users',
|
||||
"str": 'enabled login required',
|
||||
"icon": 'fa-users',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'enable_under_attack': {
|
||||
"str": 'enabled under attack mode',
|
||||
"icon": 'fa-shield',
|
||||
"str": 'enabled under attack mode',
|
||||
"icon": 'fa-shield',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'enable_under_siege': {
|
||||
|
@ -142,13 +142,13 @@ MODACTION_TYPES = {
|
|||
"color": 'bg-success',
|
||||
},
|
||||
'flair_post': {
|
||||
"str": 'set a flair on {self.target_link}',
|
||||
"icon": 'fa-tag',
|
||||
"str": 'set a flair on {self.target_link}',
|
||||
"icon": 'fa-tag',
|
||||
"color": 'bg-primary'
|
||||
},
|
||||
'link_accounts': {
|
||||
"str": 'linked {self.target_link}',
|
||||
"icon": 'fa-link',
|
||||
"str": 'linked {self.target_link}',
|
||||
"icon": 'fa-link',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'delink_accounts': {
|
||||
|
@ -157,8 +157,8 @@ MODACTION_TYPES = {
|
|||
"color": 'bg-danger'
|
||||
},
|
||||
'make_admin': {
|
||||
"str": 'made {self.target_link} an admin',
|
||||
"icon": 'fa-user-crown',
|
||||
"str": 'made {self.target_link} an admin',
|
||||
"icon": 'fa-user-crown',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'mod_mute_user': {
|
||||
|
@ -172,169 +172,169 @@ MODACTION_TYPES = {
|
|||
"color": 'bg-success'
|
||||
},
|
||||
'monthly': {
|
||||
"str": 'distributed monthly marseybux',
|
||||
"icon": 'fa-sack-dollar',
|
||||
"str": 'distributed monthly marseybux',
|
||||
"icon": 'fa-sack-dollar',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'move_hole': {
|
||||
"str": 'changed hole of {self.target_link}',
|
||||
"icon": 'fa-manhole',
|
||||
"str": 'changed hole of {self.target_link}',
|
||||
"icon": 'fa-manhole',
|
||||
"color": 'bg-primary'
|
||||
},
|
||||
'nuke_user': {
|
||||
"str": 'removed all content of {self.target_link}',
|
||||
"icon": 'fa-radiation-alt',
|
||||
"str": 'removed all content of {self.target_link}',
|
||||
"icon": 'fa-radiation-alt',
|
||||
"color": 'bg-danger'
|
||||
},
|
||||
'pin_comment': {
|
||||
"str": 'pinned {self.target_link}',
|
||||
"icon": 'fa-thumbtack fa-rotate--45',
|
||||
"str": 'pinned {self.target_link}',
|
||||
"icon": 'fa-thumbtack fa-rotate--45',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'pin_post': {
|
||||
"str": 'pinned post {self.target_link}',
|
||||
"icon": 'fa-thumbtack fa-rotate--45',
|
||||
"str": 'pinned post {self.target_link}',
|
||||
"icon": 'fa-thumbtack fa-rotate--45',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'clear_cloudflare_cache': {
|
||||
"str": 'cleared cloudflare cache',
|
||||
"str": 'cleared cloudflare cache',
|
||||
"icon": 'fab fa-cloudflare',
|
||||
"color": 'bg-muted'
|
||||
},
|
||||
'reject_app': {
|
||||
"str": 'rejected an application request by {self.target_link}',
|
||||
"icon": 'fa-robot',
|
||||
"str": 'rejected an application request by {self.target_link}',
|
||||
"icon": 'fa-robot',
|
||||
"color": 'bg-muted'
|
||||
},
|
||||
'remove_admin': {
|
||||
"str": 'removed {self.target_link} as admin',
|
||||
"icon": 'fa-user-crown',
|
||||
"str": 'removed {self.target_link} as admin',
|
||||
"icon": 'fa-user-crown',
|
||||
"color": 'bg-danger'
|
||||
},
|
||||
'revert': {
|
||||
"str": 'reverted {self.target_link} mod actions',
|
||||
"icon": 'fa-history',
|
||||
"str": 'reverted {self.target_link} mod actions',
|
||||
"icon": 'fa-history',
|
||||
"color": 'bg-danger'
|
||||
},
|
||||
'revoke_app': {
|
||||
"str": 'revoked an application by {self.target_link}',
|
||||
"icon": 'fa-robot',
|
||||
"str": 'revoked an application by {self.target_link}',
|
||||
"icon": 'fa-robot',
|
||||
"color": 'bg-muted'
|
||||
},
|
||||
'set_flair_locked': {
|
||||
"str": "set {self.target_link}'s flair (locked)",
|
||||
"icon": 'fa-award',
|
||||
"str": "set {self.target_link}'s flair (locked)",
|
||||
"icon": 'fa-award',
|
||||
"color": 'bg-primary'
|
||||
},
|
||||
'set_flair_notlocked': {
|
||||
"str": "set {self.target_link}'s flair (not locked)",
|
||||
"icon": 'fa-award',
|
||||
"str": "set {self.target_link}'s flair (not locked)",
|
||||
"icon": 'fa-award',
|
||||
"color": 'bg-primary'
|
||||
},
|
||||
'set_new': {
|
||||
"str": 'changed the default sorting of comments on {self.target_link} to `new`',
|
||||
"icon": 'fa-sparkles',
|
||||
"str": 'changed the default sorting of comments on {self.target_link} to `new`',
|
||||
"icon": 'fa-sparkles',
|
||||
"color": 'bg-primary'
|
||||
},
|
||||
'set_hot': {
|
||||
"str": 'changed the default sorting of comments on {self.target_link} to `hot`',
|
||||
"icon": 'fa-fire',
|
||||
"str": 'changed the default sorting of comments on {self.target_link} to `hot`',
|
||||
"icon": 'fa-fire',
|
||||
"color": 'bg-primary'
|
||||
},
|
||||
'set_nsfw': {
|
||||
"str": 'set {self.target_link} as +18',
|
||||
"icon": 'fa-eye-evil',
|
||||
"str": 'set {self.target_link} as +18',
|
||||
"icon": 'fa-eye-evil',
|
||||
"color": 'bg-danger'
|
||||
},
|
||||
'set_nsfw_comment': {
|
||||
"str": 'set {self.target_link} as +18',
|
||||
"icon": 'fa-eye-evil',
|
||||
"str": 'set {self.target_link} as +18',
|
||||
"icon": 'fa-eye-evil',
|
||||
"color": 'bg-danger'
|
||||
},
|
||||
'shadowban': {
|
||||
"str": 'shadowbanned {self.target_link}',
|
||||
"icon": 'fa-eye-slash',
|
||||
"str": 'shadowbanned {self.target_link}',
|
||||
"icon": 'fa-eye-slash',
|
||||
"color": 'bg-danger'
|
||||
},
|
||||
'unchud': {
|
||||
"str": 'unchudded {self.target_link}',
|
||||
"icon": 'fa-snooze',
|
||||
"str": 'unchudded {self.target_link}',
|
||||
"icon": 'fa-snooze',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'unban_comment': {
|
||||
"str": 'reinstated {self.target_link}',
|
||||
"icon": 'fa-comment',
|
||||
"str": 'reinstated {self.target_link}',
|
||||
"icon": 'fa-comment',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'unban_domain': {
|
||||
"str": 'unbanned a domain',
|
||||
"icon": 'fa-globe',
|
||||
"str": 'unbanned a domain',
|
||||
"icon": 'fa-globe',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'unban_post': {
|
||||
"str": 'reinstated post {self.target_link}',
|
||||
"icon": 'fa-feather-alt',
|
||||
"str": 'reinstated post {self.target_link}',
|
||||
"icon": 'fa-feather-alt',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'unban_user': {
|
||||
"str": 'unbanned user {self.target_link}',
|
||||
"icon": 'fa-user',
|
||||
"str": 'unbanned user {self.target_link}',
|
||||
"icon": 'fa-user',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'undistinguish_comment': {
|
||||
"str": 'un-distinguished {self.target_link}',
|
||||
"icon": 'fa-crown',
|
||||
"str": 'un-distinguished {self.target_link}',
|
||||
"icon": 'fa-crown',
|
||||
"color": 'bg-muted'
|
||||
},
|
||||
'undistinguish_post': {
|
||||
"str": 'un-distinguished {self.target_link}',
|
||||
"icon": 'fa-crown',
|
||||
"str": 'un-distinguished {self.target_link}',
|
||||
"icon": 'fa-crown',
|
||||
"color": 'bg-muted'
|
||||
},
|
||||
'unnuke_user': {
|
||||
"str": 'approved all content of {self.target_link}',
|
||||
"icon": 'fa-radiation-alt',
|
||||
"str": 'approved all content of {self.target_link}',
|
||||
"icon": 'fa-radiation-alt',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'unpin_comment': {
|
||||
"str": 'unpinned {self.target_link}',
|
||||
"icon": 'fa-thumbtack fa-rotate--45',
|
||||
"str": 'unpinned {self.target_link}',
|
||||
"icon": 'fa-thumbtack fa-rotate--45',
|
||||
"color": 'bg-muted'
|
||||
},
|
||||
'unpin_post': {
|
||||
"str": 'unpinned post {self.target_link}',
|
||||
"icon": 'fa-thumbtack fa-rotate--45',
|
||||
"str": 'unpinned post {self.target_link}',
|
||||
"icon": 'fa-thumbtack fa-rotate--45',
|
||||
"color": 'bg-muted'
|
||||
},
|
||||
'unset_nsfw': {
|
||||
"str": 'unset {self.target_link} as +18',
|
||||
"icon": 'fa-eye-evil',
|
||||
"str": 'unset {self.target_link} as +18',
|
||||
"icon": 'fa-eye-evil',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'unset_nsfw_comment': {
|
||||
"str": 'unset {self.target_link} as +18',
|
||||
"icon": 'fa-eye-evil',
|
||||
"str": 'unset {self.target_link} as +18',
|
||||
"icon": 'fa-eye-evil',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'unshadowban': {
|
||||
"str": 'unshadowbanned {self.target_link}',
|
||||
"icon": 'fa-eye',
|
||||
"str": 'unshadowbanned {self.target_link}',
|
||||
"icon": 'fa-eye',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'update_hat': {
|
||||
"str": 'updated hat image',
|
||||
"icon": 'fa-hat-cowboy',
|
||||
"str": 'updated hat image',
|
||||
"icon": 'fa-hat-cowboy',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'update_marsey': {
|
||||
"str": 'updated marsey',
|
||||
"icon": 'fa-cat',
|
||||
"str": 'updated marsey',
|
||||
"icon": 'fa-cat',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
}
|
||||
|
||||
MODACTION_PRIVILEGED_TYPES = {'shadowban', 'unshadowban',
|
||||
MODACTION_PRIVILEGED_TYPES = {'shadowban', 'unshadowban',
|
||||
'mod_mute_user', 'mod_unmute_user',
|
||||
'link_accounts', 'delink_accounts'}
|
||||
MODACTION_TYPES_FILTERED = deepcopy({t:v for t,v in MODACTION_TYPES.items()
|
||||
MODACTION_TYPES_FILTERED = deepcopy({t:v for t,v in MODACTION_TYPES.items()
|
||||
if not t in MODACTION_PRIVILEGED_TYPES})
|
||||
|
|
|
@ -1,52 +1,52 @@
|
|||
SUBACTION_TYPES = {
|
||||
'exile_user': {
|
||||
"str": 'exiled user {self.target_link}',
|
||||
"icon": 'fa-user-slash',
|
||||
"str": 'exiled user {self.target_link}',
|
||||
"icon": 'fa-user-slash',
|
||||
"color": 'bg-danger'
|
||||
},
|
||||
'unexile_user': {
|
||||
"str": 'unexiled user {self.target_link}',
|
||||
"icon": 'fa-user',
|
||||
"str": 'unexiled user {self.target_link}',
|
||||
"icon": 'fa-user',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'make_mod': {
|
||||
"str": 'made {self.target_link} a mod',
|
||||
"icon": 'fa-user-crown',
|
||||
"str": 'made {self.target_link} a mod',
|
||||
"icon": 'fa-user-crown',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'remove_mod': {
|
||||
"str": 'removed {self.target_link} as mod',
|
||||
"icon": 'fa-user-crown',
|
||||
"str": 'removed {self.target_link} as mod',
|
||||
"icon": 'fa-user-crown',
|
||||
"color": 'bg-danger'
|
||||
},
|
||||
'kick_post': {
|
||||
"str": 'kicked post {self.target_link}',
|
||||
"icon": 'fa-feather-alt',
|
||||
"str": 'kicked post {self.target_link}',
|
||||
"icon": 'fa-feather-alt',
|
||||
"color": 'bg-danger'
|
||||
},
|
||||
'move_chudrama': {
|
||||
"str": 'moved post {self.target_link} to <a href="/h/chudrama">/h/chudrama</a>',
|
||||
"icon": 'fa-feather-alt',
|
||||
"str": 'moved post {self.target_link} to <a href="/h/chudrama">/h/chudrama</a>',
|
||||
"icon": 'fa-feather-alt',
|
||||
"color": 'bg-danger'
|
||||
},
|
||||
'flair_post': {
|
||||
"str": 'set a flair on {self.target_link}',
|
||||
"icon": 'fa-tag',
|
||||
"str": 'set a flair on {self.target_link}',
|
||||
"icon": 'fa-tag',
|
||||
"color": 'bg-primary'
|
||||
},
|
||||
'edit_sidebar': {
|
||||
"str": 'edited the sidebar',
|
||||
"icon": 'fa-columns',
|
||||
"str": 'edited the sidebar',
|
||||
"icon": 'fa-columns',
|
||||
"color": 'bg-primary'
|
||||
},
|
||||
'edit_css': {
|
||||
"str": 'edited the css',
|
||||
"icon": 'fa-css3-alt',
|
||||
"str": 'edited the css',
|
||||
"icon": 'fa-css3-alt',
|
||||
"color": 'bg-primary'
|
||||
},
|
||||
'upload_banner': {
|
||||
"str": 'uploaded a banner',
|
||||
"icon": 'fa-landscape',
|
||||
"str": 'uploaded a banner',
|
||||
"icon": 'fa-landscape',
|
||||
"color": 'bg-primary'
|
||||
},
|
||||
'delete_banner': {
|
||||
|
@ -55,63 +55,63 @@ SUBACTION_TYPES = {
|
|||
"color": 'bg-danger',
|
||||
},
|
||||
'change_sidebar_image': {
|
||||
"str": 'changed the sidebar image',
|
||||
"icon": 'fa-image',
|
||||
"str": 'changed the sidebar image',
|
||||
"icon": 'fa-image',
|
||||
"color": 'bg-primary'
|
||||
},
|
||||
'change_marsey': {
|
||||
"str": 'changed the hole marsey',
|
||||
"icon": 'fa-cat',
|
||||
"str": 'changed the hole marsey',
|
||||
"icon": 'fa-cat',
|
||||
"color": 'bg-primary'
|
||||
},
|
||||
'pin_post': {
|
||||
"str": 'pinned post {self.target_link}',
|
||||
"icon": 'fa-thumbtack fa-rotate--45',
|
||||
"str": 'pinned post {self.target_link}',
|
||||
"icon": 'fa-thumbtack fa-rotate--45',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'unpin_post': {
|
||||
"str": 'unpinned post {self.target_link}',
|
||||
"icon": 'fa-thumbtack fa-rotate--45',
|
||||
"str": 'unpinned post {self.target_link}',
|
||||
"icon": 'fa-thumbtack fa-rotate--45',
|
||||
"color": 'bg-muted'
|
||||
},
|
||||
'pin_comment': {
|
||||
"str": 'pinned {self.target_link}',
|
||||
"icon": 'fa-thumbtack fa-rotate--45',
|
||||
"str": 'pinned {self.target_link}',
|
||||
"icon": 'fa-thumbtack fa-rotate--45',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'unpin_comment': {
|
||||
"str": 'unpinned {self.target_link}',
|
||||
"icon": 'fa-thumbtack fa-rotate--45',
|
||||
"str": 'unpinned {self.target_link}',
|
||||
"icon": 'fa-thumbtack fa-rotate--45',
|
||||
"color": 'bg-muted'
|
||||
},
|
||||
'enable_stealth': {
|
||||
"str": 'enabled stealth mode',
|
||||
"icon": 'fa-user-ninja',
|
||||
"str": 'enabled stealth mode',
|
||||
"icon": 'fa-user-ninja',
|
||||
"color": 'bg-primary'
|
||||
},
|
||||
'disable_stealth': {
|
||||
"str": 'disabled stealth mode',
|
||||
"icon": 'fa-user-ninja',
|
||||
"str": 'disabled stealth mode',
|
||||
"icon": 'fa-user-ninja',
|
||||
"color": 'bg-muted'
|
||||
},
|
||||
'set_nsfw': {
|
||||
"str": 'set nsfw on post {self.target_link}',
|
||||
"icon": 'fa-eye-evil',
|
||||
"str": 'set nsfw on post {self.target_link}',
|
||||
"icon": 'fa-eye-evil',
|
||||
"color": 'bg-danger'
|
||||
},
|
||||
'unset_nsfw': {
|
||||
"str": 'un-set nsfw on post {self.target_link}',
|
||||
"icon": 'fa-eye-evil',
|
||||
"str": 'un-set nsfw on post {self.target_link}',
|
||||
"icon": 'fa-eye-evil',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
'set_nsfw_comment': {
|
||||
"str": 'set nsfw on a {self.target_link}',
|
||||
"icon": 'fa-eye-evil',
|
||||
"str": 'set nsfw on a {self.target_link}',
|
||||
"icon": 'fa-eye-evil',
|
||||
"color": 'bg-danger'
|
||||
},
|
||||
'unset_nsfw_comment': {
|
||||
"str": 'un-set nsfw on a {self.target_link}',
|
||||
"icon": 'fa-eye-evil',
|
||||
"str": 'un-set nsfw on a {self.target_link}',
|
||||
"icon": 'fa-eye-evil',
|
||||
"color": 'bg-success'
|
||||
},
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ def get_users(usernames:Iterable[str], graceful=False) -> List[User]:
|
|||
return users
|
||||
|
||||
def get_account(id:Union[str, int], v:Optional[User]=None, graceful=False, include_blocks=False, include_shadowbanned=True) -> Optional[User]:
|
||||
try:
|
||||
try:
|
||||
id = int(id)
|
||||
except:
|
||||
if graceful: return None
|
||||
|
@ -97,7 +97,7 @@ def get_account(id:Union[str, int], v:Optional[User]=None, graceful=False, inclu
|
|||
|
||||
def get_accounts_dict(ids:Union[Iterable[str], Iterable[int]], v:Optional[User]=None, graceful=False, include_shadowbanned=True) -> Optional[dict[int, User]]:
|
||||
if not ids: return {}
|
||||
try:
|
||||
try:
|
||||
ids = set([int(id) for id in ids])
|
||||
except:
|
||||
if graceful: return None
|
||||
|
@ -132,15 +132,15 @@ def get_post(i:Union[str, int], v:Optional[User]=None, graceful=False) -> Option
|
|||
|
||||
post=post.filter(Submission.id == i
|
||||
).outerjoin(
|
||||
vt,
|
||||
vt.c.submission_id == Submission.id,
|
||||
vt,
|
||||
vt.c.submission_id == Submission.id,
|
||||
).outerjoin(
|
||||
blocking,
|
||||
blocking.c.target_id == Submission.author_id,
|
||||
blocking,
|
||||
blocking.c.target_id == Submission.author_id,
|
||||
)
|
||||
|
||||
post=post.one_or_none()
|
||||
|
||||
|
||||
if not post:
|
||||
if graceful: return None
|
||||
else: abort(404)
|
||||
|
@ -163,7 +163,7 @@ def get_posts(pids:Iterable[int], v:Optional[User]=None, eager:bool=False, extra
|
|||
|
||||
if v:
|
||||
vt = g.db.query(Vote.vote_type, Vote.submission_id).filter(
|
||||
Vote.submission_id.in_(pids),
|
||||
Vote.submission_id.in_(pids),
|
||||
Vote.user_id==v.id
|
||||
).subquery()
|
||||
|
||||
|
@ -180,11 +180,11 @@ def get_posts(pids:Iterable[int], v:Optional[User]=None, eager:bool=False, extra
|
|||
).outerjoin(
|
||||
vt, vt.c.submission_id==Submission.id
|
||||
).outerjoin(
|
||||
blocking,
|
||||
blocking.c.target_id == Submission.author_id,
|
||||
blocking,
|
||||
blocking.c.target_id == Submission.author_id,
|
||||
).outerjoin(
|
||||
blocked,
|
||||
blocked.c.user_id == Submission.author_id,
|
||||
blocked,
|
||||
blocked.c.user_id == Submission.author_id,
|
||||
)
|
||||
else:
|
||||
query = g.db.query(Submission).filter(Submission.id.in_(pids))
|
||||
|
@ -245,7 +245,7 @@ def add_block_props(target:Union[Submission, Comment, User], v:Optional[User]):
|
|||
id = target.id
|
||||
else:
|
||||
raise TypeError("add_block_props only supports non-None submissions, comments, and users")
|
||||
|
||||
|
||||
if hasattr(target, 'is_blocking') and hasattr(target, 'is_blocked'):
|
||||
return target
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ def end_lottery_session():
|
|||
chance_to_win = str(chance_to_win)[:3]
|
||||
if user.id == winner:
|
||||
notification_text = f'You won {active_lottery.prize} coins in the lottershe! ' \
|
||||
+ f'Congratulations!\nYour odds of winning were: {chance_to_win}%'
|
||||
+ f'Congratulations!\nYour odds of winning were: {chance_to_win}%'
|
||||
else:
|
||||
notification_text = f'You did not win the lottershe. Better luck next time!\n' \
|
||||
+ f'Your odds of winning were: {chance_to_win}%\nWinner: @{winning_user.username} (won {active_lottery.prize} coins)'
|
||||
|
|
|
@ -16,8 +16,8 @@ from files.classes.notifications import Notification
|
|||
|
||||
# Note: while https://api.pushshift.io/meta provides the key
|
||||
# server_ratelimit_per_minute, in practice Cloudflare puts stricter,
|
||||
# unofficially documented limits at around 60/minute. We get nowhere near this
|
||||
# with current keyword quantities. If this ever changes, consider reading the
|
||||
# unofficially documented limits at around 60/minute. We get nowhere near this
|
||||
# with current keyword quantities. If this ever changes, consider reading the
|
||||
# value from /meta (or just guessing) and doing a random selection of keywords.
|
||||
|
||||
def offsite_mentions_task(cache:Cache):
|
||||
|
@ -83,7 +83,7 @@ def get_mentions(cache:Cache, queries:Iterable[str], reddit_notifs_users=False):
|
|||
'text': text,
|
||||
})
|
||||
try:
|
||||
if not reddit_notifs_users:
|
||||
if not reddit_notifs_users:
|
||||
cache.set(const.REDDIT_NOTIFS_CACHE_KEY, after + 1)
|
||||
except:
|
||||
print("Failed to set cache value; there may be duplication of reddit notifications", flush=True)
|
||||
|
|
|
@ -150,7 +150,7 @@ def censor_slurs(body:Optional[str], logged_user):
|
|||
def replace_re(body:str, regex:re.Pattern, regex_upper:re.Pattern, sub_func, sub_func_upper):
|
||||
body = regex_upper.sub(sub_func_upper, body)
|
||||
return regex.sub(sub_func, body)
|
||||
|
||||
|
||||
if not logged_user or logged_user == 'chat' or logged_user.slurreplacer:
|
||||
body = replace_re(body, slur_regex, slur_regex_upper, sub_matcher_slurs, sub_matcher_slurs_upper)
|
||||
if SITE_NAME == 'rDrama':
|
||||
|
|
|
@ -10,7 +10,7 @@ from files.helpers.alerts import *
|
|||
from files.helpers.get import get_account
|
||||
|
||||
class RouletteAction(str, Enum):
|
||||
STRAIGHT_UP_BET = "STRAIGHT_UP_BET",
|
||||
STRAIGHT_UP_BET = "STRAIGHT_UP_BET",
|
||||
LINE_BET = "LINE_BET"
|
||||
COLUMN_BET = "COLUMN_BET"
|
||||
DOZEN_BET = "DOZEN_BET"
|
||||
|
|
|
@ -96,7 +96,7 @@ def allowed_attributes(tag, name, value):
|
|||
|
||||
if tag == 'table':
|
||||
if name == 'class' and value == 'table': return True
|
||||
|
||||
|
||||
return False
|
||||
|
||||
def build_url_re(tlds, protocols):
|
||||
|
|
|
@ -54,7 +54,7 @@ def casino_slot_pull(gambler, wager_value, currency):
|
|||
|
||||
return casino_game.id, casino_game.game_state
|
||||
else:
|
||||
return None, "{}",
|
||||
return None, "{}",
|
||||
|
||||
|
||||
def build_symbols(for_payout):
|
||||
|
@ -132,7 +132,7 @@ def check_slots_command(c:Comment, v:User, u:User):
|
|||
currency = 'coins'
|
||||
else:
|
||||
return
|
||||
|
||||
|
||||
if u.rehab:
|
||||
if v.id == u.id:
|
||||
abort(403, "You are under Rehab award effect!")
|
||||
|
@ -146,7 +146,7 @@ def check_slots_command(c:Comment, v:User, u:User):
|
|||
abort(400, "Invalid wager.")
|
||||
return
|
||||
|
||||
if wager < 100:
|
||||
if wager < 100:
|
||||
if v.id == u.id:
|
||||
abort(400, f"Wager must be 100 {currency} or more")
|
||||
return
|
||||
|
|
|
@ -38,25 +38,25 @@ def chart(kind, site):
|
|||
day_cutoffs = [today_cutoff - 86400 * 7 * i for i in range(num_of_weeks)][1:]
|
||||
day_cutoffs.insert(0, calendar.timegm(now))
|
||||
|
||||
daily_times = [time.strftime('%d/%m', time.gmtime(day_cutoffs[i + 1]))
|
||||
daily_times = [time.strftime('%d/%m', time.gmtime(day_cutoffs[i + 1]))
|
||||
for i in range(len(day_cutoffs) - 1)][::-1]
|
||||
|
||||
daily_signups = [g.db.query(User).filter(
|
||||
User.created_utc < day_cutoffs[i],
|
||||
User.created_utc > day_cutoffs[i + 1]).count()
|
||||
User.created_utc < day_cutoffs[i],
|
||||
User.created_utc > day_cutoffs[i + 1]).count()
|
||||
for i in range(len(day_cutoffs) - 1)][::-1]
|
||||
|
||||
post_stats = [g.db.query(Submission).filter(
|
||||
Submission.created_utc < day_cutoffs[i],
|
||||
Submission.created_utc > day_cutoffs[i + 1],
|
||||
Submission.is_banned == False).count()
|
||||
Submission.created_utc < day_cutoffs[i],
|
||||
Submission.created_utc > day_cutoffs[i + 1],
|
||||
Submission.is_banned == False).count()
|
||||
for i in range(len(day_cutoffs) - 1)][::-1]
|
||||
|
||||
comment_stats = [g.db.query(Comment).filter(
|
||||
Comment.created_utc < day_cutoffs[i],
|
||||
Comment.created_utc < day_cutoffs[i],
|
||||
Comment.created_utc > day_cutoffs[i + 1],
|
||||
Comment.is_banned == False,
|
||||
Comment.author_id != AUTOJANNY_ID).count()
|
||||
Comment.is_banned == False,
|
||||
Comment.author_id != AUTOJANNY_ID).count()
|
||||
for i in range(len(day_cutoffs) - 1)][::-1]
|
||||
|
||||
plt.rcParams['figure.figsize'] = (chart_width, 20)
|
||||
|
|
|
@ -83,7 +83,7 @@ def get_active_twentyone_game_state(gambler):
|
|||
|
||||
def charge_gambler(gambler, amount, currency):
|
||||
charged = gambler.charge_account(currency, amount)
|
||||
|
||||
|
||||
if not charged:
|
||||
raise Exception("Gambler cannot afford charge.")
|
||||
|
||||
|
@ -244,7 +244,7 @@ def handle_payout(gambler, state, game):
|
|||
raise Exception("Attempted to payout a game that has not finished.")
|
||||
|
||||
gambler.pay_account(game.currency, payout)
|
||||
|
||||
|
||||
if game.currency == 'coins':
|
||||
if status in {BlackjackStatus.BLACKJACK, BlackjackStatus.WON}:
|
||||
distribute_wager_badges(gambler, game.wager, won=True)
|
||||
|
@ -259,7 +259,7 @@ def handle_payout(gambler, state, game):
|
|||
|
||||
def remove_exploitable_information(state):
|
||||
safe_state = state
|
||||
|
||||
|
||||
if len(safe_state['dealer']) >= 2:
|
||||
safe_state['dealer'][1] = '?'
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ def move_acc(v:User, new_id, old_id):
|
|||
|
||||
old_id = int(old_id)
|
||||
new_id = int(new_id)
|
||||
|
||||
|
||||
olduser = g.db.get(User, old_id)
|
||||
newuser = g.db.get(User, new_id)
|
||||
|
||||
|
@ -307,7 +307,7 @@ def distribute(v:User, option_id):
|
|||
losing_voters.extend([x.user_id for x in o.votes])
|
||||
for uid in losing_voters:
|
||||
add_notif(cid, uid)
|
||||
|
||||
|
||||
ma = ModAction(
|
||||
kind="distribute",
|
||||
user_id=v.id,
|
||||
|
@ -455,7 +455,7 @@ def admin_home(v):
|
|||
if v.admin_level >= PERMS['SITE_SETTINGS_UNDER_ATTACK']:
|
||||
under_attack = (get_security_level() or 'high') == 'under_attack'
|
||||
|
||||
return render_template("admin/admin_home.html", v=v,
|
||||
return render_template("admin/admin_home.html", v=v,
|
||||
under_attack=under_attack)
|
||||
|
||||
@app.post("/admin/site_settings/<setting>")
|
||||
|
@ -575,7 +575,7 @@ def badge_grant_post(v):
|
|||
if v.id != user.id:
|
||||
text = f"@{v.username} (a site admin) has given you the following profile badge:\n\n![]({new_badge.path})\n\n**{new_badge.name}**\n\n{new_badge.badge.description}"
|
||||
send_repeatable_notification(user.id, text)
|
||||
|
||||
|
||||
ma = ModAction(
|
||||
kind="badge_grant",
|
||||
user_id=v.id,
|
||||
|
@ -851,7 +851,7 @@ def admin_removed(v):
|
|||
def admin_removed_comments(v):
|
||||
try: page = int(request.values.get("page", 1))
|
||||
except: page = 1
|
||||
|
||||
|
||||
ids = g.db.query(Comment.id).join(Comment.author).filter(or_(Comment.is_banned==True, User.shadowbanned != None)).order_by(Comment.id.desc()).offset(PAGE_SIZE * (page - 1)).limit(PAGE_SIZE + 1).all()
|
||||
ids=[x[0] for x in ids]
|
||||
next_exists = len(ids) > PAGE_SIZE
|
||||
|
@ -926,7 +926,7 @@ def shadowban(user_id, v):
|
|||
_note=f'reason: "{reason}"'
|
||||
)
|
||||
g.db.add(ma)
|
||||
|
||||
|
||||
cache.delete_memoized(frontlist)
|
||||
|
||||
return {"message": f"@{user.username} has been shadowbanned!"}
|
||||
|
@ -951,7 +951,7 @@ def unshadowban(user_id, v):
|
|||
target_user_id=user.id,
|
||||
)
|
||||
g.db.add(ma)
|
||||
|
||||
|
||||
cache.delete_memoized(frontlist)
|
||||
|
||||
return {"message": f"@{user.username} has been unshadowbanned!"}
|
||||
|
@ -982,7 +982,7 @@ def admin_title_change(user_id, v):
|
|||
|
||||
if user.flairchanged: kind = "set_flair_locked"
|
||||
else: kind = "set_flair_notlocked"
|
||||
|
||||
|
||||
ma=ModAction(
|
||||
kind=kind,
|
||||
user_id=v.id,
|
||||
|
@ -1379,7 +1379,7 @@ def unsticky_post(post_id, v):
|
|||
if post.stickied:
|
||||
if FEATURES['AWARDS'] and post.stickied.endswith(PIN_AWARD_TEXT): abort(403, "Can't unpin award pins!")
|
||||
if post.author_id == LAWLZ_ID and post.stickied_utc and SITE_NAME == 'rDrama': abort(403, "Can't unpin lawlzposts!")
|
||||
|
||||
|
||||
post.stickied = None
|
||||
post.stickied_utc = None
|
||||
g.db.add(post)
|
||||
|
@ -1424,13 +1424,13 @@ def sticky_comment(cid, v):
|
|||
g.db.add(c)
|
||||
|
||||
return {"message": "Comment pinned!"}
|
||||
|
||||
|
||||
|
||||
@app.post("/unsticky_comment/<int:cid>")
|
||||
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
|
||||
def unsticky_comment(cid, v):
|
||||
comment = get_comment(cid, v=v)
|
||||
|
||||
|
||||
if comment.stickied:
|
||||
if FEATURES['AWARDS'] and comment.stickied.endswith(PIN_AWARD_TEXT): abort(403, "Can't unpin award pins!")
|
||||
|
||||
|
@ -1481,7 +1481,7 @@ def remove_comment(c_id, v):
|
|||
@admin_level_required(PERMS['POST_COMMENT_MODERATION'])
|
||||
def approve_comment(c_id, v):
|
||||
comment = get_comment(c_id)
|
||||
|
||||
|
||||
if comment.author.id == v.id and comment.author.agendaposter and AGENDAPOSTER_PHRASE not in comment.body.lower() and not (comment.parent_submission and comment.post.sub == 'chudrama'):
|
||||
abort(400, "You can't bypass the chud award!")
|
||||
|
||||
|
@ -1572,7 +1572,7 @@ def ban_domain(v):
|
|||
def unban_domain(v:User, domain):
|
||||
existing = g.db.get(BannedDomain, domain)
|
||||
if not existing: abort(400, 'Domain is not banned!')
|
||||
|
||||
|
||||
g.db.delete(existing)
|
||||
ma = ModAction(
|
||||
kind="unban_domain",
|
||||
|
@ -1595,7 +1595,7 @@ def admin_nuke_user(v):
|
|||
for post in g.db.query(Submission).filter_by(author_id=user.id).all():
|
||||
if post.is_banned:
|
||||
continue
|
||||
|
||||
|
||||
post.is_banned = True
|
||||
post.ban_reason = v.username
|
||||
g.db.add(post)
|
||||
|
@ -1628,7 +1628,7 @@ def admin_nunuke_user(v):
|
|||
for post in g.db.query(Submission).filter_by(author_id=user.id).all():
|
||||
if not post.is_banned:
|
||||
continue
|
||||
|
||||
|
||||
post.is_banned = False
|
||||
post.ban_reason = None
|
||||
post.is_approved = v.id
|
||||
|
|
|
@ -63,7 +63,7 @@ def after_request(response:Response):
|
|||
if response.status_code < 400:
|
||||
_set_cloudflare_cookie(response)
|
||||
_commit_and_close_db()
|
||||
|
||||
|
||||
return response
|
||||
|
||||
|
||||
|
@ -82,7 +82,7 @@ def _set_cloudflare_cookie(response:Response) -> None:
|
|||
if not logged_in and request.cookies.get("lo"):
|
||||
response.delete_cookie("lo", domain=app.config["COOKIE_DOMAIN"], samesite="Lax")
|
||||
elif logged_in and not request.cookies.get("lo"):
|
||||
response.set_cookie("lo", CLOUDFLARE_COOKIE_VALUE if logged_in else '',
|
||||
response.set_cookie("lo", CLOUDFLARE_COOKIE_VALUE if logged_in else '',
|
||||
max_age=SESSION_LIFETIME, samesite="Lax",
|
||||
domain=app.config["COOKIE_DOMAIN"])
|
||||
|
||||
|
|
|
@ -371,7 +371,7 @@ def update_marsey(v):
|
|||
return error("Image uploads are not allowed through TOR.")
|
||||
if not file.content_type.startswith('image/'):
|
||||
return error("You need to submit an image!")
|
||||
|
||||
|
||||
for x in IMAGE_FORMATS:
|
||||
if path.isfile(f'/asset_submissions/marseys/original/{name}.{x}'):
|
||||
os.remove(f'/asset_submissions/marseys/original/{name}.{x}')
|
||||
|
@ -387,7 +387,7 @@ def update_marsey(v):
|
|||
copyfile(new_path, filename)
|
||||
process_image(filename, v, resize=200, trim=True)
|
||||
purge_files_in_cache([f"https://{SITE}/e/{name}.webp", f"https://{SITE}/assets/images/emojis/{name}.webp", f"https://{SITE}/asset_submissions/marseys/original/{name}.{format}"])
|
||||
|
||||
|
||||
if tags and existing.tags != tags and tags != "none":
|
||||
existing.tags = tags
|
||||
g.db.add(existing)
|
||||
|
|
|
@ -103,7 +103,7 @@ def buy(v:User, award):
|
|||
v.lootboxes_bought += 1
|
||||
lootbox_msg = "You open your lootbox and receive: " + ', '.join(lootbox_items)
|
||||
send_repeatable_notification(v.id, lootbox_msg)
|
||||
|
||||
|
||||
if v.lootboxes_bought == 10:
|
||||
badge_grant(badge_id=76, user=v)
|
||||
elif v.lootboxes_bought == 50:
|
||||
|
@ -131,16 +131,16 @@ def buy(v:User, award):
|
|||
def award_thing(v, thing_type, id):
|
||||
kind = request.values.get("kind", "").strip()
|
||||
|
||||
if thing_type == 'post':
|
||||
if thing_type == 'post':
|
||||
thing = get_post(id)
|
||||
else:
|
||||
else:
|
||||
thing = get_comment(id)
|
||||
if not thing.parent_submission and not thing.wall_user_id: abort(404) # don't let users award messages
|
||||
|
||||
if v.shadowbanned: abort(500)
|
||||
author = thing.author
|
||||
if author.shadowbanned: abort(404)
|
||||
|
||||
|
||||
AWARDS = deepcopy(AWARDS_ENABLED)
|
||||
if v.house:
|
||||
AWARDS[v.house] = HOUSE_AWARDS[v.house]
|
||||
|
@ -288,7 +288,7 @@ def award_thing(v, thing_type, id):
|
|||
|
||||
if author.agendaposter and time.time() < author.agendaposter: author.agendaposter += 86400
|
||||
else: author.agendaposter = int(time.time()) + 86400
|
||||
|
||||
|
||||
badge_grant(user=author, badge_id=28)
|
||||
elif kind == "flairlock":
|
||||
new_name = note[:100].replace("𒐪","").replace("﷽","").strip()
|
||||
|
@ -375,10 +375,10 @@ def award_thing(v, thing_type, id):
|
|||
elif "Vampire" in kind and kind == v.house:
|
||||
if author.bite: author.bite += 172800
|
||||
else: author.bite = int(time.time()) + 172800
|
||||
|
||||
|
||||
if not author.old_house:
|
||||
author.old_house = author.house
|
||||
|
||||
|
||||
if 'Vampire' not in author.house:
|
||||
author.house = 'Vampire'
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ def casino_game_page(v:User, game):
|
|||
@limiter.limit("100/minute;2000/hour;12000/day")
|
||||
@auth_required
|
||||
def casino_game_feed(v:User, game):
|
||||
if v.rehab:
|
||||
if v.rehab:
|
||||
abort(403, "You are under Rehab award effect!")
|
||||
elif game not in CASINO_GAME_KINDS:
|
||||
abort(404)
|
||||
|
|
|
@ -83,7 +83,7 @@ def speak(data, v):
|
|||
"text_censored": censor_slurs(text_html, 'chat'),
|
||||
"time": int(time.time()),
|
||||
}
|
||||
|
||||
|
||||
if v.shadowbanned or not execute_blackjack(v, None, text, "chat"):
|
||||
emit('speak', data)
|
||||
elif recipient:
|
||||
|
|
|
@ -43,7 +43,7 @@ def post_pid_comment_cid(cid, pid=None, anything=None, v=None, sub=None):
|
|||
g.db.commit()
|
||||
|
||||
post = comment.post
|
||||
|
||||
|
||||
if post.over_18 and not (v and v.over_18) and not session.get('over_18', 0) >= int(time.time()):
|
||||
if v and v.client: abort(403, "This content is not suitable for some users and situations.")
|
||||
else: return render_template("errors/nsfw.html", v=v), 403
|
||||
|
@ -70,9 +70,9 @@ def post_pid_comment_cid(cid, pid=None, anything=None, v=None, sub=None):
|
|||
|
||||
execute_shadowban_viewers_and_voters(v, post)
|
||||
execute_shadowban_viewers_and_voters(v, comment)
|
||||
|
||||
|
||||
if v and v.client: return top_comment.json(db=g.db)
|
||||
else:
|
||||
else:
|
||||
if post.is_banned and not (v and (v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or post.author_id == v.id)): template = "submission_banned.html"
|
||||
else: template = "submission.html"
|
||||
return render_template(template, v=v, p=post, sort=sort, comment_info=comment_info, render_replies=True, sub=post.subr)
|
||||
|
@ -107,7 +107,7 @@ def comment(v:User):
|
|||
post_target = get_post(parent.parent_submission, v=v, graceful=True) or get_account(parent.wall_user_id, v=v, include_blocks=True, include_shadowbanned=False)
|
||||
parent_comment_id = parent.id
|
||||
if parent.author_id == v.id: rts = True
|
||||
if not v.can_post_in_ghost_threads and isinstance(post_target, Submission) and post_target.ghost:
|
||||
if not v.can_post_in_ghost_threads and isinstance(post_target, Submission) and post_target.ghost:
|
||||
abort(403, f"You need {TRUESCORE_GHOST_MINIMUM} truescore to post in ghost threads")
|
||||
ghost = parent.ghost
|
||||
else: abort(404)
|
||||
|
@ -200,7 +200,7 @@ def comment(v:User):
|
|||
abort(415)
|
||||
|
||||
body = body.strip()[:COMMENT_BODY_LENGTH_LIMIT]
|
||||
|
||||
|
||||
if v.admin_level >= PERMS['SITE_SETTINGS_SNAPPY_QUOTES'] and posting_to_submission and post_target.id == SNAPPY_THREAD and level == 1:
|
||||
with open(f"snappy_{SITE_NAME}.txt", "a", encoding="utf-8") as f:
|
||||
f.write('\n{[para]}\n' + body)
|
||||
|
@ -297,7 +297,7 @@ def comment(v:User):
|
|||
|
||||
for x in subscribers:
|
||||
notify_users.add(x[0])
|
||||
|
||||
|
||||
if parent_user.id != v.id:
|
||||
notify_users.add(parent_user.id)
|
||||
|
||||
|
@ -422,9 +422,9 @@ def edit_comment(cid, v):
|
|||
if int(time.time()) - c.created_utc > 60 * 3: c.edited_utc = int(time.time())
|
||||
|
||||
g.db.add(c)
|
||||
|
||||
|
||||
notify_users = NOTIFY_USERS(body, v)
|
||||
|
||||
|
||||
for x in notify_users-bots:
|
||||
notif = g.db.query(Notification).filter_by(comment_id=c.id, user_id=x).one_or_none()
|
||||
if not notif:
|
||||
|
@ -481,12 +481,12 @@ def undelete_comment(cid, v):
|
|||
@feature_required('PINS')
|
||||
@auth_required
|
||||
def pin_comment(cid, v):
|
||||
|
||||
|
||||
comment = get_comment(cid, v=v)
|
||||
|
||||
|
||||
if not comment.stickied:
|
||||
if v.id != comment.post.author_id: abort(403)
|
||||
|
||||
|
||||
if comment.post.ghost: comment.stickied = "(OP)"
|
||||
else: comment.stickied = v.username + " (OP)"
|
||||
|
||||
|
@ -498,18 +498,18 @@ def pin_comment(cid, v):
|
|||
send_repeatable_notification(comment.author_id, message)
|
||||
|
||||
return {"message": "Comment pinned!"}
|
||||
|
||||
|
||||
|
||||
@app.post("/unpin_comment/<int:cid>")
|
||||
@auth_required
|
||||
def unpin_comment(cid, v):
|
||||
|
||||
|
||||
comment = get_comment(cid, v=v)
|
||||
|
||||
|
||||
if comment.stickied:
|
||||
if v.id != comment.post.author_id: abort(403)
|
||||
|
||||
if not comment.stickied.endswith(" (OP)"):
|
||||
if not comment.stickied.endswith(" (OP)"):
|
||||
abort(403, "You can only unpin comments you have pinned!")
|
||||
|
||||
comment.stickied = None
|
||||
|
@ -602,7 +602,7 @@ def handle_wordle_action(cid, v):
|
|||
comment.wordle_result = f'{guesses}_{status}_{answer}'
|
||||
|
||||
g.db.add(comment)
|
||||
|
||||
|
||||
return {"response" : comment.wordle_html(v)}
|
||||
|
||||
|
||||
|
@ -613,7 +613,7 @@ def toggle_comment_nsfw(cid, v):
|
|||
|
||||
if comment.author_id != v.id and not v.admin_level >= PERMS['POST_COMMENT_MODERATION'] and not (comment.post.sub and v.mods(comment.post.sub)):
|
||||
abort(403)
|
||||
|
||||
|
||||
if comment.over_18 and v.is_suspended_permanently:
|
||||
abort(403)
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ def feeds_user(sort='hot', t='all'):
|
|||
t=t,
|
||||
v=None,
|
||||
)
|
||||
|
||||
|
||||
posts = get_posts(ids)
|
||||
|
||||
doc, tag, text = Doc().tagtext()
|
||||
|
@ -54,7 +54,7 @@ def feeds_user(sort='hot', t='all'):
|
|||
|
||||
with tag("published"):
|
||||
text(datetime.datetime.utcfromtimestamp(post.created_utc).isoformat()+"Z")
|
||||
|
||||
|
||||
with tag("author"):
|
||||
with tag("name"):
|
||||
text(post.author_name)
|
||||
|
|
|
@ -35,7 +35,7 @@ def front_all(v, sub=None, subdomain=None):
|
|||
sub = get_sub_by_name(sub, graceful=True)
|
||||
if sub and not User.can_see(v, sub):
|
||||
abort(403)
|
||||
|
||||
|
||||
if (request.path.startswith('/h/') or request.path.startswith('/s/')) and not sub: abort(404)
|
||||
|
||||
try: page = max(int(request.values.get("page", 1)), 1)
|
||||
|
@ -52,7 +52,7 @@ def front_all(v, sub=None, subdomain=None):
|
|||
|
||||
sort=request.values.get("sort", defaultsorting)
|
||||
t=request.values.get('t', defaulttime)
|
||||
|
||||
|
||||
try: gt=int(request.values.get("after", 0))
|
||||
except: gt=0
|
||||
|
||||
|
@ -79,7 +79,7 @@ def front_all(v, sub=None, subdomain=None):
|
|||
)
|
||||
|
||||
posts = get_posts(ids, v=v, eager=True)
|
||||
|
||||
|
||||
if v:
|
||||
if v.hidevotedon: posts = [x for x in posts if not hasattr(x, 'voted') or not x.voted]
|
||||
award_timers(v)
|
||||
|
@ -91,7 +91,7 @@ def front_all(v, sub=None, subdomain=None):
|
|||
@cache.memoize(timeout=86400)
|
||||
def frontlist(v=None, sort="hot", page=1, t="all", ids_only=True, filter_words='', gt=0, lt=0, sub=None, site=None, pins=True, holes=True):
|
||||
posts = g.db.query(Submission)
|
||||
|
||||
|
||||
if v and v.hidevotedon:
|
||||
posts = posts.outerjoin(Vote,
|
||||
and_(Vote.submission_id == Submission.id, Vote.user_id == v.id)
|
||||
|
@ -148,7 +148,7 @@ def frontlist(v=None, sort="hot", page=1, t="all", ids_only=True, filter_words='
|
|||
pins = g.db.query(Submission).filter(Submission.sub == sub.name, Submission.hole_pinned != None)
|
||||
else:
|
||||
pins = g.db.query(Submission).filter(Submission.stickied != None, Submission.is_banned == False)
|
||||
|
||||
|
||||
if v:
|
||||
pins = pins.filter(or_(Submission.sub == None, Submission.sub.notin_(v.all_blocks)))
|
||||
for pin in pins:
|
||||
|
@ -184,7 +184,7 @@ def random_post(v:User):
|
|||
@auth_required
|
||||
def random_user(v:User):
|
||||
u = g.db.query(User.username).filter(User.song != None, User.shadowbanned == None).order_by(func.random()).first()
|
||||
|
||||
|
||||
if u: u = u[0]
|
||||
else: abort(404, "No users have set a profile anthem so far!")
|
||||
|
||||
|
|
|
@ -63,14 +63,14 @@ def calc_users():
|
|||
ua = str(user_agents.parse(g.agent))
|
||||
if 'spider' not in ua.lower() and 'bot' not in ua.lower():
|
||||
loggedout[session["session_id"]] = (timestamp, ua)
|
||||
|
||||
|
||||
loggedin = {k: v for k, v in loggedin.items() if (timestamp - v) < LOGGEDIN_ACTIVE_TIME}
|
||||
loggedout = {k: v for k, v in loggedout.items() if (timestamp - v[0]) < LOGGEDIN_ACTIVE_TIME}
|
||||
cache.set(LOGGED_IN_CACHE_KEY, loggedin)
|
||||
cache.set(LOGGED_OUT_CACHE_KEY, loggedout)
|
||||
loggedin_counter = len(loggedin)
|
||||
loggedout_counter = len(loggedout)
|
||||
return {'loggedin_counter':loggedin_counter,
|
||||
return {'loggedin_counter':loggedin_counter,
|
||||
'loggedout_counter':loggedout_counter,
|
||||
'loggedin_chat':loggedin_chat}
|
||||
|
||||
|
@ -82,7 +82,7 @@ def inject_constants():
|
|||
return {"environ":environ, "SITE":SITE, "SITE_NAME":SITE_NAME, "SITE_FULL":SITE_FULL,
|
||||
"AUTOJANNY_ID":AUTOJANNY_ID, "MODMAIL_ID":MODMAIL_ID, "VAPID_PUBLIC_KEY":VAPID_PUBLIC_KEY,
|
||||
"listdir":listdir, "os_path":path, "AEVANN_ID":AEVANN_ID,
|
||||
"PIZZASHILL_ID":PIZZASHILL_ID, "DEFAULT_COLOR":DEFAULT_COLOR,
|
||||
"PIZZASHILL_ID":PIZZASHILL_ID, "DEFAULT_COLOR":DEFAULT_COLOR,
|
||||
"COLORS":COLORS, "time":time, "PERMS":PERMS, "FEATURES":FEATURES,
|
||||
"HOLE_NAME":HOLE_NAME, "HOLE_STYLE_FLAIR":HOLE_STYLE_FLAIR, "HOLE_REQUIRED":HOLE_REQUIRED,
|
||||
"GUMROAD_LINK":GUMROAD_LINK, "DEFAULT_THEME":DEFAULT_THEME, "DESCRIPTION":DESCRIPTION,
|
||||
|
@ -95,9 +95,9 @@ def inject_constants():
|
|||
"site_settings":get_settings(), "EMAIL":EMAIL, "max": max, "min": min, "user_can_see":User.can_see,
|
||||
"TELEGRAM_ID":TELEGRAM_ID, "EMAIL_REGEX_PATTERN":EMAIL_REGEX_PATTERN,
|
||||
"TRUESCORE_DONATE_MINIMUM":TRUESCORE_DONATE_MINIMUM,
|
||||
"DONATE_LINK":DONATE_LINK, "DONATE_SERVICE":DONATE_SERVICE, "BAN_EVASION_DOMAIN":BAN_EVASION_DOMAIN,
|
||||
"DONATE_LINK":DONATE_LINK, "DONATE_SERVICE":DONATE_SERVICE, "BAN_EVASION_DOMAIN":BAN_EVASION_DOMAIN,
|
||||
"HOUSE_JOIN_COST":HOUSE_JOIN_COST, "HOUSE_SWITCH_COST":HOUSE_SWITCH_COST, "IMAGE_FORMATS":','.join(IMAGE_FORMATS),
|
||||
"PAGE_SIZES":PAGE_SIZES, "THEMES":THEMES, "COMMENT_SORTS":COMMENT_SORTS, "SORTS":SORTS,
|
||||
"TIME_FILTERS":TIME_FILTERS, "HOUSES":HOUSES, "TIERS_ID_TO_NAME":TIERS_ID_TO_NAME,
|
||||
"PAGE_SIZES":PAGE_SIZES, "THEMES":THEMES, "COMMENT_SORTS":COMMENT_SORTS, "SORTS":SORTS,
|
||||
"TIME_FILTERS":TIME_FILTERS, "HOUSES":HOUSES, "TIERS_ID_TO_NAME":TIERS_ID_TO_NAME,
|
||||
"DEFAULT_CONFIG_VALUE":DEFAULT_CONFIG_VALUE, "IS_LOCALHOST":IS_LOCALHOST, "BACKGROUND_CATEGORIES":BACKGROUND_CATEGORIES, "PAGE_SIZE":PAGE_SIZE, "TAGLINES":TAGLINES, "IS_FISTMAS":IS_FISTMAS, "get_alt_graph":get_alt_graph, "current_registered_users":current_registered_users
|
||||
}
|
||||
|
|
|
@ -346,7 +346,7 @@ def sign_up_post(v:Optional[User]):
|
|||
|
||||
check_for_alts(new_user)
|
||||
send_notification(new_user.id, WELCOME_MSG)
|
||||
|
||||
|
||||
if SIGNUP_FOLLOW_ID:
|
||||
signup_autofollow = get_account(SIGNUP_FOLLOW_ID)
|
||||
new_follow = Follow(user_id=new_user.id, target_id=signup_autofollow.id)
|
||||
|
@ -502,7 +502,7 @@ def request_2fa_disable():
|
|||
token=generate_hash(f"{user.id}+{user.username}+disable2fa+{valid}+{user.mfa_secret}+{user.login_nonce}")
|
||||
|
||||
action_url=f"{SITE_FULL}/reset_2fa?id={user.id}&t={valid}&token={token}"
|
||||
|
||||
|
||||
send_mail(to_address=user.email,
|
||||
subject="2FA Removal Request",
|
||||
html=render_template("email/2fa_remove.html",
|
||||
|
|
|
@ -329,7 +329,7 @@ def notifications(v:User):
|
|||
total.extend(c.replies2)
|
||||
|
||||
if c not in listing: listing.append(c)
|
||||
|
||||
|
||||
total.extend(listing)
|
||||
|
||||
total_cids = [x.id for x in total]
|
||||
|
|
|
@ -97,7 +97,7 @@ def delete_oauth_app(v, aid):
|
|||
abort(404)
|
||||
app = g.db.get(OauthApp, aid)
|
||||
if not app: abort(404)
|
||||
|
||||
|
||||
if app.author_id != v.id: abort(403)
|
||||
|
||||
for auth in g.db.query(ClientAuth).filter_by(oauth_client=app.id).all():
|
||||
|
|
|
@ -22,7 +22,7 @@ def vote_option(option_id, v):
|
|||
if option.exclusive == 2:
|
||||
if option.post.total_bet_voted(v):
|
||||
abort(403, "You can't bet on a closed poll!")
|
||||
if not v.charge_account('coins', POLL_BET_COINS):
|
||||
if not v.charge_account('coins', POLL_BET_COINS):
|
||||
abort(400, f"You don't have {POLL_BET_COINS} coins!")
|
||||
g.db.add(v)
|
||||
autojanny = get_account(AUTOJANNY_ID)
|
||||
|
|
|
@ -45,7 +45,7 @@ def publish(pid, v):
|
|||
post.private = False
|
||||
post.created_utc = int(time.time())
|
||||
g.db.add(post)
|
||||
|
||||
|
||||
if not post.ghost:
|
||||
notify_users = NOTIFY_USERS(f'{post.title} {post.body}', v)
|
||||
|
||||
|
@ -189,7 +189,7 @@ def view_more(v, pid, sort, offset):
|
|||
except: abort(400)
|
||||
try: ids = set(int(x) for x in request.values.get("ids").split(','))
|
||||
except: abort(400)
|
||||
|
||||
|
||||
if v:
|
||||
# shadowban check is done in sort_objects
|
||||
# output is needed: see comments.py
|
||||
|
@ -209,7 +209,7 @@ def view_more(v, pid, sort, offset):
|
|||
|
||||
comments = sort_objects(sort, comments, Comment,
|
||||
include_shadowbanned=False)
|
||||
|
||||
|
||||
comments = comments.offset(offset).all()
|
||||
|
||||
comments2 = []
|
||||
|
@ -226,7 +226,7 @@ def view_more(v, pid, sort, offset):
|
|||
ids.add(comment.id)
|
||||
count += g.db.query(Comment).filter_by(parent_submission=post.id, parent_comment_id=comment.id).count() + 1
|
||||
if count > 20: break
|
||||
|
||||
|
||||
if len(comments) == len(comments2): offset = 0
|
||||
else: offset += 1
|
||||
comments = comments2
|
||||
|
@ -255,7 +255,7 @@ def more_comments(v, cid):
|
|||
|
||||
if comments: p = comments[0].post
|
||||
else: p = None
|
||||
|
||||
|
||||
return render_template("comments.html", v=v, comments=comments, p=p, render_replies=True)
|
||||
|
||||
@app.post("/edit_post/<int:pid>")
|
||||
|
@ -320,7 +320,7 @@ def edit_post(pid, v):
|
|||
for text in [p.body, p.title, p.url]:
|
||||
if not execute_blackjack(v, p, text, 'submission'): break
|
||||
|
||||
if len(body_html) > POST_BODY_HTML_LENGTH_LIMIT:
|
||||
if len(body_html) > POST_BODY_HTML_LENGTH_LIMIT:
|
||||
abort(400, f"Submission body_html too long!")
|
||||
|
||||
p.body_html = body_html
|
||||
|
@ -367,13 +367,13 @@ def thumbnail_thread(pid:int, vid:int):
|
|||
return f"{post_url}/{fragment_url}"
|
||||
|
||||
post = db.get(Submission, pid)
|
||||
|
||||
|
||||
if not post or not post.url:
|
||||
time.sleep(5)
|
||||
post = db.get(Submission, pid)
|
||||
|
||||
if not post or not post.url: return
|
||||
|
||||
|
||||
fetch_url = post.url
|
||||
|
||||
if fetch_url.startswith('/') and '\\' not in fetch_url:
|
||||
|
@ -404,12 +404,12 @@ def thumbnail_thread(pid:int, vid:int):
|
|||
]
|
||||
|
||||
for tag_name in meta_tags:
|
||||
|
||||
|
||||
|
||||
tag = soup.find(
|
||||
'meta',
|
||||
'meta',
|
||||
attrs={
|
||||
"name": tag_name,
|
||||
"name": tag_name,
|
||||
"content": True
|
||||
}
|
||||
)
|
||||
|
@ -510,7 +510,7 @@ def is_repost():
|
|||
params=parsed_url.params,
|
||||
query=urlencode(filtered, doseq=True),
|
||||
fragment=parsed_url.fragment)
|
||||
|
||||
|
||||
url = urlunparse(new_url)
|
||||
url = url.rstrip('/')
|
||||
|
||||
|
@ -539,7 +539,7 @@ def submit_post(v:User, sub=None):
|
|||
|
||||
def error(error):
|
||||
if g.is_api_or_xhr: abort(400, error)
|
||||
|
||||
|
||||
SUBS = [x[0] for x in g.db.query(Sub.name).order_by(Sub.name).all()]
|
||||
return render_template("submit.html", SUBS=SUBS, v=v, error=error, title=title, url=url, body=body), 400
|
||||
|
||||
|
@ -555,7 +555,7 @@ def submit_post(v:User, sub=None):
|
|||
title_html = filter_emojis_only(title, graceful=True, count_marseys=True, torture=torture)
|
||||
if v.marseyawarded and not marseyaward_title_regex.fullmatch(title_html):
|
||||
return error("You can only type marseys!")
|
||||
if len(title_html) > POST_TITLE_HTML_LENGTH_LIMIT:
|
||||
if len(title_html) > POST_TITLE_HTML_LENGTH_LIMIT:
|
||||
return error("Rendered title is too big!")
|
||||
|
||||
if sub == 'changelog' and not v.admin_level >= PERMS['POST_TO_CHANGELOG']:
|
||||
|
@ -610,7 +610,7 @@ def submit_post(v:User, sub=None):
|
|||
params=parsed_url.params,
|
||||
query=urlencode(filtered, doseq=True),
|
||||
fragment=parsed_url.fragment)
|
||||
|
||||
|
||||
url = urlunparse(new_url)
|
||||
|
||||
url = url.rstrip('/')
|
||||
|
@ -660,7 +660,7 @@ def submit_post(v:User, sub=None):
|
|||
if not url and not body and not request.files.get("file") and not request.files.get("file-url"):
|
||||
return error("Please enter a url or some text.")
|
||||
|
||||
if not IS_LOCALHOST:
|
||||
if not IS_LOCALHOST:
|
||||
dup = g.db.query(Submission).filter(
|
||||
Submission.author_id == v.id,
|
||||
Submission.deleted_utc == 0,
|
||||
|
@ -738,7 +738,7 @@ def submit_post(v:User, sub=None):
|
|||
submission_id=post.id
|
||||
)
|
||||
g.db.add(vote)
|
||||
|
||||
|
||||
if request.files.get('file-url') and not g.is_tor:
|
||||
file = request.files['file-url']
|
||||
|
||||
|
@ -761,7 +761,7 @@ def submit_post(v:User, sub=None):
|
|||
post.url = process_audio(file, v)
|
||||
else:
|
||||
abort(415)
|
||||
|
||||
|
||||
if not post.thumburl and post.url:
|
||||
gevent.spawn(thumbnail_thread, post.id, v.id)
|
||||
|
||||
|
@ -889,7 +889,7 @@ def mark_post_nsfw(pid, v):
|
|||
|
||||
if post.author_id != v.id and not v.admin_level >= PERMS['POST_COMMENT_MODERATION'] and not (post.sub and v.mods(post.sub)):
|
||||
abort(403)
|
||||
|
||||
|
||||
if post.over_18 and v.is_suspended_permanently:
|
||||
abort(403)
|
||||
|
||||
|
@ -923,7 +923,7 @@ def unmark_post_nsfw(pid, v):
|
|||
|
||||
if post.author_id != v.id and not v.admin_level >= PERMS['POST_COMMENT_MODERATION'] and not (post.sub and v.mods(post.sub)):
|
||||
abort(403)
|
||||
|
||||
|
||||
if post.over_18 and v.is_suspended_permanently:
|
||||
abort(403)
|
||||
|
||||
|
@ -1056,7 +1056,7 @@ def get_post_title(v):
|
|||
try:
|
||||
x = gevent.with_timeout(POST_TITLE_TIMEOUT, requests.get, url, headers=titleheaders, timeout=POST_TITLE_TIMEOUT, proxies=proxies)
|
||||
except: abort(400)
|
||||
|
||||
|
||||
content_type = x.headers.get("Content-Type")
|
||||
if not content_type or "text/html" not in content_type: abort(400)
|
||||
|
||||
|
|
|
@ -19,5 +19,5 @@ def push_subscribe(v):
|
|||
subscription_json=subscription_json,
|
||||
)
|
||||
g.db.add(subscription)
|
||||
|
||||
|
||||
return ''
|
||||
|
|
|
@ -58,7 +58,7 @@ def flag_post(pid, v):
|
|||
|
||||
moved = move_post(post, v, reason)
|
||||
if moved: return {"message": moved}
|
||||
|
||||
|
||||
existing = g.db.query(Flag.post_id).filter_by(user_id=v.id, post_id=post.id).one_or_none()
|
||||
if existing: abort(409, "You already reported this post!")
|
||||
flag = Flag(post_id=post.id, user_id=v.id, reason=reason)
|
||||
|
@ -74,7 +74,7 @@ def flag_post(pid, v):
|
|||
def flag_comment(cid, v):
|
||||
|
||||
comment = get_comment(cid)
|
||||
|
||||
|
||||
existing = g.db.query(CommentFlag.comment_id).filter_by(user_id=v.id, comment_id=comment.id).one_or_none()
|
||||
if existing: abort(409, "You already reported this comment!")
|
||||
|
||||
|
@ -125,7 +125,7 @@ def remove_report_comment(v, cid, uid):
|
|||
uid = int(uid)
|
||||
except: abort(404)
|
||||
report = g.db.query(CommentFlag).filter_by(comment_id=cid, user_id=uid).one_or_none()
|
||||
|
||||
|
||||
if report:
|
||||
g.db.delete(report)
|
||||
|
||||
|
@ -143,7 +143,7 @@ def move_post(post:Submission, v:User, reason:str) -> Union[bool, str]:
|
|||
sub_from = post.sub
|
||||
sub_to = get_sub_by_name(reason, graceful=True)
|
||||
sub_to = sub_to.name if sub_to else None
|
||||
|
||||
|
||||
can_move_post = v.admin_level >= PERMS['POST_COMMENT_MODERATION'] or (post.sub and v.mods(sub_from))
|
||||
if sub_from != 'chudrama': # posts can only be moved out of /h/chudrama by admins
|
||||
can_move_post = can_move_post or post.author_id == v.id
|
||||
|
@ -158,7 +158,7 @@ def move_post(post:Submission, v:User, reason:str) -> Union[bool, str]:
|
|||
abort(403, f"You need to be a member of House {sub_to.capitalize()} to post in /h/{sub_to}")
|
||||
else:
|
||||
abort(403, f"@{post.author.username} needs to be a member of House {sub_to.capitalize()} for their post to be moved to /h/{sub_to}")
|
||||
|
||||
|
||||
post.sub = sub_to
|
||||
post.hole_pinned = None
|
||||
g.db.add(post)
|
||||
|
|
|
@ -41,7 +41,7 @@ def get_alt_graph_ids(uid:int) -> List[int]:
|
|||
).select_from(Alt, alt_graph_cte).filter(
|
||||
or_(alt_graph_cte.c.user_id == Alt.user1, alt_graph_cte.c.user_id == Alt.user2)
|
||||
)
|
||||
|
||||
|
||||
alt_graph_cte = alt_graph_cte.union(alt_graph_cte_inner)
|
||||
return set([x[0] for x in g.db.query(User.id).filter(User.id == alt_graph_cte.c.user_id, User.id != uid).all()])
|
||||
|
||||
|
@ -86,7 +86,7 @@ def check_for_alts(current:User, include_current_session=True):
|
|||
if a.user1 != current_id: add_alt(a.user1, current_id)
|
||||
if a.user2 != past_id: add_alt(a.user2, past_id)
|
||||
if a.user2 != current_id: add_alt(a.user2, current_id)
|
||||
|
||||
|
||||
past_accs.add(current_id)
|
||||
if include_current_session:
|
||||
session["history"] = list(past_accs)
|
||||
|
@ -110,7 +110,7 @@ def execute_shadowban_viewers_and_voters(v:Optional[User], target:Union[Submissi
|
|||
max_upvotes = min(ti, 13)
|
||||
rand = randint(0, max_upvotes)
|
||||
if target.upvotes >= rand: return
|
||||
|
||||
|
||||
amount = randint(0, 3)
|
||||
if amount != 1: return
|
||||
|
||||
|
|
|
@ -59,13 +59,13 @@ def searchposts(v:User):
|
|||
posts = g.db.query(Submission.id) \
|
||||
.join(Submission.author) \
|
||||
.filter(Submission.author_id.notin_(v.userblocks))
|
||||
|
||||
|
||||
if v.admin_level < PERMS['POST_COMMENT_MODERATION']:
|
||||
posts = posts.filter(
|
||||
Submission.deleted_utc == 0,
|
||||
Submission.is_banned == False,
|
||||
Submission.private == False)
|
||||
|
||||
|
||||
if 'author' in criteria:
|
||||
posts = posts.filter(Submission.ghost == False)
|
||||
author = get_user(criteria['author'], v=v, include_shadowbanned=False)
|
||||
|
@ -95,7 +95,7 @@ def searchposts(v:User):
|
|||
words = [or_(Submission.title.ilike('%'+x+'%'), Submission.body.ilike('%'+x+'%')) \
|
||||
for x in criteria['q']]
|
||||
posts = posts.filter(*words)
|
||||
|
||||
|
||||
if 'over18' in criteria: posts = posts.filter(Submission.over_18==True)
|
||||
|
||||
if 'domain' in criteria:
|
||||
|
@ -187,7 +187,7 @@ def searchcomments(v:User):
|
|||
Comment.author_id.notin_(v.userblocks),
|
||||
)
|
||||
|
||||
|
||||
|
||||
if 'post' in criteria:
|
||||
try: post = int(criteria['post'])
|
||||
except: abort(404)
|
||||
|
@ -282,21 +282,21 @@ def searchusers(v:User):
|
|||
t = request.values.get('t', 'all').lower()
|
||||
term=query.lstrip('@')
|
||||
term = term.replace('\\','').replace('_','\_').replace('%','')
|
||||
|
||||
|
||||
users=g.db.query(User).filter(
|
||||
or_(
|
||||
User.username.ilike(f'%{term}%'),
|
||||
User.original_username.ilike(f'%{term}%')
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
if v.admin_level < PERMS['USER_SHADOWBAN']:
|
||||
users = users.filter(User.shadowbanned == None)
|
||||
|
||||
users=users.order_by(User.username.ilike(term).desc(), User.stored_subscriber_count.desc())
|
||||
|
||||
|
||||
total=users.count()
|
||||
|
||||
|
||||
users = users.offset(PAGE_SIZE * (page-1)).limit(PAGE_SIZE+1).all()
|
||||
next_exists=(len(users)>PAGE_SIZE)
|
||||
users=users[:PAGE_SIZE]
|
||||
|
|
|
@ -111,7 +111,7 @@ def settings_personal_post(v):
|
|||
updated = False
|
||||
|
||||
# begin common selectors #
|
||||
|
||||
|
||||
def update_flag(column_name:str, request_name:str):
|
||||
if not request.values.get(request_name, ''): return False
|
||||
request_flag = request.values.get(request_name, '') == 'true'
|
||||
|
@ -119,7 +119,7 @@ def settings_personal_post(v):
|
|||
setattr(v, column_name, request_flag)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def update_potentially_permanent_flag(column_name:str, request_name:str, friendly_name:str, badge_id:Optional[int]):
|
||||
if not request.values.get(request_name): return False
|
||||
current_value = getattr(v, column_name)
|
||||
|
@ -161,14 +161,14 @@ def settings_personal_post(v):
|
|||
updated = True
|
||||
v.poor = request.values.get("poor", v.poor) == 'true'
|
||||
session['poor'] = v.poor
|
||||
|
||||
|
||||
slur_filter_updated = updated or update_potentially_permanent_flag("slurreplacer", "slurreplacer", "slur replacer", 192)
|
||||
if isinstance(slur_filter_updated, bool):
|
||||
updated = slur_filter_updated
|
||||
else:
|
||||
g.db.add(v)
|
||||
return slur_filter_updated
|
||||
|
||||
|
||||
profanity_filter_updated = updated or update_potentially_permanent_flag("profanityreplacer", "profanityreplacer", "profanity replacer", 190)
|
||||
if isinstance(profanity_filter_updated, bool):
|
||||
updated = profanity_filter_updated
|
||||
|
@ -191,7 +191,7 @@ def settings_personal_post(v):
|
|||
updated = True
|
||||
v.spider = int(request.values.get("spider") == 'true')
|
||||
if v.spider: badge_grant(user=v, badge_id=179)
|
||||
else:
|
||||
else:
|
||||
badge = v.has_badge(179)
|
||||
if badge: g.db.delete(badge)
|
||||
|
||||
|
@ -317,7 +317,7 @@ def settings_personal_post(v):
|
|||
updated = True
|
||||
cache.delete_memoized(frontlist)
|
||||
else: abort(400)
|
||||
|
||||
|
||||
updated = updated or set_selector_option("defaultsortingcomments", "defaultsortingcomments", COMMENT_SORTS, "comment sort")
|
||||
updated = updated or set_selector_option("defaultsorting", "defaultsorting", SORTS, "post sort")
|
||||
updated = updated or set_selector_option("defaulttime", "defaulttime", TIME_FILTERS, "time filter")
|
||||
|
@ -337,7 +337,7 @@ def settings_personal_post(v):
|
|||
if v.house:
|
||||
if v.house.replace(' Founder', '') == house: abort(409, f"You're already in House {house}")
|
||||
cost = HOUSE_SWITCH_COST
|
||||
else:
|
||||
else:
|
||||
cost = HOUSE_JOIN_COST
|
||||
|
||||
success = v.charge_account('coins', cost)
|
||||
|
@ -345,7 +345,7 @@ def settings_personal_post(v):
|
|||
success = v.charge_account('marseybux', cost)
|
||||
if not success: abort(403)
|
||||
|
||||
if house == "None": house = ''
|
||||
if house == "None": house = ''
|
||||
v.house = house
|
||||
|
||||
updated = True
|
||||
|
@ -389,7 +389,7 @@ def set_color(v:User, attr:str, color:Optional[str]):
|
|||
@auth_required
|
||||
def namecolor(v):
|
||||
return set_color(v, "namecolor", request.values.get("namecolor"))
|
||||
|
||||
|
||||
@app.post("/settings/themecolor")
|
||||
@limiter.limit(DEFAULT_RATELIMIT_SLOWER)
|
||||
@limiter.limit(DEFAULT_RATELIMIT_SLOWER, key_func=lambda:f'{request.host}-{session.get("lo_user")}')
|
||||
|
@ -430,7 +430,7 @@ def gumroad(v):
|
|||
g.db.add(v)
|
||||
|
||||
badge_grant(badge_id=20+tier, user=v)
|
||||
|
||||
|
||||
|
||||
return {"message": f"{patron} rewards claimed!"}
|
||||
|
||||
|
@ -640,7 +640,7 @@ def settings_security(v:User):
|
|||
def settings_block_user(v):
|
||||
user = get_user(request.values.get("username"), graceful=True)
|
||||
if not user: abort(404, "This user doesn't exist.")
|
||||
|
||||
|
||||
if user.unblockable:
|
||||
if not v.shadowbanned:
|
||||
send_notification(user.id, f"@{v.username} has tried to block you and failed because of your unblockable status!")
|
||||
|
@ -778,12 +778,12 @@ def settings_song_change(v):
|
|||
|
||||
if not yt_id_regex.fullmatch(id):
|
||||
return render_template("settings/personal.html", v=v, error="Not a YouTube link"), 400
|
||||
if path.isfile(f'/songs/{id}.mp3'):
|
||||
if path.isfile(f'/songs/{id}.mp3'):
|
||||
v.song = id
|
||||
g.db.add(v)
|
||||
return render_template("settings/personal.html", v=v, msg="Profile Anthem successfully updated!")
|
||||
|
||||
|
||||
|
||||
|
||||
req = requests.get(f"https://www.googleapis.com/youtube/v3/videos?id={id}&key={YOUTUBE_KEY}&part=contentDetails", timeout=5).json()
|
||||
duration = req['items'][0]['contentDetails']['duration']
|
||||
if duration == 'P0D':
|
||||
|
@ -794,7 +794,7 @@ def settings_song_change(v):
|
|||
|
||||
if "M" in duration:
|
||||
duration = int(duration.split("PT")[1].split("M")[0])
|
||||
if duration > 15:
|
||||
if duration > 15:
|
||||
return render_template("settings/personal.html", v=v, error="Duration of the video must not exceed 15 minutes."), 400
|
||||
|
||||
|
||||
|
@ -835,7 +835,7 @@ def settings_song_change(v):
|
|||
@auth_required
|
||||
def settings_title_change(v):
|
||||
if v.flairchanged: abort(403)
|
||||
|
||||
|
||||
customtitleplain = sanitize_settings_text(request.values.get("title"), 100)
|
||||
|
||||
if len(customtitleplain) > 100:
|
||||
|
|
|
@ -142,7 +142,7 @@ def log(v:User):
|
|||
actions = []
|
||||
else:
|
||||
actions = g.db.query(ModAction)
|
||||
if not (v and v.admin_level >= PERMS['USER_SHADOWBAN']):
|
||||
if not (v and v.admin_level >= PERMS['USER_SHADOWBAN']):
|
||||
actions = actions.filter(ModAction.kind.notin_(MODACTION_PRIVILEGED_TYPES))
|
||||
|
||||
if admin_id:
|
||||
|
@ -156,7 +156,7 @@ def log(v:User):
|
|||
if kind: actions = actions.filter_by(kind=kind)
|
||||
|
||||
actions = actions.order_by(ModAction.id.desc()).offset(PAGE_SIZE*(page-1)).limit(PAGE_SIZE+1).all()
|
||||
|
||||
|
||||
next_exists=len(actions) > PAGE_SIZE
|
||||
actions=actions[:PAGE_SIZE]
|
||||
admins = [x[0] for x in g.db.query(User.username).filter(User.admin_level >= PERMS['ADMIN_MOP_VISIBLE']).order_by(User.username).all()]
|
||||
|
@ -228,7 +228,7 @@ def submit_contact(v):
|
|||
execute_blackjack(v, new_comment, new_comment.body_html, 'modmail')
|
||||
execute_under_siege(v, new_comment, new_comment.body_html, 'modmail')
|
||||
new_comment.top_comment_id = new_comment.id
|
||||
|
||||
|
||||
admins = g.db.query(User).filter(User.admin_level >= PERMS['NOTIFICATIONS_MODMAIL'], User.id != AEVANN_ID)
|
||||
|
||||
for admin in admins.all():
|
||||
|
@ -254,7 +254,7 @@ def badge_list(site):
|
|||
counts = {}
|
||||
for c in counts_raw:
|
||||
counts[c[0]] = (c[1], float(c[1]) * 100 / max(users, 1))
|
||||
|
||||
|
||||
return badges, counts
|
||||
|
||||
@app.get("/badges")
|
||||
|
|
|
@ -37,7 +37,7 @@ def exile_post(v:User, pid):
|
|||
_note=f'for <a href="{p.permalink}">{p.title_html}</a>'
|
||||
)
|
||||
g.db.add(ma)
|
||||
|
||||
|
||||
return {"message": f"@{u.username} has been exiled from /h/{sub} successfully!"}
|
||||
|
||||
@app.post("/exile/comment/<int:cid>")
|
||||
|
@ -92,11 +92,11 @@ def unexile(v:User, sub, uid):
|
|||
target_user_id=u.id
|
||||
)
|
||||
g.db.add(ma)
|
||||
|
||||
|
||||
if g.is_api_or_xhr:
|
||||
return {"message": f"@{u.username} has been unexiled from /h/{sub} successfully!"}
|
||||
|
||||
|
||||
|
||||
return redirect(f'/h/{sub}/exilees')
|
||||
|
||||
@app.post("/h/<sub>/block")
|
||||
|
@ -205,7 +205,7 @@ def sub_blockers(v:User, sub):
|
|||
.filter_by(sub=sub.name) \
|
||||
.order_by(nullslast(SubBlock.created_utc.desc()), User.username).all()
|
||||
|
||||
return render_template("sub/blockers.html",
|
||||
return render_template("sub/blockers.html",
|
||||
v=v, sub=sub, users=users, verb="blocking")
|
||||
|
||||
|
||||
|
@ -219,7 +219,7 @@ def sub_followers(v:User, sub):
|
|||
.filter_by(sub=sub.name) \
|
||||
.order_by(nullslast(SubSubscription.created_utc.desc()), User.username).all()
|
||||
|
||||
return render_template("sub/blockers.html",
|
||||
return render_template("sub/blockers.html",
|
||||
v=v, sub=sub, users=users, verb="following")
|
||||
|
||||
|
||||
|
@ -265,7 +265,7 @@ def add_mod(v:User, sub):
|
|||
@is_not_permabanned
|
||||
def remove_mod(v:User, sub):
|
||||
sub = get_sub_by_name(sub).name
|
||||
|
||||
|
||||
if not v.mods(sub): abort(403)
|
||||
if v.shadowbanned: abort(500)
|
||||
|
||||
|
@ -510,7 +510,7 @@ def delete_sub_banner(v:User, sub:str, index:int):
|
|||
@limiter.limit("1/10 second;30/day")
|
||||
@limiter.limit("1/10 second;30/day", key_func=lambda:f'{request.host}-{session.get("lo_user")}')
|
||||
@is_not_permabanned
|
||||
def delete_all_sub_banners(v:User, sub:str):
|
||||
def delete_all_sub_banners(v:User, sub:str):
|
||||
sub = get_sub_by_name(sub)
|
||||
if not v.mods(sub.name): abort(403)
|
||||
if v.shadowbanned: return redirect(f'/h/{sub}/settings')
|
||||
|
@ -542,7 +542,7 @@ def sub_sidebar(v:User, sub):
|
|||
sub = get_sub_by_name(sub)
|
||||
if not v.mods(sub.name): abort(403)
|
||||
if v.shadowbanned: return redirect(f'/h/{sub}/settings')
|
||||
|
||||
|
||||
file = request.files["sidebar"]
|
||||
name = f'/images/{time.time()}'.replace('.','') + '.webp'
|
||||
file.save(name)
|
||||
|
@ -573,7 +573,7 @@ def sub_marsey(v:User, sub):
|
|||
sub = get_sub_by_name(sub)
|
||||
if not v.mods(sub.name): abort(403)
|
||||
if v.shadowbanned: return redirect(f'/h/{sub}/settings')
|
||||
|
||||
|
||||
file = request.files["marsey"]
|
||||
name = f'/images/{time.time()}'.replace('.','') + '.webp'
|
||||
file.save(name)
|
||||
|
@ -692,12 +692,12 @@ def sub_stealth(v:User, sub):
|
|||
@feature_required('PINS')
|
||||
@is_not_permabanned
|
||||
def mod_pin(cid, v):
|
||||
|
||||
|
||||
comment = get_comment(cid, v=v)
|
||||
|
||||
|
||||
if not comment.stickied:
|
||||
if not (comment.post.sub and v.mods(comment.post.sub)): abort(403)
|
||||
|
||||
|
||||
comment.stickied = v.username + " (Mod)"
|
||||
|
||||
g.db.add(comment)
|
||||
|
@ -719,9 +719,9 @@ def mod_pin(cid, v):
|
|||
@app.post("/unmod_pin/<int:cid>")
|
||||
@is_not_permabanned
|
||||
def mod_unpin(cid, v):
|
||||
|
||||
|
||||
comment = get_comment(cid, v=v)
|
||||
|
||||
|
||||
if comment.stickied:
|
||||
if not (comment.post.sub and v.mods(comment.post.sub)): abort(403)
|
||||
|
||||
|
@ -776,7 +776,7 @@ def hole_log(v:User, sub):
|
|||
if kind: actions = actions.filter_by(kind=kind)
|
||||
|
||||
actions = actions.order_by(SubAction.id.desc()).offset(PAGE_SIZE*(page-1)).limit(PAGE_SIZE+1).all()
|
||||
|
||||
|
||||
next_exists=len(actions)>25
|
||||
actions=actions[:25]
|
||||
mods = [x[0] for x in g.db.query(Mod.user_id).filter_by(sub=sub.name).all()]
|
||||
|
|
|
@ -96,7 +96,7 @@ def upvoting_downvoting(v, username, uid, cls, vote_cls, vote_dir, template, sta
|
|||
listing = [p.id for p in listing]
|
||||
next_exists = len(listing) > PAGE_SIZE
|
||||
listing = listing[:PAGE_SIZE]
|
||||
|
||||
|
||||
if cls == Submission:
|
||||
listing = get_posts(listing, v=v, eager=True)
|
||||
elif cls == Comment:
|
||||
|
@ -238,7 +238,7 @@ def all_upvoters_downvoters(v:User, username:str, vote_dir:int, is_who_simps_hat
|
|||
users = g.db.query(User).filter(User.id.in_(votes.keys()))
|
||||
if not v.can_see_shadowbanned:
|
||||
users = users.filter(User.shadowbanned == None)
|
||||
|
||||
|
||||
users2 = [(user, votes[user.id]) for user in users.all()]
|
||||
users = sorted(users2, key=lambda x: x[1], reverse=True)
|
||||
|
||||
|
@ -255,7 +255,7 @@ def all_upvoters_downvoters(v:User, username:str, vote_dir:int, is_who_simps_hat
|
|||
|
||||
try: page = int(request.values.get("page", 1))
|
||||
except: page = 1
|
||||
|
||||
|
||||
users = users[PAGE_SIZE * (page-1):]
|
||||
next_exists = (len(users) > PAGE_SIZE)
|
||||
users = users[:PAGE_SIZE]
|
||||
|
@ -340,7 +340,7 @@ def transfer_currency(v:User, username:str, currency_name:Literal['coins', 'mars
|
|||
send_repeatable_notification(receiver.id, notif_text)
|
||||
g.db.add(v)
|
||||
return {"message": f"{amount - tax} {currency_name} have been transferred to @{receiver.username}"}
|
||||
|
||||
|
||||
@app.post("/@<username>/transfer_coins")
|
||||
@limiter.limit(DEFAULT_RATELIMIT_SLOWER)
|
||||
@limiter.limit(DEFAULT_RATELIMIT_SLOWER, key_func=lambda:f'{request.host}-{session.get("lo_user")}')
|
||||
|
@ -445,7 +445,7 @@ def subscribe(v, post_id):
|
|||
new_sub = Subscription(user_id=v.id, submission_id=post_id)
|
||||
g.db.add(new_sub)
|
||||
return {"message": "Subscribed to post successfully!"}
|
||||
|
||||
|
||||
@app.post("/unsubscribe/<int:post_id>")
|
||||
@limiter.limit(DEFAULT_RATELIMIT_SLOWER)
|
||||
@limiter.limit(DEFAULT_RATELIMIT_SLOWER, key_func=lambda:f'{request.host}-{session.get("lo_user")}')
|
||||
|
@ -629,7 +629,7 @@ def is_available(name:str):
|
|||
|
||||
if len(name)<3 or len(name)>25:
|
||||
return {name:False}
|
||||
|
||||
|
||||
name2 = name.replace('\\', '').replace('_','\_').replace('%','')
|
||||
|
||||
x = g.db.query(User).filter(
|
||||
|
@ -648,7 +648,7 @@ def is_available(name:str):
|
|||
def user_id(id):
|
||||
user = get_account(id)
|
||||
return redirect(user.url)
|
||||
|
||||
|
||||
@app.get("/u/<username>")
|
||||
@auth_required
|
||||
def redditor_moment_redirect(v:User, username:str):
|
||||
|
@ -785,10 +785,10 @@ def u_username_wall(v:Optional[User], username:str):
|
|||
|
||||
next_exists = (len(comments) > PAGE_SIZE)
|
||||
comments = comments[:PAGE_SIZE]
|
||||
|
||||
|
||||
if (v and v.client) or request.path.endswith(".json"):
|
||||
return {"data": [c.json(g.db) for c in comments]}
|
||||
|
||||
|
||||
return render_template("userpage/wall.html", u=u, v=v, listing=comments, page=page, next_exists=next_exists, is_following=is_following, standalone=True, render_replies=True, wall=True)
|
||||
|
||||
|
||||
|
@ -837,12 +837,12 @@ def u_username_wall_comment(v:User, username:str, cid):
|
|||
c = c.parent_comment
|
||||
context -= 1
|
||||
top_comment = c
|
||||
|
||||
|
||||
if v:
|
||||
# this is required because otherwise the vote and block
|
||||
# props won't save properly unless you put them in a list
|
||||
output = get_comments_v_properties(v, False, None, Comment.top_comment_id == c.top_comment_id)[1]
|
||||
|
||||
|
||||
if v and v.client: return top_comment.json(db=g.db)
|
||||
|
||||
return render_template("userpage/wall.html", u=u, v=v, listing=[top_comment], page=1, is_following=is_following, standalone=True, render_replies=True, wall=True, comment_info=comment_info)
|
||||
|
@ -899,7 +899,7 @@ def u_username(v:Optional[User], username:str):
|
|||
if u.unban_utc:
|
||||
if (v and v.client) or request.path.endswith(".json"):
|
||||
return {"data": [x.json(g.db) for x in listing]}
|
||||
|
||||
|
||||
return render_template("userpage/submissions.html",
|
||||
unban=u.unban_string,
|
||||
u=u,
|
||||
|
@ -913,7 +913,7 @@ def u_username(v:Optional[User], username:str):
|
|||
|
||||
if (v and v.client) or request.path.endswith(".json"):
|
||||
return {"data": [x.json(g.db) for x in listing]}
|
||||
|
||||
|
||||
return render_template("userpage/submissions.html",
|
||||
u=u,
|
||||
v=v,
|
||||
|
@ -955,7 +955,7 @@ def u_username_comments(username, v=None):
|
|||
|
||||
try: page = max(int(request.values.get("page", "1")), 1)
|
||||
except: page = 1
|
||||
|
||||
|
||||
sort=request.values.get("sort","new")
|
||||
t=request.values.get("t","all")
|
||||
|
||||
|
@ -990,7 +990,7 @@ def u_username_comments(username, v=None):
|
|||
|
||||
if (v and v.client) or request.path.endswith(".json"):
|
||||
return {"data": [c.json(g.db) for c in listing]}
|
||||
|
||||
|
||||
return render_template("userpage/comments.html", u=u, v=v, listing=listing, page=page, sort=sort, t=t,next_exists=next_exists, is_following=is_following, standalone=True)
|
||||
|
||||
|
||||
|
@ -1064,7 +1064,7 @@ def unfollow_user(username, v):
|
|||
|
||||
if follow:
|
||||
g.db.delete(follow)
|
||||
|
||||
|
||||
g.db.flush()
|
||||
target.stored_subscriber_count = g.db.query(Follow).filter_by(target_id=target.id).count()
|
||||
g.db.add(target)
|
||||
|
@ -1087,7 +1087,7 @@ def remove_follow(username, v):
|
|||
if not follow: return {"message": f"@{target.username} has been removed as a follower!"}
|
||||
|
||||
g.db.delete(follow)
|
||||
|
||||
|
||||
g.db.flush()
|
||||
v.stored_subscriber_count = g.db.query(Follow).filter_by(target_id=v.id).count()
|
||||
g.db.add(v)
|
||||
|
@ -1129,7 +1129,7 @@ def get_saves_and_subscribes(v, template, relationship_cls, page:int, standalone
|
|||
ids = ids[:PAGE_SIZE]
|
||||
|
||||
extra = None
|
||||
if not v.admin_level >= PERMS['POST_COMMENT_MODERATION']:
|
||||
if not v.admin_level >= PERMS['POST_COMMENT_MODERATION']:
|
||||
extra = lambda q:q.filter(cls.is_banned == False, cls.deleted_utc == 0)
|
||||
|
||||
if cls is Submission:
|
||||
|
@ -1138,7 +1138,7 @@ def get_saves_and_subscribes(v, template, relationship_cls, page:int, standalone
|
|||
listing = get_comments(ids, v=v, extra=extra)
|
||||
else:
|
||||
raise TypeError("Only supports Submissions and Comments. This is probably the result of a bug with *this* function")
|
||||
|
||||
|
||||
if v.client: return {"data": [x.json(g.db) for x in listing]}
|
||||
return render_template(template, u=v, v=v, listing=listing, page=page, next_exists=next_exists, standalone=standalone)
|
||||
|
||||
|
@ -1183,7 +1183,7 @@ def fp(v:User, fp):
|
|||
if existing: continue
|
||||
add_alt(user1=v.id, user2=u.id)
|
||||
print(v.username + ' + ' + u.username, flush=True)
|
||||
|
||||
|
||||
check_for_alts(v)
|
||||
g.db.add(v)
|
||||
return '', 204
|
||||
|
@ -1282,13 +1282,13 @@ def settings_kofi(v:User):
|
|||
abort(400, f"You must have a verified email to verify {patron} status and claim your rewards!")
|
||||
|
||||
transactions = g.db.query(Transaction).filter_by(email=v.email, claimed=None).all()
|
||||
|
||||
|
||||
if not transactions:
|
||||
abort(400, f"{patron} rewards already claimed")
|
||||
|
||||
highest_tier = 0
|
||||
marseybux = 0
|
||||
|
||||
|
||||
for transaction in transactions:
|
||||
tier = kofi_tiers[transaction.amount]
|
||||
marseybux += marseybux_li[tier]
|
||||
|
|
|
@ -87,7 +87,7 @@ def vote_post_comment(target_id, new, v, cls, vote_cls):
|
|||
else:
|
||||
abort(400)
|
||||
existing = existing.one_or_none()
|
||||
|
||||
|
||||
if IS_FISTMAS():
|
||||
coin_mult = 2
|
||||
coin_value = coin_delta * coin_mult
|
||||
|
@ -125,7 +125,7 @@ def vote_post_comment(target_id, new, v, cls, vote_cls):
|
|||
real=real,
|
||||
coins=coin_value
|
||||
)
|
||||
elif vote_cls == CommentVote:
|
||||
elif vote_cls == CommentVote:
|
||||
vote = CommentVote(user_id=v.id,
|
||||
vote_type=new,
|
||||
comment_id=target_id,
|
||||
|
|
|
@ -18,7 +18,7 @@ def get_logged_in_user():
|
|||
token = request.headers.get("Authorization","").strip()
|
||||
if token:
|
||||
client = g.db.query(ClientAuth).filter(ClientAuth.access_token == token).one_or_none()
|
||||
if client:
|
||||
if client:
|
||||
v = client.user
|
||||
v.client = client
|
||||
else:
|
||||
|
@ -65,7 +65,7 @@ def get_logged_in_user():
|
|||
if f'@{v.username}, ' not in f.read():
|
||||
t = time.strftime("%d/%B/%Y %H:%M:%S UTC", time.gmtime(time.time()))
|
||||
log_file(f'@{v.username}, {v.truescore}, {ip}, {t}\n', 'eg.log')
|
||||
|
||||
|
||||
g.is_api_or_xhr = bool((v and v.client) or request.headers.get("xhr"))
|
||||
|
||||
return v
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
{% if not app.client_id%}
|
||||
|
||||
<button type="button" class="btn btn-primary ml-auto mr-2" data-nonce="{{g.nonce}}" data-onclick="postToastReload(this,'/admin/app/approve/{{app.id}}')">Approve</button>
|
||||
<button type="button" class="btn btn-secondary mr-0" data-nonce="{{g.nonce}}" data-onclick="postToastReload(this,'/admin/app/reject/{{app.id}}')">Reject</button>
|
||||
<button type="button" class="btn btn-secondary mr-0" data-nonce="{{g.nonce}}" data-onclick="postToastReload(this,'/admin/app/reject/{{app.id}}')">Reject</button>
|
||||
|
||||
{% else %}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
{% if not app.client_id %}
|
||||
|
||||
<button type="button" class="btn btn-primary ml-auto mr-2" data-nonce="{{g.nonce}}" data-onclick="postToastReload(this,'/admin/app/approve/{{app.id}}')">Approve</button>
|
||||
<button type="button" class="btn btn-secondary mr-0" data-nonce="{{g.nonce}}" data-onclick="postToastReload(this,'/admin/app/reject/{{app.id}}')">Reject</button>
|
||||
<button type="button" class="btn btn-secondary mr-0" data-nonce="{{g.nonce}}" data-onclick="postToastReload(this,'/admin/app/reject/{{app.id}}')">Reject</button>
|
||||
|
||||
{% else %}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
<div class="custom-control">
|
||||
<input autocomplete="off" class="custom-control-input" type="radio" id="{{badge.id}}" name="badge_id" value="{{badge.id}}" required>
|
||||
<label class="custom-control-label" for="{{badge.id}}"></label>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<label for="badge-{{badge.id}}">
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
{% include "comments.html" %}
|
||||
{% endwith %}
|
||||
{% if not listing %}
|
||||
<div class="row no-gutters">
|
||||
<div class="col">
|
||||
<div class="row no-gutters">
|
||||
<div class="col">
|
||||
<div class="text-center py-6">
|
||||
<h4 class="p-2">There are no comments here (yet).</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
{% include "comments.html" %}
|
||||
{% endwith %}
|
||||
{% if not listing %}
|
||||
<div class="row no-gutters">
|
||||
<div class="col">
|
||||
<div class="row no-gutters">
|
||||
<div class="col">
|
||||
<div class="text-center py-6">
|
||||
<h4 class="p-2">There are no comments here (yet).</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% extends "default.html" %}
|
||||
{% block pagetitle %}{{game.capitalize()}}{% endblock %}
|
||||
{% block pagetitle %}{{game.capitalize()}}{% endblock %}
|
||||
{% block content %}
|
||||
<link rel="stylesheet" href="{{('css/casino/game_screen.css') | asset}}">
|
||||
<script defer src="{{'js/casino/game_screen.js' | asset}}"></script>
|
||||
|
|
|
@ -35,8 +35,8 @@
|
|||
{% if c.is_banned %}removed by @{{c.ban_reason}} (Admin){% elif c.deleted_utc %}Deleted by author{% elif c.is_blocking %}You are blocking @{{c.author_name}}{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if render_replies %}
|
||||
|
||||
{% if render_replies %}
|
||||
<div id="replies-of-{{c.fullname}}">
|
||||
{% if level<9 or request.path.startswith('/notifications') %}
|
||||
{% for reply in replies %}
|
||||
|
@ -197,7 +197,7 @@
|
|||
{% elif c.created_utc %}
|
||||
<span id="timestamp-{{c.id}}" data-nonce="{{g.nonce}}" data-onmouseover="timestamp(this, '{{c.created_utc}}')" data-bs-toggle="tooltip" data-bs-placement="bottom" class="time-stamp"> {{c.age_string}}</span>
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if c.edited_utc %}
|
||||
<span class="time-edited" id="time-edit-{{c.id}}" data-nonce="{{g.nonce}}" data-onmouseover="timestamp(this, '{{c.edited_utc}}')"><span>·</span> <span class="font-italic">Edited {{c.edited_string}}</span></span>
|
||||
{% endif %}
|
||||
|
@ -251,26 +251,26 @@
|
|||
{% if c.parent_submission or c.wall_user_id %}
|
||||
|
||||
{% if v and v.id==c.author_id %}
|
||||
|
||||
|
||||
<div id="comment-edit-{{c.id}}" class="d-none comment-write collapsed child">
|
||||
<input type="hidden" name="formkey" value="{{v|formkey}}">
|
||||
<textarea autocomplete="off" {% if v.longpost %}minlength="280"{% endif %} maxlength="{% if v.bird %}140{% else %}10000{% endif %}" data-preview="preview-edit-{{c.id}}" data-nonce="{{g.nonce}}" data-oninput="markdown(this);charLimit('comment-edit-body-{{c.id}}','charcount-edit-{{c.id}}')" id="comment-edit-body-{{c.id}}" data-id="{{c.id}}" name="body" form="comment-edit-form-{{c.id}}" class="comment-box form-control rounded" placeholder="Add your comment..." rows="3">{{c.body}}</textarea>
|
||||
|
||||
<textarea autocomplete="off" {% if v.longpost %}minlength="280"{% endif %} maxlength="{% if v.bird %}140{% else %}10000{% endif %}" data-preview="preview-edit-{{c.id}}" data-nonce="{{g.nonce}}" data-oninput="markdown(this);charLimit('comment-edit-body-{{c.id}}','charcount-edit-{{c.id}}')" id="comment-edit-body-{{c.id}}" data-id="{{c.id}}" name="body" form="comment-edit-form-{{c.id}}" class="comment-box form-control rounded" placeholder="Add your comment..." rows="3">{{c.body}}</textarea>
|
||||
|
||||
<div class="text-small font-weight-bold mt-1" id="charcount-edit-{{c.id}}" style="right: 1rem; bottom: 0.5rem; z-index: 3;"></div>
|
||||
|
||||
<div class="comment-format">
|
||||
<div class="comment-format">
|
||||
<small class="btn btn-secondary format m-0" data-nonce="{{g.nonce}}" data-onclick="getGifs('comment-edit-body-{{c.id}}')" data-bs-toggle="modal" data-bs-target="#gifModal" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Add GIF"><span class="font-weight-bolder text-uppercase">GIF</span></small>
|
||||
|
||||
<small class="btn btn-secondary format m-0" data-nonce="{{g.nonce}}" data-onclick="loadEmojis('comment-edit-body-{{c.id}}')" data-bs-toggle="modal" data-bs-target="#emojiModal" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Add Emoji"><i class="fas fa-smile-beam"></i></small>
|
||||
|
||||
|
||||
|
||||
<label class="btn btn-secondary format m-0" for="file-edit-reply-{{c.id}}">
|
||||
<div id="filename-edit-reply-{{c.id}}"><i class="fas fa-file"></i></div>
|
||||
<input autocomplete="off" id="file-edit-reply-{{c.id}}" accept="image/*, video/*, audio/*" type="file" multiple="multiple" name="file" {% if g.is_tor %}disabled{% endif %} data-nonce="{{g.nonce}}" data-onchange="changename('filename-edit-reply-{{c.id}}','file-edit-reply-{{c.id}}')" hidden>
|
||||
</label>
|
||||
</div>
|
||||
<button type="button" id="edit-btn-{{c.id}}" form="comment-edit-form-{{c.id}}" class="btn btn-primary ml-2 fl-r commentmob" data-nonce="{{g.nonce}}" data-onclick="comment_edit('{{c.id}}');remove_dialog()">Save Edit</button>
|
||||
<button type="button" id="cancel-edit-{{c.id}}" data-nonce="{{g.nonce}}" data-onclick="toggleEdit('{{c.id}}');remove_dialog()" class="btn btn-link text-muted ml-auto fl-r commentmob">Cancel</button>
|
||||
<button type="button" id="edit-btn-{{c.id}}" form="comment-edit-form-{{c.id}}" class="btn btn-primary ml-2 fl-r commentmob" data-nonce="{{g.nonce}}" data-onclick="comment_edit('{{c.id}}');remove_dialog()">Save Edit</button>
|
||||
<button type="button" id="cancel-edit-{{c.id}}" data-nonce="{{g.nonce}}" data-onclick="toggleEdit('{{c.id}}');remove_dialog()" class="btn btn-link text-muted ml-auto fl-r commentmob">Cancel</button>
|
||||
<div id="preview-edit-{{c.id}}" class="preview mb-3 mt-5"></div>
|
||||
<div class="form-text text-small p-0 m-0"><a href="/formatting" {% if v and v.newtab %}data-target="t" target="_blank"{% endif %}>Formatting help</a></div>
|
||||
</div>
|
||||
|
@ -290,45 +290,45 @@
|
|||
{% if v and not c.deleted_utc %}
|
||||
<button type="button" class="list-inline-item mr-3 btn nobackground" data-nonce="{{g.nonce}}" data-onclick="toggleReplyBox('reply-to-{{c.fullname}}')"><i class="fas fa-reply" style="margin-top:0.35rem"></i></button>
|
||||
{% endif %}
|
||||
|
||||
|
||||
<li class="list-inline-item">
|
||||
<button type="button" data-bs-toggle="modal" data-bs-target="#actionsModal-{{c.id}}">
|
||||
<i class="fas fa-ellipsis-h"></i>
|
||||
</button>
|
||||
</li>
|
||||
|
||||
|
||||
{% if v and (request.path.startswith('/@') and not wall) and v.admin_level < PERMS['VIEW_VOTE_BUTTONS_ON_USER_PAGE'] %}
|
||||
<li id="voting-{{c.id}}-mobile" class="voting list-inline-item d-md-none">
|
||||
{% if voted==1 %}
|
||||
<span class="mr-2 arrow-up comment-{{c.id}}-up active"></span>
|
||||
{% endif %}
|
||||
|
||||
|
||||
<span class="comment-mobile-score-{{c.id}} score comment-score-{{c.id}} {% if voted==1 %}score-up{% elif voted==-1%}score-down{% endif %}{% if c.controversial %} controversial{% endif %}"{% if not c.is_banned %} data-bs-toggle="tooltip" data-bs-placement="top" title="+{{ups}} | -{{downs}}"{% endif %}style="cursor: default">{{score}}</span>
|
||||
|
||||
|
||||
{% if voted==-1 %}
|
||||
<span class="ml-2 my-0 arrow-down comment-{{c.id}}-down active"></span>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% elif v %}
|
||||
<li id="voting-{{c.id}}-mobile" class="voting list-inline-item d-md-none">
|
||||
|
||||
|
||||
<span tabindex="0" role="button" data-nonce="{{g.nonce}}" data-onclick="vote('comment-mobile', '{{c.id}}', '1')" class="comment-mobile-{{c.id}}-up mx-0 pr-1 arrow-up upvote-button comment-{{c.id}}-up {% if voted==1 %}active{% endif %}">
|
||||
</span>
|
||||
|
||||
|
||||
<span class="comment-mobile-score-{{c.id}} score comment-score-{{c.id}} {% if voted==1 %}score-up{% elif voted==-1%}score-down{% endif %}{% if c.controversial %} controversial{% endif %}"{% if not c.is_banned %} data-bs-toggle="tooltip" data-bs-placement="top" title="+{{ups}} | -{{downs}}"{% endif %}style="cursor: default">{{score}}</span>
|
||||
|
||||
|
||||
<span {% if DISABLE_DOWNVOTES %}style="display:None!important"{% endif %} tabindex="0" role="button" data-nonce="{{g.nonce}}" data-onclick="vote('comment-mobile', '{{c.id}}', '-1')" class="comment-mobile-{{c.id}}-down mx-0 pl-1 my-0 arrow-down downvote-button comment-{{c.id}}-down {% if voted==-1 %}active{% endif %}">
|
||||
</span>
|
||||
|
||||
|
||||
</li>
|
||||
{% else %}
|
||||
<li id="voting-{{c.id}}-mobile" class="voting list-inline-item d-md-none">
|
||||
<span tabindex="0" class="arrow-{{c.id}}-mobile-up mx-0 pr-1 arrow-mobile-up" data-href="/login?redirect={{request.full_path | urlencode}}">
|
||||
<i class="fas fa-arrow-alt-up mx-0"></i>
|
||||
</span>
|
||||
|
||||
|
||||
<span class="comment-mobile-score-{{c.id}} score{% if c.controversial %} controversial{% endif %}"{% if not c.is_banned %} data-bs-toggle="tooltip" data-bs-placement="top" title="+{{ups}} | -{{downs}}"{% endif %}style="cursor: default">{{score}}</span>
|
||||
|
||||
|
||||
<span tabindex="0" class="arrow-{{c.id}}-mobile-down arrow-mobile-down mx-0 pl-1 my-0" data-href="/login?redirect={{request.full_path | urlencode}}">
|
||||
<i class="fas fa-arrow-alt-down mx-0"></i>
|
||||
</span>
|
||||
|
@ -344,35 +344,35 @@
|
|||
<button type="button" class="btn caction py-0 m-0 px-3 nobackground arrow-up mx-0 comment-{{c.id}}-up active"></button>
|
||||
{% endif %}
|
||||
{% elif v %}
|
||||
|
||||
|
||||
<button type="button" tabindex="0" data-nonce="{{g.nonce}}" data-onclick="vote('comment', '{{c.id}}', '1')" class="comment-{{c.id}}-up btn caction py-0 m-0 px-3 nobackground arrow-up upvote-button mx-0 comment-{{c.id}}-up {% if voted==1 %}active{% endif %}"></button>
|
||||
|
||||
|
||||
{% else %}
|
||||
<button type="button" tabindex="0" class="comment-{{c.id}}-up btn caction nobackground py-0 m-0 px-3 arrow-up" data-href="/login?redirect={{request.full_path | urlencode}}"></button>
|
||||
|
||||
|
||||
{% endif %}
|
||||
|
||||
|
||||
<span class="btn caction nobackground p-0 m-0" style="cursor: default">
|
||||
<span data-bs-toggle="tooltip" data-bs-placement="top" title="+{{ups}} | -{{downs}}" class="comment-score-{{c.id}} score comment-score-{{c.id}} {% if voted==1 %}score-up{% elif voted==-1%}score-down{% endif %}{% if c.controversial %} controversial{% endif %}">{{score}}</span>
|
||||
</span>
|
||||
|
||||
|
||||
{% if v and (request.path.startswith('/@') and not wall) and v.admin_level < PERMS['VIEW_VOTE_BUTTONS_ON_USER_PAGE'] %}
|
||||
{% if voted==-1 %}
|
||||
<li class=" arrow-down py-0 m-0 px-3 comment-{{c.id}}-down active"></li>
|
||||
{% endif %}
|
||||
{% elif v %}
|
||||
<button type="button" {% if DISABLE_DOWNVOTES %}style="display:None!important"{% endif %} tabindex="0" data-nonce="{{g.nonce}}" data-onclick="vote('comment', '{{c.id}}', '-1')" class="comment-{{c.id}}-down btn caction py-0 m-0 px-3 nobackground arrow-down downvote-button comment-{{c.id}}-down {% if voted==-1 %}active{% endif %}"></button>
|
||||
|
||||
|
||||
{% else %}
|
||||
|
||||
|
||||
<button type="button" {% if DISABLE_DOWNVOTES %}style="display:None!important"{% endif %} tabindex="0" class="comment-{{c.id}}-down btn caction py-0 m-0 px-3 nobackground arrow-down" data-href="/login?redirect={{request.full_path | urlencode}}"></button>
|
||||
|
||||
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if not c.ghost or (v and v.id == AEVANN_ID) %}
|
||||
<a href="/votes/{{c.fullname}}" class="btn caction nobackground px-1 text-muted"><i class="fas fa-arrows-v"></i>Votes</a>
|
||||
{% endif %}
|
||||
|
||||
|
||||
<a class="btn caction nobackground px-1 text-muted" href="{{c.permalink}}"><i class="fas fa-book-open"></i>Context</a>
|
||||
|
||||
<button type="button" class="btn caction py-0 nobackground px-1 text-muted copy-link" data-clipboard-text="{% if SITE == 'rdrama.net' %}https://{{BAN_EVASION_DOMAIN}}{{c.shortlink}}{% else %}{{c.permalink}}{% endif %}"><i class="fas fa-copy"></i>Copy link</button>
|
||||
|
@ -387,16 +387,16 @@
|
|||
{% if FEATURES['AWARDS'] -%}
|
||||
<button type="button" class="btn caction py-0 nobackground px-1 text-muted" data-bs-toggle="modal" data-bs-target="#awardModal" data-url="/award/comment/{{c.id}}" data-nonce="{{g.nonce}}"><i class="fas fa-gift"></i>Give Award</button>
|
||||
{%- endif %}
|
||||
|
||||
|
||||
<button type="button" id="unsave-{{c.id}}" class="btn caction py-0 nobackground px-1 {% if c.id in v.saved_comment_idlist %}d-md-inline-block{% endif %} text-muted d-none" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/unsave_comment/{{c.id}}','save-{{c.id}}','unsave-{{c.id}}','d-md-inline-block')"><i class="fas fa-save"></i>Unsave</button>
|
||||
|
||||
|
||||
<button type="button" id="save-{{c.id}}" class="btn caction py-0 nobackground px-1 {% if c.id not in v.saved_comment_idlist %}d-md-inline-block{% endif %} text-muted d-none" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/save_comment/{{c.id}}','save-{{c.id}}','unsave-{{c.id}}','d-md-inline-block')"><i class="fas fa-save"></i>Save</button>
|
||||
{% endif %}
|
||||
|
||||
{% if c.parent_submission or c.wall_user_id %}
|
||||
{% if v and c.author_id == v.id %}
|
||||
<button type="button" class="btn caction py-0 nobackground px-1 text-muted" data-nonce="{{g.nonce}}" data-onclick="toggleEdit('{{c.id}}')"><i class="fas fa-edit fa-fw"></i>Edit</button>
|
||||
|
||||
|
||||
<button type="button" id="undelete-{{c.id}}" class="btn caction py-0 nobackground px-1 text-muted {% if not c.deleted_utc %}d-none{% endif %}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/undelete/comment/{{c.id}}','delete-{{c.id}}','undelete-{{c.id}}','d-none')" data-toggleelement="comment-{{c.id}}-only" data-toggleattr="deleted"><i class="fas fa-trash-alt fa-fw"></i>Undelete</button>
|
||||
|
||||
<button type="button" id="delete-{{c.id}}" class="btn caction py-0 nobackground px-1 text-muted {% if c.deleted_utc %}d-none{% endif %}" data-bs-toggle="modal" data-bs-target="#deleteCommentModal" data-nonce="{{g.nonce}}" data-onclick="delete_commentModal(this, '{{c.id}}')"><i class="fas fa-trash-alt fa-fw"></i>Delete</button>
|
||||
|
@ -437,7 +437,7 @@
|
|||
|
||||
{% if url != "" %}
|
||||
<button type="button" id="unpin-{{c.id}}" class="dropdown-item list-inline-item {% if c.stickied %}d-md-block{% endif %} text-muted d-none text-info" data-bs-dismiss="modal" data-bs-target="#actionsModal-{{c.id}}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/un{{url}}/{{c.id}}','pin-{{c.id}}','unpin-{{c.id}}','d-md-block')"><i class="fas fa-thumbtack fa-rotate--45 text-info fa-fw"></i>Unpin</button>
|
||||
|
||||
|
||||
<button type="button" id="pin-{{c.id}}" class="dropdown-item list-inline-item {% if not c.stickied %}d-md-block{% endif %} text-muted d-none text-info" data-bs-dismiss="modal" data-bs-target="#actionsModal-{{c.id}}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/{{url}}/{{c.id}}','pin-{{c.id}}','unpin-{{c.id}}','d-md-block')"><i class="fas fa-thumbtack fa-rotate--45 text-info fa-fw"></i>Pin</button>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
@ -480,7 +480,7 @@
|
|||
</div>
|
||||
|
||||
{% if v and v.id != c.author_id and c.body %}
|
||||
<div autocomplete="off" class="markdown d-none card border my-2 p-3 comment-box form-control rounded" id="markdown-{{c.id}}" readonly>{{c.body.strip()}}</div>
|
||||
<div autocomplete="off" class="markdown d-none card border my-2 p-3 comment-box form-control rounded" id="markdown-{{c.id}}" readonly>{{c.body.strip()}}</div>
|
||||
{% endif %}
|
||||
{{macros.comment_reply_box(c.fullname, "reply-to-" + c.fullname, "d-none", "collapsed child", 'reply-to-' + c.fullname, true)}}
|
||||
|
||||
|
@ -489,7 +489,7 @@
|
|||
<button type="button" class="copy-link ml-3" data-clipboard-text="{{c.log_link}}"><i class="far fa-copy text-muted"></i></button>
|
||||
{% endif %}
|
||||
|
||||
{% if render_replies %}
|
||||
{% if render_replies %}
|
||||
<div id="replies-of-{{c.fullname}}">
|
||||
{% if request.path.startswith('/notifications/') and replies|length > 8 %}
|
||||
{% for reply in replies %}
|
||||
|
@ -506,7 +506,7 @@
|
|||
</div>
|
||||
|
||||
{% if request.path.startswith('/notifications') and c.level == 1 and c.sentto and not c.parent_submission and c.author_id != AUTOJANNY_ID %}
|
||||
{% if (v and v.admin_level >= PERMS['USER_BAN']) and (c.sentto == MODMAIL_ID) %}
|
||||
{% if (v and v.admin_level >= PERMS['USER_BAN']) and (c.sentto == MODMAIL_ID) %}
|
||||
<button type="button" class="btn btn-danger mr-3 {% if c.author.is_muted %}d-none{% endif %}" id="mute-user-{{c.id}}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/mute_user/{{c.author.id}}','mute-user-{{c.id}}','unmute-user-{{c.id}}','d-none')">Mute</button>
|
||||
<button type="button" class="btn btn-primary mr-3 {% if not c.author.is_muted %}d-none{% endif %}" id="unmute-user-{{c.id}}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/unmute_user/{{c.author.id}}','mute-user-{{c.id}}','unmute-user-{{c.id}}','d-none')">Unmute</button>
|
||||
{% endif %}
|
||||
|
@ -517,9 +517,9 @@
|
|||
<div id="reply-message-{{c.fullname}}" class="d-none">
|
||||
<div id="comment-form-space-{{c.id}}" class="comment-write collapsed child">
|
||||
<div class="input-group">
|
||||
<input type="hidden" name="formkey" value="{{v|formkey}}">
|
||||
<textarea required autocomplete="off" minlength="1" maxlength="10000" name="body" form="reply-to-c_{{c.id}}" data-id="{{c.id}}" class="comment-box form-control rounded" id="reply-form-body-{{c.id}}" rows="3" data-preview="message-reply-{{c.id}}" data-nonce="{{g.nonce}}" data-oninput="markdown(this)"></textarea>
|
||||
<div class="comment-format" id="comment-format-bar-{{c.id}}">
|
||||
<input type="hidden" name="formkey" value="{{v|formkey}}">
|
||||
<textarea required autocomplete="off" minlength="1" maxlength="10000" name="body" form="reply-to-c_{{c.id}}" data-id="{{c.id}}" class="comment-box form-control rounded" id="reply-form-body-{{c.id}}" rows="3" data-preview="message-reply-{{c.id}}" data-nonce="{{g.nonce}}" data-oninput="markdown(this)"></textarea>
|
||||
<div class="comment-format" id="comment-format-bar-{{c.id}}">
|
||||
<button role="button" data-nonce="{{g.nonce}}" data-onclick="loadEmojis('reply-form-body-{{c.id}}')" class="btn btn-secondary m-0 mt-3 mr-1" data-bs-toggle="modal" data-bs-target="#emojiModal" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Add Emoji"><i class="fas fa-smile-beam"></i></button>
|
||||
|
||||
{% if c.sentto == MODMAIL_ID %}
|
||||
|
@ -530,7 +530,7 @@
|
|||
{% endif %}
|
||||
</div>
|
||||
|
||||
<button type="button" data-nonce="{{g.nonce}}" data-onclick="remove_dialog()" class="btn btn-link text-muted ml-auto" data-toggleelement="reply-message-{{c.fullname}}" data-toggleattr="d-none">Cancel</button>
|
||||
<button type="button" data-nonce="{{g.nonce}}" data-onclick="remove_dialog()" class="btn btn-link text-muted ml-auto" data-toggleelement="reply-message-{{c.fullname}}" data-toggleattr="d-none">Cancel</button>
|
||||
<button type="button" id="save-reply-to-{{c.id}}" class="btn btn-primary ml-2" data-nonce="{{g.nonce}}" data-onclick="post_reply('{{c.id}}');remove_dialog()">Reply</button>
|
||||
</div>
|
||||
<div id="message-reply-{{c.id}}" class="preview mt-2"></div>
|
||||
|
@ -576,7 +576,7 @@
|
|||
|
||||
{% if c.author_id == v.id %}
|
||||
<button type="button" data-bs-dismiss="modal" data-nonce="{{g.nonce}}" data-onclick="toggleEdit('{{c.id}}')" class="list-group-item"><i class="fas fa-edit mr-2"></i>Edit</button>
|
||||
|
||||
|
||||
<button type="button" id="undelete2-{{c.id}}" class="{% if not c.deleted_utc %}d-none{% endif %} list-group-item text-success" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/undelete/comment/{{c.id}}', 'delete2-{{c.id}}', 'undelete2-{{c.id}}','d-none')" data-toggleelement="comment-{{c.id}}-only" data-toggleattr="deleted" data-bs-dismiss="modal"><i class="far fa-trash-alt text-success mr-2"></i>Undelete</button>
|
||||
|
||||
<button type="button" id="delete2-{{c.id}}" class="{% if c.deleted_utc %}d-none{% endif %} list-group-item text-danger" data-bs-toggle="modal" data-bs-dismiss="modal" data-bs-target="#deleteCommentModal" data-nonce="{{g.nonce}}" data-onclick="delete_commentModal(this, '{{c.id}}')"><i class="far fa-trash-alt text-danger mr-2"></i>Delete</button>
|
||||
|
@ -711,7 +711,7 @@
|
|||
<p class="d-mob-none">Your comment will be deleted everywhere on {{SITE_NAME}}.</p>
|
||||
|
||||
<p class="text-muted d-md-none">Your comment will be deleted everywhere on {{SITE_NAME}}.</p>
|
||||
|
||||
|
||||
<button type="button" id="deleteCommentButton" class="btn btn-danger btn-block mt-5" data-bs-dismiss="modal">Delete comment</button>
|
||||
|
||||
<button type="button" class="btn btn-secondary btn-block" data-bs-dismiss="modal">Cancel</button>
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
opacity: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
||||
body,
|
||||
td,
|
||||
th {
|
||||
|
@ -80,7 +80,7 @@
|
|||
p.sub {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
|
||||
.align-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
@ -90,7 +90,7 @@
|
|||
.align-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
.button {
|
||||
background-color: #FF66AC;
|
||||
border-top: 10px solid #FF66AC;
|
||||
|
@ -124,7 +124,7 @@
|
|||
text-align: center !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.attributes {
|
||||
margin: 0 0 21px;
|
||||
}
|
||||
|
@ -136,7 +136,7 @@
|
|||
.attributes_item {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
||||
.related {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
|
@ -164,7 +164,7 @@
|
|||
text-align: center;
|
||||
padding: 25px 0 10px;
|
||||
}
|
||||
|
||||
|
||||
.discount {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
|
@ -182,7 +182,7 @@
|
|||
text-align: center;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
|
||||
.social {
|
||||
width: auto;
|
||||
}
|
||||
|
@ -195,7 +195,7 @@
|
|||
margin: 0 8px 10px 8px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
||||
.purchase {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
|
@ -267,7 +267,7 @@
|
|||
-premailer-cellpadding: 0;
|
||||
-premailer-cellspacing: 0;
|
||||
}
|
||||
|
||||
|
||||
.email-masthead {
|
||||
display: none;
|
||||
}
|
||||
|
@ -280,7 +280,7 @@
|
|||
color: #121213;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
|
||||
.email-body {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
|
@ -328,7 +328,7 @@
|
|||
.content-cell {
|
||||
padding: 35px;
|
||||
}
|
||||
|
||||
|
||||
@media only screen and (max-width: 600px) {
|
||||
.email-body_inner,
|
||||
.email-footer {
|
||||
|
|
|
@ -135,7 +135,7 @@ Text 2
|
|||
Poll — Pick Multiple<br>
|
||||
<span style="font-style: italic; font-weight: normal;">
|
||||
* Polls always appear at end of post.
|
||||
</span>
|
||||
</span>
|
||||
</td>
|
||||
<td>$$bussy$$<br>$$gussy$$</td>
|
||||
<td>
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
<th>Owners</th>
|
||||
<th>Price</th>
|
||||
<th>Actions</th>
|
||||
<th>Added on</th>
|
||||
<th>Added on</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
|
@ -79,7 +79,7 @@
|
|||
|
||||
<div id="if-owned-{{hat.id}}" {% if hat.id not in owned_hat_ids %}class="d-none"{% endif %}>
|
||||
<button type="button" id="unequip-{{hat.id}}" class="unequip {% if hat.id not in v.equipped_hat_ids %}d-none{% endif %} btn btn-success" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this, '/unequip_hat/{{hat.id}}', 'equip-{{hat.id}}', 'unequip-{{hat.id}}', 'd-none')"><span class="m-auto">Unequip</span></button>
|
||||
|
||||
|
||||
<button type="button" id="equip-{{hat.id}}" class="equip {% if hat.id in v.equipped_hat_ids %}d-none{% endif %} btn btn-success" data-nonce="{{g.nonce}}" data-onclick="equip_hat(this, '{{hat.id}}', '{{hat.name}}')"><span class="m-auto">Equip</span></button>
|
||||
</div>
|
||||
</td>
|
||||
|
@ -89,5 +89,5 @@
|
|||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
{% endif %}
|
||||
<img id="header--icon" alt="header icon" {% if sub %}src="{{sub.marsey_url}}"{% else %}src="{{icon_url}}"{% endif %}>
|
||||
</a>
|
||||
|
||||
|
||||
{% if sub %}
|
||||
<a id="sub-name" href="/h/{{sub}}" class="font-weight-bold ml-2 flex-grow-1 mt-1" {% if sub.name|length >= 17 %}style="font-size:max(10px,1.2vw)"{% else %}style="font-size:max(14px,1.2vw)"{% endif %}>{% if not HOLE_STYLE_FLAIR %}/h/{% endif %}{{sub}}</a>
|
||||
{% elif has_logo %}
|
||||
|
@ -77,7 +77,7 @@
|
|||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if not request.path.startswith('/search/') %}
|
||||
<div class="flex-grow-1 d-fl d-mob-none {% if not v %}pad{% endif %}">
|
||||
<form class="form-inline search flex-nowrap mx-0 mx-lg-auto mb-0" {% if err %}style="margin-right:40rem!important"{% endif %} action="{% if request.path.startswith('/search') %}{{request.path}}{% else %}/search/posts/{% endif %}" method="get">
|
||||
|
@ -102,7 +102,7 @@
|
|||
<a class="mobile-nav-icon d-md-none" href="/notifications" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Notifications"><i class="fas fa-bell align-middle text-gray-500 black"></i></a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if not err %}
|
||||
{% if v and v.admin_level >= PERMS['ADMIN_HOME_VISIBLE'] %}
|
||||
<a class="mobile-nav-icon d-md-none" href="/admin"><i class="fas fa-crown align-middle text-gray-500 black"></i></a>
|
||||
|
@ -154,7 +154,7 @@
|
|||
{% if FEATURES['CHAT'] and v.admin_level >= PERMS['CHAT'] -%}
|
||||
<li class="nav-item d-none d-lg-flex align-items-center justify-content-center text-center mx-1">
|
||||
<a class="nav-link position-relative" href="/chat">
|
||||
<i class="fas fa-messages" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Chat"></i>
|
||||
<i class="fas fa-messages" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Chat"></i>
|
||||
<b class="text-lg" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Users in chat right now">
|
||||
{{loggedin_chat}}
|
||||
</b>
|
||||
|
@ -165,7 +165,7 @@
|
|||
<li class="nav-item d-flex align-items-center justify-content-center text-center mx-1">
|
||||
<a class="nav-link" href="/random_user" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Random User"><i class="fas fa-music"></i></a>
|
||||
</li>
|
||||
|
||||
|
||||
<li class="nav-item d-none d-lg-flex align-items-center justify-content-center text-center mx-1">
|
||||
<a class="nav-link" href="/comments" data-bs-toggle="tooltip" data-bs-placement="bottom" title="All Comments"><i class="fas fa-comment-dots"></i></a>
|
||||
</li>
|
||||
|
@ -287,7 +287,7 @@
|
|||
<li class="nav-item">
|
||||
<button type="button" class="nav-link copy-link" data-clipboard-text="{{SITE_FULL}}/signup?ref={{v.username}}"><i class="fas fa-user-friends fa-fw mr-3"></i>Invite friends</button>
|
||||
</li>
|
||||
|
||||
|
||||
<a class="nav-item nav-link" href="https://rdrama.net/h/changelog"><i class="fas fa-clipboard fa-fw mr-3"></i>Changelog</a>
|
||||
|
||||
<a class="nav-item nav-link" rel="nofollow noopener" href="https://fsdfsd.net/rDrama/rDrama"><i class="fab fa-git-alt fa-fw mr-3"></i>Source code</a>
|
||||
|
@ -301,7 +301,7 @@
|
|||
{% if SITE_NAME == 'rDrama' %}
|
||||
<a class="nav-item nav-link" href="/archives"><i class="fas fa-book fa-fw mr-3"></i>Archives</a>
|
||||
{% endif %}
|
||||
|
||||
|
||||
<a class="nav-item nav-link" href="/contact"><i class="fas fa-file-signature fa-fw mr-3"></i>Contact us</a>
|
||||
|
||||
<li class="nav-item border-top border-bottom mt-2 pt-2">
|
||||
|
|
|
@ -1,33 +1,33 @@
|
|||
{%-
|
||||
set JOURNOID_BANNERS = [
|
||||
(
|
||||
"Official site of /r/SubredditDrama 🍿",
|
||||
"https://reddit.com/r/subredditdrama",
|
||||
"Official site of /r/SubredditDrama 🍿",
|
||||
"https://reddit.com/r/subredditdrama",
|
||||
""
|
||||
),
|
||||
(
|
||||
"As seen on The Independent 📰✨💞",
|
||||
"https://www.independent.co.uk/news/world/americas/us-politics/reddit-conservatives-post-trans-child-fake-b2060803.html",
|
||||
"As seen on The Independent 📰✨💞",
|
||||
"https://www.independent.co.uk/news/world/americas/us-politics/reddit-conservatives-post-trans-child-fake-b2060803.html",
|
||||
"https://rdrama.net//post/61530"
|
||||
),
|
||||
(
|
||||
"As fact-checked by Reuters 📰✨💞",
|
||||
"https://www.reuters.com/article/factcheck-socialmedia-gender/fact-check-post-about-parent-forcefully-medicating-transgender-child-is-fabricated-idUSL2N2WC1OK",
|
||||
"As fact-checked by Reuters 📰✨💞",
|
||||
"https://www.reuters.com/article/factcheck-socialmedia-gender/fact-check-post-about-parent-forcefully-medicating-transgender-child-is-fabricated-idUSL2N2WC1OK",
|
||||
"https://rdrama.net//post/60443"
|
||||
),
|
||||
(
|
||||
"As analyzed by Mashable 📰✨💞",
|
||||
"https://mashable.com/article/libs-of-tiktok-furries-school-troll-fake",
|
||||
"As analyzed by Mashable 📰✨💞",
|
||||
"https://mashable.com/article/libs-of-tiktok-furries-school-troll-fake",
|
||||
"https://rdrama.net//post/63155"
|
||||
),
|
||||
(
|
||||
"As seen on Business Insider's retraction 📰✨💞",
|
||||
"https://businessinsider.com/reddit-shuts-down-forum-for-texas-abortion-bounty-hunters-2021-9",
|
||||
"As seen on Business Insider's retraction 📰✨💞",
|
||||
"https://businessinsider.com/reddit-shuts-down-forum-for-texas-abortion-bounty-hunters-2021-9",
|
||||
"https://rdrama.net//post/19236"
|
||||
),
|
||||
(
|
||||
"As discussed on The Glenn Beck Program 📻✨💞",
|
||||
"https://www.audacy.com/podcasts/the-glenn-beck-program-45436/elon-musk-vs-the-world-guests-rob-collins-riaz-patel-42722-1386209895",
|
||||
"As discussed on The Glenn Beck Program 📻✨💞",
|
||||
"https://www.audacy.com/podcasts/the-glenn-beck-program-45436/elon-musk-vs-the-world-guests-rob-collins-riaz-patel-42722-1386209895",
|
||||
"https://rdrama.net//post/64305"
|
||||
),
|
||||
(
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
<div class="row" style="overflow: visible;padding-top:5px;">
|
||||
<div class="col">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
|
||||
|
||||
{% block navbar %}
|
||||
<div class="d-flex align-items-center mb-3 ml-auto">
|
||||
<div class="dropdown dropdown-actions">
|
||||
|
@ -44,7 +44,7 @@
|
|||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="dropdown dropdown-actions ml-3">
|
||||
<button type="button" class="btn btn-secondary dropdown-toggle" id="dropdownMenuButton2" data-bs-toggle="dropdown">
|
||||
{% if type %}<i class="fas {{types[type]['icon']}} mr-2"></i>{{type}}{% else %}<i class="fas fa-broom mr-2"></i>All{% endif %}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
Already have an account? <a href="/login{{'?redirect='+redirect if redirect else ''}}" class="font-weight-bold toggle-login">Log in</a>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block scripts %}
|
||||
{% block scripts %}
|
||||
<div class="toast clipboard" id="toast-success" role="alert" data-bs-animation="true" data-bs-autohide="true" data-bs-delay="5000">
|
||||
<div class="toast-body text-center">
|
||||
<i class="fas fa-check-circle text-success mr-2"></i>Link copied to clipboard
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{% extends "default.html" %}
|
||||
{% block pagetitle %}Directory{% endblock %}
|
||||
{% block pagetype %}directory{% endblock %}
|
||||
{# Title (~25char max), Description (~80char max),
|
||||
{# Title (~25char max), Description (~80char max),
|
||||
Icon (fa-foo-bar), Color (#ff0000), URL (/post/12345/) #}
|
||||
{%- set MEGATHREAD_INDEX = [] -%}
|
||||
|
||||
|
|
|
@ -41,5 +41,5 @@
|
|||
<div class="toast-body bg-danger text-center text-white">
|
||||
<i class="fas fa-exclamation-circle mr-2"></i><span id="toast-post-error-text2">Error, please try again later.</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<p class="d-mob-none">Your post will be deleted everywhere on {{SITE_NAME}}.</p>
|
||||
|
||||
<p class="text-muted d-md-none">Your post will be deleted everywhere on {{SITE_NAME}}.</p>
|
||||
|
||||
|
||||
<button type="button" id="deletePostButton" class="btn btn-danger btn-block mt-5" data-bs-dismiss="modal">Delete post</button>
|
||||
|
||||
<button type="button" class="btn btn-secondary btn-block" data-bs-dismiss="modal">Cancel</button>
|
||||
|
|
|
@ -81,7 +81,7 @@
|
|||
<div>
|
||||
{% if ma.sub %}
|
||||
<a href="/h/{{ma.sub}}">/h/{{ma.sub}}</a>
|
||||
-
|
||||
-
|
||||
{% endif %}
|
||||
<a href="{{ma.user.url}}" class="font-weight-bold text-black" target="_self">@{{ma.user.username}}</a>
|
||||
<span>{{ma.string | safe}}</span>
|
||||
|
@ -106,7 +106,7 @@
|
|||
<i class="fas fa-check-circle text-success mr-2"></i>Link copied to clipboard
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script defer src="{{'js/vendor/clipboard.js' | asset}}"></script>
|
||||
{% else %}
|
||||
{% with comments=notifications %}
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
<button type="button" id="save-{{p.id}}" class="{% if p.id in v.saved_idlist %}d-none{% endif %} list-inline-item" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/save_post/{{p.id}}','save-{{p.id}}','unsave-{{p.id}}','d-none')"><i class="fas fa-save"></i>Save</button>
|
||||
<button type="button" id="unsave-{{p.id}}" class="{% if not p.id in v.saved_idlist %}d-none{% endif %} list-inline-item" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/unsave_post/{{p.id}}','save-{{p.id}}','unsave-{{p.id}}','d-none')"><i class="fas fa-save"></i>Unsave</button>
|
||||
|
||||
|
||||
<button type="button" class="list-inline-item" data-bs-toggle="modal" data-bs-dismiss="modal" data-bs-target="#reportPostModal" data-nonce="{{g.nonce}}" data-onclick="report_postModal('{{p.id}}')"><i class="fas fa-flag"></i>Report</button>
|
||||
{% endif %}
|
||||
|
||||
|
@ -42,7 +42,7 @@
|
|||
<ul class="dropdown-menu">
|
||||
{% if v.admin_level >= PERMS['POST_COMMENT_MODERATION'] and p.oauth_app %}
|
||||
<a class="dropdown-item list-inline-item text-info" href="{{p.oauth_app.permalink}}/posts"><i class="fas fa-code"></i>API App</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if v.can_edit(p) %}
|
||||
<button type="button" class="dropdown-item {% if p.new %} d-none{% endif %} list-inline-item text-info" id="{{p.id}}-sort-new" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this, '/post/{{p.id}}/new', '{{p.id}}-sort-new', '{{p.id}}-unsort-new', 'd-none', null, 'PUT')"><i class="fas fa-sparkles text-center text-primary mr-2"></i>Set Default Sort New</button>
|
||||
<button type="button" class="dropdown-item {% if not p.new %} d-none{% endif %} list-inline-item text-info" id="{{p.id}}-unsort-new" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this, '/post/{{p.id}}/new', '{{p.id}}-unsort-new', '{{p.id}}-sort-new', 'd-none', null, 'DELETE')"><i class="fas fa-fire text-center text-primary mr-2"></i>Set Default Sort Hot</button>
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
{% if request.path.startswith('/search/posts') %}
|
||||
<div>
|
||||
<div style="display: inline-block; width: 150px; text-align: center;">Post Title Only:</div>
|
||||
<button type="button" data-nonce="{{g.nonce}}" data-onclick="addParam()" class="searchparam mb-1">title:true</button>
|
||||
<button type="button" data-nonce="{{g.nonce}}" data-onclick="addParam()" class="searchparam mb-1">title:true</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
</div>
|
||||
|
||||
{% if error %}
|
||||
<div class="row no-gutters">
|
||||
<div class="row no-gutters">
|
||||
<div class="col">
|
||||
{{macros.ghost_box(error, '', 1)}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -91,7 +91,7 @@
|
|||
<option value="{{entry}}"{{' selected' if v.defaulttime==entry}}>{{entry}}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -17,12 +17,12 @@
|
|||
<input type="hidden" name="formkey" value="{{v|formkey}}">
|
||||
<label for="edit-{{app.id}}-name" class="mb-0 w-lg-25">App Name</label>
|
||||
<input autocomplete="off" id="edit-{{app.id}}-name" class="form-control" type="text" name="name" value="{{app.app_name}}">
|
||||
|
||||
|
||||
{% if app.client_id %}
|
||||
<label for="edit-{{app.id}}-client-id" class="mb-0 w-lg-25">Client ID</label>
|
||||
<input autocomplete="off" id="edit-{{app.id}}-client-id" class="form-control copy-link" type="text" name="name" value="{{app.client_id}}" data-clipboard-text="{{app.client_id}}" readonly="readonly">
|
||||
{% endif %}
|
||||
|
||||
|
||||
<label for="edit-{{app.id}}-redirect" class="mb-0 w-lg-25">Redirect URI</label>
|
||||
<input autocomplete="off" id="edit-{{app.id}}-redirect" class="form-control" type="text" name="redirect_uri" value="{{app.redirect_uri}}">
|
||||
<label for="edit-{{app.id}}-desc" class="mb-0 w-lg-25">Description</label>
|
||||
|
|
|
@ -73,9 +73,9 @@
|
|||
|
||||
{% macro text_area_section(id, form_action, form_name, section_title, contents, below_text, placeholder_text, show_extras, show_file_upload, maxlength, show_if) %}
|
||||
{% if show_if -%}
|
||||
<div class="body d-lg-flex border-bottom">
|
||||
<div class="body d-lg-flex border-bottom">
|
||||
<label class="text-black w-lg-25">{{section_title}}</label>
|
||||
<div class="w-lg-100">
|
||||
<div class="w-lg-100">
|
||||
<form id="{{id}}-form" action="{{form_action}}" method="post" enctype="multipart/form-data">
|
||||
<input type="hidden" name="formkey" value="{{v|formkey}}">
|
||||
<textarea autocomplete="off" id="{{id}}-text" class="form-control rounded" placeholder="{{placeholder_text}}" rows="3" name="{{form_name}}" form="{{id}}-form" maxlength="{{maxlength}}">{% if contents %}{{contents}}{% endif %}</textarea>
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
<div class="body w-lg-100">
|
||||
<p>Change the background for the website.</p>
|
||||
<div class="input-group mb2">
|
||||
<select autocomplete="off" id='backgroundSelector' class="form-control" form="profile-settings" name="background" data-nonce="{{g.nonce}}" data-onchange="updatebgselection();">
|
||||
<select autocomplete="off" id='backgroundSelector' class="form-control" form="profile-settings" name="background" data-nonce="{{g.nonce}}" data-onchange="updatebgselection();">
|
||||
{% for entry in BACKGROUND_CATEGORIES %}
|
||||
<option value="{{entry}}" {% if v.background and v.background.startswith(entry) %}selected{% endif %}>
|
||||
{{entry}}
|
||||
|
@ -55,10 +55,10 @@
|
|||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<form class="d-flex mt-3 mb-2" id="upload-custom-background" action="/settings/custom_background" method="post" enctype="multipart/form-data">
|
||||
<form class="d-flex mt-3 mb-2" id="upload-custom-background" action="/settings/custom_background" method="post" enctype="multipart/form-data">
|
||||
<input type="hidden" name="formkey" value="{{v|formkey}}">
|
||||
<label class="btn btn-primary" for="upload-custom-background-file">
|
||||
<i class="fas fa-image mr-1"></i>
|
||||
<i class="fas fa-image mr-1"></i>
|
||||
{% if v.background and v.background.startswith('/images/') %}
|
||||
{{v.background}}
|
||||
{% else %}
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
{% if FEATURES['MARSEYBUX'] %}
|
||||
<span class="text-small text-muted pl-1">Must be same email as the one you used to donate
|
||||
{% if v.truescore >= TRUESCORE_DONATE_MINIMUM %}
|
||||
on
|
||||
on
|
||||
{% if KOFI_TOKEN %}
|
||||
<a rel="nofollow noopener" class="text-primary" href="{{KOFI_LINK}}">Kofi</a>
|
||||
{% else %}
|
||||
|
@ -61,14 +61,14 @@
|
|||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</form>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
<section id="site-settings-password-section" class="settings-section-section">
|
||||
<h5>Password</h5>
|
||||
<div class="settings-section rounded">
|
||||
<form action="/settings/security" method="post">
|
||||
<div class="body">
|
||||
<div class="body">
|
||||
<div class="d-lg-flex">
|
||||
<label for="old_password" class="mb-0 w-lg-25">Old Password</label>
|
||||
<input autocomplete="off" class="form-control mb-2 w-lg-100" id="old_password" type="password" name="old_password" required>
|
||||
|
|
|
@ -78,5 +78,5 @@
|
|||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<button type="submit" class="btn btn-primary ml-auto" id="create_button" {% if cost > v.coins %}disabled{% endif %}>Create {{HOLE_NAME|capitalize}}</button>
|
||||
</div>
|
||||
<p class="mt-2 mr-1" style="float: right"><b>Cost</b>: {{cost}} coins</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -130,7 +130,7 @@
|
|||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
|
||||
<div id="post-text" class="{% if p.author.agendaposter and p.sub != 'chudrama' %}agendaposter{% endif %} {% if p.author.rainbow %}rainbow-text{% endif %}">
|
||||
{% if p.is_image %}
|
||||
<div class="row no-gutters mb-4">
|
||||
|
@ -175,23 +175,23 @@
|
|||
<input type="hidden" name="formkey" value="{{v|formkey}}">
|
||||
<input type="hidden" name="current_page" value="{{request.path}}">
|
||||
<textarea id="post-edit-title" autocomplete="off" max-length="500" name="title" class="comment-box form-control rounded" required placeholder="title">{{p.title}}</textarea>
|
||||
<textarea autocomplete="off" name="body" {% if v.longpost %}minlength="280"{% endif %} maxlength="{% if v.bird %}140{% else %}20000{% endif %}" data-preview="post-edit-{{p.id}}" data-nonce="{{g.nonce}}" data-oninput="markdown(this);charLimit('post-edit-box-{{p.id}}','charcount-post-edit')" id="post-edit-box-{{p.id}}" form="post-edit-form-{{p.id}}" class="comment-box form-control rounded" placeholder="Add text to your post..." rows="10" data-id="{{p.id}}">{{p.body}}</textarea>
|
||||
|
||||
<textarea autocomplete="off" name="body" {% if v.longpost %}minlength="280"{% endif %} maxlength="{% if v.bird %}140{% else %}20000{% endif %}" data-preview="post-edit-{{p.id}}" data-nonce="{{g.nonce}}" data-oninput="markdown(this);charLimit('post-edit-box-{{p.id}}','charcount-post-edit')" id="post-edit-box-{{p.id}}" form="post-edit-form-{{p.id}}" class="comment-box form-control rounded" placeholder="Add text to your post..." rows="10" data-id="{{p.id}}">{{p.body}}</textarea>
|
||||
|
||||
<div class="text-small font-weight-bold mt-1" id="charcount-post-edit" style="right: 1rem; bottom: 0.5rem; z-index: 3;"></div>
|
||||
|
||||
<div class="comment-format">
|
||||
<button type="button" class="format btn btn-secondary"><span class="font-weight-bolder text-uppercase" data-nonce="{{g.nonce}}" data-onclick="getGifs('post-edit-box-{{p.id}}')" data-bs-toggle="modal" data-bs-target="#gifModal" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Add GIF">GIF</span></button>
|
||||
<button role="button" data-nonce="{{g.nonce}}" data-onclick="loadEmojis('post-edit-box-{{p.id}}')" class="format btn btn-secondary" role="button" data-bs-toggle="modal" data-bs-target="#emojiModal" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Add Emoji"><i class="fas fa-smile-beam"></i></button>
|
||||
<button role="button" data-nonce="{{g.nonce}}" data-onclick="loadEmojis('post-edit-box-{{p.id}}')" class="format btn btn-secondary" role="button" data-bs-toggle="modal" data-bs-target="#emojiModal" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Add Emoji"><i class="fas fa-smile-beam"></i></button>
|
||||
|
||||
<label class="format btn btn-secondary m-0 {% if v %}d-inline-block{% else %}d-none{% endif %}" for="file-upload-edit-{{p.id}}">
|
||||
<div id="filename-show-edit-{{p.id}}"><i class="fas fa-file"></i></div>
|
||||
<input autocomplete="off" id="file-upload-edit-{{p.id}}" accept="image/*, video/*, audio/*" type="file" multiple="multiple" name="file" {% if g.is_tor %}disabled{% endif %} data-nonce="{{g.nonce}}" data-onchange="changename('filename-show-edit-{{p.id}}','file-upload-edit-{{p.id}}')" hidden>
|
||||
</label>
|
||||
|
||||
<small class="format d-none"><i class="fas fa-link"></i></small>
|
||||
|
||||
<small class="format d-none"><i class="fas fa-link"></i></small>
|
||||
</div>
|
||||
<button type="submit" form="post-edit-form-{{p.id}}" class="btn btn-primary ml-2 fl-r" data-nonce="{{g.nonce}}" data-onclick="disable(this);remove_dialog()">Save Edit</button>
|
||||
<button type="button" data-nonce="{{g.nonce}}" data-onclick="togglePostEdit('{{p.id}}');remove_dialog()" class="btn btn-link text-muted ml-auto fl-r">Cancel</button>
|
||||
<button type="button" data-nonce="{{g.nonce}}" data-onclick="togglePostEdit('{{p.id}}');remove_dialog()" class="btn btn-link text-muted ml-auto fl-r">Cancel</button>
|
||||
</form>
|
||||
<div id="post-edit-{{p.id}}" class="preview mb-3 mt-5"></div>
|
||||
<div class="form-text text-small p-0 m-0"><a href="/formatting" {% if v and v.newtab %}data-target="t" target="_blank"{% endif %}>Formatting help</a></div>
|
||||
|
@ -301,7 +301,7 @@
|
|||
</div>
|
||||
|
||||
{% if v and v.id != p.author_id and p.body and not v_forbid_deleted %}
|
||||
<div autocomplete="off" class="markdown d-none card border my-2 p-3 comment-box form-control rounded" id="markdown-{{p.id}}" readonly>{{p.body.strip()}}</div>
|
||||
<div autocomplete="off" class="markdown d-none card border my-2 p-3 comment-box form-control rounded" id="markdown-{{p.id}}" readonly>{{p.body.strip()}}</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="row border-md-0 comment-section pb-3">
|
||||
|
@ -342,7 +342,7 @@
|
|||
{% include "comments.html" %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
|
||||
|
||||
{% if offset %}
|
||||
<script defer src="{{'js/view_more.js' | asset}}"></script>
|
||||
{% endif %}
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div id="voting" class="d-md-block my-auto mr-3 text-center">
|
||||
<div class="post-{{p.id}}-up arrow-up mx-auto">
|
||||
</div>
|
||||
|
@ -44,7 +44,7 @@
|
|||
|
||||
</div>
|
||||
{% if v and v.admin_level >= PERMS['POST_COMMENT_MODERATION'] and p.body_html %}
|
||||
<div class="post-body mt-4 mb-2">
|
||||
<div class="post-body mt-4 mb-2">
|
||||
{{p.body_html | safe}}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
|
|
@ -144,7 +144,7 @@
|
|||
{% endif %}
|
||||
|
||||
</li>
|
||||
|
||||
|
||||
{% if p.realbody(v, listing=True) %}
|
||||
<button type="button" class="list-inline-item ml-2" data-nonce="{{g.nonce}}" data-onclick="expandText('{{p.id}}')"><i class="fas fa-expand-alt mx-0 text-expand-icon-{{p.id}}"></i></button>
|
||||
{% endif %}
|
||||
|
@ -250,8 +250,8 @@
|
|||
{% else %}
|
||||
{% if u %}
|
||||
{% if v and v.id == u.id %}
|
||||
<div class="row no-gutters">
|
||||
<div class="col">
|
||||
<div class="row no-gutters">
|
||||
<div class="col">
|
||||
<div class="text-center px-3 my-3">
|
||||
<span class="fa-stack fa-2x text-muted mb-4">
|
||||
<i class="fas fa-square text-gray-500 opacity-25 fa-stack-2x"></i>
|
||||
|
@ -260,12 +260,12 @@
|
|||
<h5>You haven't {% if "/saved/" in request.path %}saved{% elif "/subscribed/" in request.path %}subscribed to{% else %}made{% endif %} a post yet</h5>
|
||||
<p class="text-muted mb-md-5">Your {% if "/saved/" in request.path %}saved posts{% elif "/subscribed/" in request.path %}subscribed posts{% else %}posting history{% endif %} will show here.</p>
|
||||
{% if "/saved/" not in request.path and "/subscribed/" not in request.path %}<a href="/submit" class="btn btn-primary">Create a post</a>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="row no-gutters">
|
||||
<div class="col">
|
||||
<div class="row no-gutters">
|
||||
<div class="col">
|
||||
<div class="text-center px-3 my-3">
|
||||
<span class="fa-stack fa-2x text-muted mb-4">
|
||||
<i class="fas fa-square text-gray-500 opacity-25 fa-stack-2x"></i>
|
||||
|
@ -273,16 +273,16 @@
|
|||
</span>
|
||||
<h5>@{{u.username}} hasn't made a post yet</h5>
|
||||
<p class="text-muted mb-1">Their posting history will show here.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% elif request.path != '/notifications/posts' %}
|
||||
<div class="row no-gutters">
|
||||
<div class="row no-gutters">
|
||||
<div class="col">
|
||||
{{macros.ghost_box(error if request.path.startswith('/search') else '', '', 1)}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
</div>
|
||||
<label class='mt-4' for="title">Post Title</label>
|
||||
<input autocomplete="off" class="form-control allow-emojis" id="post-title" type="text" name="title" placeholder="Required" value="{{title}}" minlength="1" maxlength="500" required data-nonce="{{g.nonce}}" data-oninput="checkForRequired();savetext()">
|
||||
<button role="button" data-nonce="{{g.nonce}}" data-onclick="loadEmojis('post-title')" class="btn btn-secondary format d-inline-block m-0" id="emoji-reply-btn-2" data-bs-toggle="modal" data-bs-target="#emojiModal" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Add Emoji"><i class="fas fa-smile-beam"></i></button>
|
||||
<button role="button" data-nonce="{{g.nonce}}" data-onclick="loadEmojis('post-title')" class="btn btn-secondary format d-inline-block m-0" id="emoji-reply-btn-2" data-bs-toggle="modal" data-bs-target="#emojiModal" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Add Emoji"><i class="fas fa-smile-beam"></i></button>
|
||||
<div id="urlblock">
|
||||
<label for="URL" class="mt-3">URL</label>
|
||||
<input autocomplete="off" class="form-control" id="post-url" name="url" type="url" placeholder="Optional if you have text." value="{{request.values.get('url','')}}" required data-nonce="{{g.nonce}}" data-oninput="checkForRequired();hide_image();savetext();checkRepost();autoSuggestTitle()">
|
||||
|
@ -59,11 +59,11 @@
|
|||
</div>
|
||||
<small class="btn btn-secondary format d-inline-block m-0"><span class="font-weight-bolder text-uppercase" data-nonce="{{g.nonce}}" data-onclick="getGifs('post-text')" data-bs-toggle="modal" data-bs-target="#gifModal" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Add GIF">GIF</span></small>
|
||||
|
||||
<button role="button" data-nonce="{{g.nonce}}" data-onclick="loadEmojis('post-text')" class="btn btn-secondary format d-inline-block m-0" id="emoji-reply-btn" data-bs-toggle="modal" data-bs-target="#emojiModal" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Add Emoji"><i class="fas fa-smile-beam"></i></button>
|
||||
<button role="button" data-nonce="{{g.nonce}}" data-onclick="loadEmojis('post-text')" class="btn btn-secondary format d-inline-block m-0" id="emoji-reply-btn" data-bs-toggle="modal" data-bs-target="#emojiModal" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Add Emoji"><i class="fas fa-smile-beam"></i></button>
|
||||
<label class="format btn btn-secondary m-0 ml-2 {% if v %}d-inline-block{% else %}d-none{% endif %}" for="file-upload-submit">
|
||||
<div id="filename-show-submit"><i class="fas fa-file"></i></div>
|
||||
<input autocomplete="off" id="file-upload-submit" multiple="multiple" accept="image/*, video/*, audio/*" type="file" name="file" {% if g.is_tor %}disabled{% endif %} data-nonce="{{g.nonce}}" data-onchange="changename('filename-show-submit','file-upload-submit');checkForRequired()" hidden>
|
||||
</label>
|
||||
</label>
|
||||
<div id="preview" class="preview my-3"></div>
|
||||
<div class="form-text text-small my-1"><a href="/formatting" {% if v and v.newtab %}data-target="t" target="_blank"{% endif %}>Formatting help</a></div>
|
||||
<div class="custom-control custom-checkbox">
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
<input id="submit-hat" disabled type="submit" data-nonce="{{g.nonce}}" data-onclick="disable(this)" class="btn btn-primary ml-auto" value="Submit Hat">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -60,7 +60,7 @@
|
|||
<div class="d-lg-flex">
|
||||
<div class="body w-lg-100">
|
||||
<input type="hidden" name="formkey" value="{{v|formkey}}">
|
||||
|
||||
|
||||
<div><label class="mt-3">Image</label></div>
|
||||
<img loading="lazy" src="/asset_submissions/hats/{{hat.name}}.webp?s={{range(1, 10000000)|random}}" style="max-width:50%;border:5px white solid">
|
||||
|
||||
|
@ -78,7 +78,7 @@
|
|||
<label class="mt-3" for="{{hat.name}}-name">Name</label>
|
||||
<input autocomplete="off" type="text" id="{{hat.name}}-name" class="form-control" name="name" maxlength="30" value="{{hat.name}}" pattern='hat[a-zA-Z0-9]{1,24}' placeholder="Required" required {% if v.admin_level < PERMS['MODERATE_PENDING_SUBMITTED_HATS'] %}readonly{% endif %}>
|
||||
>
|
||||
|
||||
|
||||
<label class="mt-3" for="{{hat.name}}-description">Description</label>
|
||||
<input autocomplete="off" type="text" id="{{hat.name}}-description" class="form-control" name="description" maxlength="300" value="{{hat.description}}" pattern='[^<>&\n\t]{1,300}' placeholder="Required" required {% if v.admin_level < PERMS['MODERATE_PENDING_SUBMITTED_HATS'] %}readonly{% endif %}>
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
<input id="submit-marsey" disabled type="submit" data-nonce="{{g.nonce}}" data-onclick="disable(this)" class="btn btn-primary ml-auto" value="Submit Marsey">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -55,10 +55,10 @@
|
|||
<div class="d-lg-flex">
|
||||
<div class="body w-lg-100">
|
||||
<input type="hidden" name="formkey" value="{{v|formkey}}">
|
||||
|
||||
|
||||
<div><label class="mt-3">Image</label></div>
|
||||
<img loading="lazy" src="/asset_submissions/marseys/{{marsey.name}}.webp?s={{range(1, 10000000)|random}}" style="max-width:50%;border:5px white solid">
|
||||
|
||||
|
||||
<div><label class="mt-3" for="{{marsey.name}}-submitter">Submitter</label></div>
|
||||
<input autocomplete="off" type="text" id="{{marsey.name}}-submitter" class="form-control" maxlength="30" value="{{marsey.submitter}}" readonly>
|
||||
|
||||
|
@ -67,7 +67,7 @@
|
|||
|
||||
<label class="mt-3" for="{{marsey.name}}-name">Name</label>
|
||||
<input autocomplete="off" type="text" id="{{marsey.name}}-name" class="form-control" name="name" maxlength="30" value="{{marsey.name}}" pattern='marsey[a-z0-9]{1,24}' placeholder="Required" required {% if v.admin_level < PERMS['MODERATE_PENDING_SUBMITTED_MARSEYS'] %}readonly{% endif %}>
|
||||
|
||||
|
||||
<label class="mt-3" for="{{marsey.name}}-tags">Tags</label>
|
||||
<input autocomplete="off" type="text" id="{{marsey.name}}-tags" class="form-control" name="tags" maxlength="200" value="{{marsey.tags}}" pattern='[a-z0-9: ]{1,200}' placeholder="Required" required {% if v.admin_level < PERMS['MODERATE_PENDING_SUBMITTED_MARSEYS'] %}readonly{% endif %}>
|
||||
</div>
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue