Lots of shit

- Delete docs because they're outdated
- Move Environment to env
- Update server so it can be ran independently of the (main) function
ご主人様
not manx 5 years ago
parent 65d43fd73d
commit a479b49b3f
Signed by: C-xC-c
GPG Key ID: F52ED472284EF2F4

@ -1,4 +0,0 @@
* /api/flags
returns a plaintext list of all the resolved flags, seperated by
newline characters (\n). This is maintained by the database service
and updated whenever changes are committed to the flag console.

@ -1,70 +0,0 @@
* /api/get
** Recieved Data
All versions of the script send a comma seperated list of post
numbers, =post_nrs= and a board =board=. Modern versions of bantflags
also send a version number, =version=, which decides how the returned
data will be formatted.
Data looks like this:
#+BEGIN_SRC http
POST https://flags.plum.moe/api/get
Content-Type: application/x-www-form-urlencoded
post_nrs=12345,12346,14444&board=bant&version=1
#+END_SRC
** Sent Data
*** GetPosts
Returns an =IEnumerable<IGrouping<int, DataRow>>= of post numbers and
their flags where the post numbers are contained in
=post_nrs=. =board= limits the query to only the board we're currently
on.
*** GetPosts_V1
Minimum script version: 0
Flags are converted from an =IEnumerable<IGrouping<int, DataRow>>= to
a =List<Dictionary<string, string>>= by joining the values in the
=DataRow= by "||", which are then split and converted into an array by
the script.
We're doing a needless conversion at both ends which slows the whole
process down, but it's how extraflags is set up and we need to support
it.
Data looks like this:
#+BEGIN_SRC javascript
[
{
{"post_nr": "123"},
{"regions": "flag1||flag2||flag3"}
},
{
{"post_nr": "456"},
{"regions": "flag4||flag3||flag3"}
}
]
#+END_SRC
*** getPosts_V2
Minimum script version: 2
Flags are converted from an =IEnumerable<IGrouping<int, DataRow>>= to
a =Dictionary<int, IEnumerable<string>>= which can then be parsed by
the script without any conversion. This format is the same as returned
from the database query, sans the extra information returned by a
=DataRow=
Data looks like this:
#+BEGIN_SRC javascript
[
123: [
"flag1",
"flag2",
"flag3"
],
456: [
"flag4",
"flag3",
"flag3"
]
]
#+END_SRC

@ -1,18 +0,0 @@
* /api/post
** Recieved Data
Data is sent from the script to the backend after a post has been
made, containing the post number, =post_nr=, =board= identifier, and
selected flags, =regions=. Modern versions of the script also encode a
=version= which is used when splitting =regions= into individual flags
Data looks like this:
#+BEGIN_SRC http :pretty
POST https://flags/plum.moe/api/post
Content-Type: application/x-www-form-urlencoded
post_nr=12345&board=bant&regions=Patchouli,dount,VIP&version=1
#+END_SRC
** Sent Data
The backend returns either a JSON object of the post, as it would be
returned by =/api/get=, or an error message specific to the issue if
the form data is invalid.

@ -1,15 +0,0 @@
* /Upload
The flag console is the preferred way for adding and modifying flags
in the database. It provides controls for adding, deleting and
renaming flags, all of which are visible before being committed by
someone with with password, which is set using the =staging-password=
section in =appsettings.json=. Changes may be unstaged on an
individual basis, but committed changes must be done all at once.
Flags have several hard-coded requirements for being uploaded using
the console. The image must be 16 by 11 pixels in size, be a PNG file
and have a valid PNG header. Names of files must be under 100
characters in length, and not contain either "," or
"||". Additionally, you cannot name a flag "Empty, or there were
errors. Please re-set your flags." as this is used, well, when someone
hasn't set their flags right.

