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 4 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]]
** Userscript
The userscript uses of ~GM_xmlhttpRequest~ to get and post flags with
the backend . A user's flags are stored between pages using
~GM_setValue~ and ~GM_getValue~.
The userscript uses of ~GM_xmlhttpRequest~ to get and post flags
with the backend . A user's flags are stored between pages using
~GM_setValue~ and ~GM_getValue~, or their GreaseMonkey4
equivalents.
Old versions of GreaseMonkey will be able to recieve updates to the
script through the ~@updateURL~ and ~@downloadURL~ directives, though
these were depricated sometime in GreaseMonkey 3.x and updates are
only checked from the location the script was downloaded from so be
careful where you upload links.
script through the ~@updateURL~ and ~@downloadURL~ directives,
though these were depricated sometime in GreaseMonkey 3.x and
updates are only checked from the location the script was
downloaded from so be careful where you upload links.
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
example nginx config.
you need to do, but don't take this as fact.
The userscript has been designed specifically to target ECMAScript
2015 (ES6), making liberal use of arrow functions, and const/let
@ -26,9 +26,12 @@
** Backend
*** Prerequisites
- I use SBCL
- Some mysql, I use Mariadb
- Quicklisp
*** Dependancies
- 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
- jonathan, the JSON encoder/decoder
- cl-ppcre
@ -37,11 +40,18 @@
2. Symlink src/ to your ~/quicklisp/local-projects
3. Move ~src/config.example.org~ to ~src/config.org~ and change it
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
(ql:quickload :bantflags)
(bantflags:main)
#+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
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

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

@ -29,7 +29,7 @@
(clsql:execute-command
(with-output-to-string (s)
(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)))
(format s "(~a,~a);" post-id (flag-id (car (last flags)))))
:database db)))

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

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

Loading…
Cancel
Save