mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-09-22 12:03:25 -04:00
#101 stats - server
This commit is contained in:
parent
2ee74b0a1d
commit
073612a10f
@ -1,17 +1,12 @@
|
||||
import { loadSuml } from './server/loader';
|
||||
import fs from 'fs';
|
||||
import {buildDict} from "./src/helpers";
|
||||
import {buildDict, buildLocaleList} from "./src/helpers";
|
||||
|
||||
const config = loadSuml('config');
|
||||
const translations = loadSuml('translations');
|
||||
|
||||
const locale = config.locale;
|
||||
const locales = buildDict(function* () {
|
||||
for (let locale of process.env.LOCALES.split('|')) {
|
||||
const [code, name, url] = locale.split(',');
|
||||
yield [code, {name, url}];
|
||||
}
|
||||
});
|
||||
const locales = buildLocaleList();
|
||||
const title = translations.title;
|
||||
const description = translations.description;
|
||||
const banner = process.env.BASE_URL + '/api/banner/zaimki.png';
|
||||
|
@ -145,7 +145,12 @@
|
||||
for (let pronoun in this.profile.pronouns) {
|
||||
if (!this.profile.pronouns.hasOwnProperty(pronoun)) { continue; }
|
||||
|
||||
const link = decodeURIComponent(pronoun.replace(new RegExp('^' + this.$base), '').replace(new RegExp('^/'), ''));
|
||||
const link = decodeURIComponent(
|
||||
pronoun
|
||||
.replace(new RegExp('^' + this.$base), '')
|
||||
.replace(new RegExp('^' + this.$base.replace(/^https?:\/\//, '')), '')
|
||||
.replace(new RegExp('^/'), '')
|
||||
);
|
||||
const pronounEntity = buildPronoun(pronouns, link);
|
||||
|
||||
if (pronounEntity) {
|
||||
|
@ -189,7 +189,12 @@
|
||||
this.$router.push(`/@${this.$user().username}`)
|
||||
},
|
||||
validatePronoun(pronoun) {
|
||||
const link = decodeURIComponent(pronoun.replace(new RegExp('^' + this.$base), '').replace(new RegExp('^/'), ''));
|
||||
const link = decodeURIComponent(
|
||||
pronoun
|
||||
.replace(new RegExp('^' + this.$base), '')
|
||||
.replace(new RegExp('^' + this.$base.replace(/^https?:\/\//, '')), '')
|
||||
.replace(new RegExp('^/'), '')
|
||||
);
|
||||
|
||||
return buildPronoun(pronouns, link) ? null : 'profile.pronounsNotFound'
|
||||
},
|
||||
|
@ -6,6 +6,7 @@ import cookieParser from 'cookie-parser';
|
||||
import grant from "grant";
|
||||
import router from "./routes/user";
|
||||
import { loadSuml } from './loader';
|
||||
import {buildLocaleList} from "../src/helpers";
|
||||
|
||||
const app = express()
|
||||
|
||||
@ -21,6 +22,7 @@ app.use(session({
|
||||
|
||||
app.use(async function (req, res, next) {
|
||||
req.config = loadSuml('config');
|
||||
req.locales = buildLocaleList();
|
||||
req.rawUser = authenticate(req);
|
||||
req.user = req.rawUser && req.rawUser.authenticated ? req.rawUser : null;
|
||||
req.admin = req.user && req.user.roles === 'admin';
|
||||
|
@ -2,7 +2,7 @@ import { Router } from 'express';
|
||||
import SQL from 'sql-template-strings';
|
||||
import avatar from '../avatar';
|
||||
import {config as socialLoginConfig} from "../social";
|
||||
import {now} from "../../src/helpers";
|
||||
import {now, sortByValue} from "../../src/helpers";
|
||||
|
||||
const router = Router();
|
||||
|
||||
@ -46,4 +46,50 @@ router.get('/admin/users', async (req, res) => {
|
||||
return res.json(groupedUsers);
|
||||
});
|
||||
|
||||
router.get('/admin/stats', async (req, res) => {
|
||||
if (!req.admin) {
|
||||
return res.status(401).json({error: 'Unauthorised'});
|
||||
}
|
||||
|
||||
const users = {
|
||||
overall: (await req.db.get(SQL`SELECT count(*) AS c FROM users`)).c,
|
||||
admins: (await req.db.get(SQL`SELECT count(*) AS c FROM users WHERE roles=${'admin'}`)).c,
|
||||
};
|
||||
|
||||
const locales = {};
|
||||
for (let locale in req.locales) {
|
||||
if (!req.locales.hasOwnProperty(locale)) { continue; }
|
||||
const profiles = await req.db.all(SQL`SELECT pronouns FROM profiles WHERE locale=${locale}`);
|
||||
const pronouns = {}
|
||||
for (let profile of profiles) {
|
||||
const pr = JSON.parse(profile.pronouns);
|
||||
for (let pronoun in pr) {
|
||||
if (!pr.hasOwnProperty(pronoun)) { continue; }
|
||||
|
||||
if (pronoun.includes(',') || pr[pronoun] < 0) {
|
||||
continue;
|
||||
}
|
||||
const p = pronoun.replace(/^.*:\/\//, '').replace(/^\//, '').toLowerCase().replace(/^[a-z]+\.[^/]+\//, '');
|
||||
if (pronouns[p] === undefined) {
|
||||
pronouns[p] = 0;
|
||||
}
|
||||
pronouns[p]++;
|
||||
}
|
||||
}
|
||||
|
||||
locales[locale] = {
|
||||
name: req.locales[locale].name,
|
||||
url: req.locales[locale].url,
|
||||
profiles: profiles.length,
|
||||
pronouns: sortByValue(pronouns, true),
|
||||
nouns: {
|
||||
approved: (await req.db.get(SQL`SELECT count(*) AS c FROM nouns WHERE locale=${locale} AND approved=1`)).c,
|
||||
awaiting: (await req.db.get(SQL`SELECT count(*) AS c FROM nouns WHERE locale=${locale} AND approved=0`)).c,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return res.json({ users, locales });
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
@ -131,3 +131,30 @@ export const now = function () {
|
||||
export const isEmoji = char => {
|
||||
return !!char.match(/^(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\u0023-\u0039]\ufe0f?\u20e3|\u3299|\u3297|\u303d|\u3030|\u24c2|\ud83c[\udd70-\udd71]|\ud83c[\udd7e-\udd7f]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|\ud83c[\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|\ud83c[\ude32-\ude3a]|\ud83c[\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|\u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|\u2b1c|\u2b50|\u2b55|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|\ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff])$/)
|
||||
}
|
||||
|
||||
export const buildLocaleList = () => {
|
||||
return buildDict(function* () {
|
||||
for (let locale of process.env.LOCALES.split('|')) {
|
||||
const [code, name, url] = locale.split(',');
|
||||
yield [code, {name, url}];
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export const zip = (list, reverse) => {
|
||||
return buildDict(function* () {
|
||||
for (let [k, v] of list) {
|
||||
yield reverse ? [v, k] : [k, v];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const sortByValue = (obj, reverse = false) => {
|
||||
const sortedArray = [];
|
||||
for (let i in obj) {
|
||||
if (obj.hasOwnProperty(i)) {
|
||||
sortedArray.push([parseInt(obj[i]), i]);
|
||||
}
|
||||
}
|
||||
return zip(sortedArray.sort((a, b) => reverse ? b[0] - a[0] : a[0] - b[0]), true);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user