@ -1,16 +0,0 @@
[Unit]
Description=bantflags serb
[Service]
# Set to the location of the application
WorkingDirectory=/var/www/bantflags/src/
ExecStart=/usr/bin/env sbcl --eval '(progn (push #p"/var/www/bantflags/src" ql:*local-project-directories*) (ql:quickload :bantflags) (main))'
Restart=always
# restarts 10 seconds after it goes bang
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=bantflags
User=nginx
[Install]
WantedBy=multi-user.target

@ -1,102 +0,0 @@
DROP DATABASE IF EXISTS `bantflags`;
CREATE DATABASE `bantflags`;
USE `bantflags`;
CREATE USER IF NOT EXISTS flags@localhost IDENTIFIED BY 'default';
GRANT ALL PRIVILEGES ON bantflags.* TO flags@localhost;
FLUSH PRIVILEGES;
CREATE TABLE `flags` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`flag` varchar(100) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `flag` (`flag`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
CREATE TABLE `posts` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`post_nr` int(10) NOT NULL DEFAULT '0',
`board` varchar(10) NOT NULL DEFAULT 'bant',
PRIMARY KEY (`id`),
UNIQUE KEY `post_nr_board` (`post_nr`,`board`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
CREATE TABLE `postflags` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`post_nr` int(10) NOT NULL DEFAULT '0',
`flag` int(10) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `flag` (`flag`),
KEY `post_nr` (`post_nr`),
CONSTRAINT `flag` FOREIGN KEY (`flag`) REFERENCES `flags` (`id`) ON DELETE CASCADE,
CONSTRAINT `post_nr` FOREIGN KEY (`post_nr`) REFERENCES `posts` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
DELIMITER $$
CREATE DEFINER=`flags`@`localhost` PROCEDURE `insert_post`(
IN `@post_nr` INT,
IN `@board` VARCHAR(5)
)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
BEGIN
INSERT IGNORE INTO `posts` (`post_nr`, `board`) VALUES (`@post_nr`, `@board`);
END
$$
CREATE DEFINER=`flags`@`localhost` PROCEDURE `insert_post_flags`(
IN `@post_nr` INT,
IN `@flag` VARCHAR(100)
)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
BEGIN
insert into postflags (post_nr, flag) VALUES (
(select id from posts where post_nr = `@post_nr`),
(select id from flags where flag = `@flag`)
);
END
$$
CREATE DEFINER=`flags`@`localhost` PROCEDURE `rename_flag`(
IN `@old` VARCHAR(100),
IN `@new` VARCHAR(100)
)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
BEGIN
UPDATE flags SET flags.flag = `@new` WHERE flags.flag = `@old`;
END
$$
CREATE DEFINER=`flags`@`localhost` PROCEDURE `delete_flag`(
IN `@flag` VARCHAR(100)
)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
BEGIN
DELETE flags.* FROM flags WHERE flags.flag = `@flag`;
END
$$
CREATE DEFINER=`flags`@`localhost` PROCEDURE `insert_flag`(
IN `@flag` VARCHAR(100)
)
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
BEGIN
INSERT INTO `flags` (`flag`) VALUES (`@flag`);
END
$$
DELIMITER ;

@ -1,36 +0,0 @@
events {
worker_connections 768;
}
http {
types {
text/html html htm shtm;
text/css css;
image/gif gif;
image/jpeg jpg jpeg;
image/png png;
}
default_type application/octet-stream;
sendfile on;
tcp_nopush on;
charset utf-8;
index index.htm index.html;
server {
root /var/www/flags;
server_name flags.plum.moe;
listen 80;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_cache_bypass $http_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
}
}
}

@ -5,19 +5,19 @@
[[https://flags.plum.moe/bantflags.user.js][Install bantflags]] [[https://flags.plum.moe/bantflags.user.js][Install bantflags]]
** Userscript ** Userscript
The userscript uses of ~GM_xmlhttpRequest~ to get and post flags with The userscript uses of ~GM_xmlhttpRequest~ to get and post flags
the backend . A user's flags are stored between pages using with the backend . A user's flags are stored between pages using
~GM_setValue~ and ~GM_getValue~. ~GM_setValue~ and ~GM_getValue~, or their GreaseMonkey4
equivalents.
Old versions of GreaseMonkey will be able to recieve updates to the Old versions of GreaseMonkey will be able to recieve updates to the
script through the ~@updateURL~ and ~@downloadURL~ directives, though script through the ~@updateURL~ and ~@downloadURL~ directives,
these were depricated sometime in GreaseMonkey 3.x and updates are though these were depricated sometime in GreaseMonkey 3.x and
only checked from the location the script was downloaded from so be updates are only checked from the location the script was
careful where you upload links. downloaded from so be careful where you upload links.
On self hosting, changing ~back_end~ to your domain /should/ be all On self hosting, changing ~back_end~ to your domain /should/ be all
you need to do, but don't take this as fact. I haven't tested the you need to do, but don't take this as fact.
example nginx config.
The userscript has been designed specifically to target ECMAScript The userscript has been designed specifically to target ECMAScript
2015 (ES6), making liberal use of arrow functions, and const/let 2015 (ES6), making liberal use of arrow functions, and const/let
@ -26,9 +26,12 @@
** Backend ** Backend
*** Prerequisites *** Prerequisites
- I use SBCL - I use SBCL
- Some mysql, I use Mariadb
- Quicklisp
*** Dependancies *** Dependancies
- hunchentoot - hunchentoot
- [[https://github.com/C-xC-c/hunchenhelpers][hunchenhelpers]], my hunchentoot helper library - [[https://github.com/C-xC-c/hunchenhelpers][hunchenhelpers]], my hunchentoot helper library (yes I'm proud of
the name)
- clsql - clsql
- jonathan, the JSON encoder/decoder - jonathan, the JSON encoder/decoder
- cl-ppcre - cl-ppcre
@ -37,11 +40,18 @@
2. Symlink src/ to your ~/quicklisp/local-projects 2. Symlink src/ to your ~/quicklisp/local-projects
3. Move ~src/config.example.org~ to ~src/config.org~ and change it 3. Move ~src/config.example.org~ to ~src/config.org~ and change it
to whatever your settings are. to whatever your settings are.
4. Type the following into your repl: 4. Initialise the database by doing something like ~mysql <<
env/database.sql~, This will create all the tables you will
need, plus an entry for the ~`empty flag`~
5. Type the following into your repl:
#+BEGIN_SRC lisp #+BEGIN_SRC lisp
(ql:quickload :bantflags) (ql:quickload :bantflags)
(bantflags:main) (bantflags:main)
#+END_SRC #+END_SRC
6. To use bantflags as a Systemd service, I have included an
example service and an ~init.el~ file for the service to run,
since Systemd will automatically kill it if you just eval
~bantflags:main~.
You will almost certainly have several issues building clsql, the You will almost certainly have several issues building clsql, the
database connector used. I've [[https://plum.moe/words/bludgeoning-clsql-and-mariadb.html][written a blog post]] on some of the database connector used. I've [[https://plum.moe/words/bludgeoning-clsql-and-mariadb.html][written a blog post]] on some of the
issues I've encountered personally, but there's no guarantee it'll issues I've encountered personally, but there's no guarantee it'll

@ -1,9 +1,9 @@
(in-package #:bantflags) (in-package #:bantflags)
(defvar config (defvar config
'((boards "bant") '((boards ("bant" "uhh"))
(staging-password "not implemented") (staging-password "not implemented")
(db-conn "localhost" "bantflags" "flags" "default") (db-conn ("localhost" "bantflags" "flags" "default"))
(poolsize 3) (poolsize 3)
(www-root #p"/path/to/files/") (www-root #p"/path/to/files/")
(port 4242) (port 4242)

@ -29,7 +29,7 @@
(clsql:execute-command (clsql:execute-command
(with-output-to-string (s) (with-output-to-string (s)
(format s "insert into postflags (post_nr, flag) values") (format s "insert into postflags (post_nr, flag) values")
(loop for flag in (butlast flags) (loop for flag in (butlast flags) ;; The last flag needs a semi-colon instead of a comma
do (format s "(~a,~a)," post-id (flag-id flag))) do (format s "(~a,~a)," post-id (flag-id flag)))
(format s "(~a,~a);" post-id (flag-id (car (last flags))))) (format s "(~a,~a);" post-id (flag-id (car (last flags)))))
:database db))) :database db)))

@ -5,27 +5,29 @@
(in-package :bantflags) (in-package :bantflags)
(defun init () (defun init ()
(assert (not (null config)))
(setf conn (conf 'db-conn)) (setf conn (conf 'db-conn))
(loop repeat (cconf 'poolsize) do (loop repeat (conf 'poolsize)
do ;; This doesn't work lole
(clsql:connect conn :database-type :mysql :pool t :if-exists :new)) (clsql:connect conn :database-type :mysql :pool t :if-exists :new))
(set-boards) (set-boards)
(set-flags) (set-flags)
(defvar +serb+ (make-instance 'hunchentoot:easy-acceptor (defvar *serb* (make-instance 'hunchentoot:easy-acceptor
:port (cconf 'port) :port (conf 'port)
:document-root (cconf 'www-root) :address "127.0.0.1" ;; localhost
:access-log-destination (cconf 'access-log) :document-root (conf 'www-root)
:message-log-destination (cconf 'error-log)))) :access-log-destination (conf 'access-log)
:message-log-destination (conf 'error-log))))
(defun main () (defun main ()
(handler-case (init) (handler-case (init)
(error (c) (error (c)
(format t "Init fucked up, exiting ~a" c) (format t "Init fucked up, exiting ~a" c)
(return-from main))) (return-from main)))
(handler-case (hunchentoot:start +serb+) (handler-case (hunchentoot:start *serb*)
(error (c) (error (c)
(format t "couldn't start serb: ~a" c) (format t "couldn't start serb: ~a" c)
(return-from main))) (return-from main))))
(loop (sleep 43200) (gc :full t)))
(defmethod hunchentoot:acceptor-status-message (acceptor (http-status-code (eql 404)) &key) (defmethod hunchentoot:acceptor-status-message (acceptor (http-status-code (eql 404)) &key)
(format nil "")) ;; Empty 404 page (format nil "")) ;; Empty 404 page

@ -7,15 +7,11 @@
(defvar empty-flag '("empty, or there were errors. Re-set your flags.")) (defvar empty-flag '("empty, or there were errors. Re-set your flags."))
(defun conf (thing) (defun conf (thing)
(let ((item (cdr (assoc thing config)))) (let ((item (nth 1 (assoc thing config))))
(if (null item) (if (null item)
(error "no such config item" thing) (error "no such config item" thing)
item))) item)))
(defun cconf (thing)
(car (conf thing)))
;; db
(defun set-boards () (defun set-boards ()
(setf *boards* (make-hash-table :test 'equal)) (setf *boards* (make-hash-table :test 'equal))
(mapc (lambda (board) (setf (gethash board *boards*) t)) (conf 'boards))) (mapc (lambda (board) (setf (gethash board *boards*) t)) (conf 'boards)))
@ -25,8 +21,7 @@
(let ((flags (get-flags))) (let ((flags (get-flags)))
(loop for (id . flag) in flags (loop for (id . flag) in flags
do (setf (gethash (car flag) *flags*) id)) do (setf (gethash (car flag) *flags*) id))
;; We don't want users to select `empty-flag` (setf *flags-txt* ;; We don't want users to select `empty-flag`
(setf *flags-txt*
(cl-ppcre:regex-replace (concatenate 'string (car empty-flag) "\\n") ;; newline (cl-ppcre:regex-replace (concatenate 'string (car empty-flag) "\\n") ;; newline
(format nil "~{~a~^~%~}" (mapcan (lambda (x) (cdr x)) flags)) (format nil "~{~a~^~%~}" (mapcan (lambda (x) (cdr x)) flags))
"")))) ""))))

Loading…
Cancel
Save