rj1
about | log | files | refs
commit 91db096ef0cfd48e9b78d7d5e2a78001717fca0f
author: rj1 <[email protected]>
date:   Fri,  9 Dec 2022 02:33:17 -0600

first

Diffstat:
A.gitignore | 1+
AREADME.md | 27+++++++++++++++++++++++++++
Apaste.py | 72++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Arequirements.txt | 4++++
Aschema.sql | 1+
Astyle.css | 1+
6 files changed, 106 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1 @@ +paste.db diff --git a/README.md b/README.md @@ -0,0 +1,27 @@ +# paste.rj1.su + +personal *bin clone + +## usage + +``` +cat paste.py | curl -F 'paste=<-' https://paste.rj1.su/ +``` + +## setup + +### database + +``` +sqlite3 paste.db < schema.sql +``` + +### uwsgi + +``` +[uwsgi] +socket = 127.0.0.1:55555 +chdir = /usr/home/rj1/web/paste.rj1.su +wsgi-file = paste.py +``` + diff --git a/paste.py b/paste.py @@ -0,0 +1,72 @@ +import bottle +from bottle import template, response, request, HTTPError, static_file, redirect +from bottle.ext import sqlite +from hashids import Hashids +import pygments.lexers +from pygments import highlight +from pygments.formatters import HtmlFormatter +from datetime import datetime + + +app = bottle.Bottle() +app.install(bottle.ext.sqlite.Plugin(dbfile="paste.db")) +hashids = Hashids(salt="", min_length="3") + + [email protected]("/") +def index(): + return redirect("https://rj1.su/") + + [email protected]("/style.css") +def stylesheet(): + return static_file("/style.css", root=".") + + [email protected]("/<hashed>") +def share_paste(hashed, db): + id = hashids.decrypt(hashed) + if len(id) == 0: + return HTTPError(404, "404") + + row = db.execute("select * from paste where docid = ?", (id[0],)).fetchone() + if not row: + return HTTPError(404, "404") + + syntax = request.query_string + if not syntax: + response.content_type = "text/plain; charset=UTF-8" + return row[0] + + try: + lexer = pygments.lexers.get_lexer_by_name(syntax) + except: + lexer = pygments.lexers.TextLexer() + + response.content_type = "text/html; charset=UTF-8" + return highlight( + row[0], + lexer, + HtmlFormatter( + full=True, + cssfile="style.css", + noclobber_cssfile=True, + lineanchors="n", + linenos="table", + encoding="utf-8", + ), + ) + + [email protected]("/") +def receive_paste(db): + response.content_type = "text/plain; charset=UTF-8" + paste = request.forms.get("paste") + cur = db.cursor() + cur.execute("insert into paste values(?,?)", (paste, datetime.now().isoformat())) + id = cur.lastrowid + hashed = hashids.encrypt(id) + return "https://paste.rj1.su/" + hashed + "\n" + + +# app.run(port=55555, host="0.0.0.0") diff --git a/requirements.txt b/requirements.txt @@ -0,0 +1,4 @@ +bottle +bottle-sqlite +hashids +pygments diff --git a/schema.sql b/schema.sql @@ -0,0 +1 @@ +CREATE VIRTUAL TABLE paste USING fts3 (content text, ts timestamp); diff --git a/style.css b/style.css @@ -0,0 +1 @@ +html{color:#232333;font-family:monospace;font-size:15px;line-height:1.6em}body{display:block;margin:8px;color:#fff;background-color:#1d2330}p{line-height:1.5}hr{border:0;margin:1em 0}blockquote{border-left:3px solid rebeccapurple;color:#737373;margin:0;padding-left:1em}nav a,a{text-decoration:none;border-bottom-style:solid;border-bottom-width:1px;border-bottom-color:#98c379}ul{list-style:none;padding-left:2ch}ul li{text-indent:-2ch}ul>li::before{content:"* ";font-weight:700}.table-container{overflow-x:scroll;margin:4px,;padding:4px;overflow-x:auto;overflow-y:hidden;white-space:nowrap}th td{white-space:nowrap;width:calc(50% - 0.5em);display:inline-block;overflow:auto}table{width:100%}table#files,#branches,#tags{width:unset}table tr th{background:#3e4452;padding:0;border:#111 solid 1px;text-align:center;font-weight:700}table tr td{border:none}figure{box-sizing:border-box;display:inline-block;margin:0;max-width:100%}figure img{max-height:500px}@media screen and (min-width:600px){figure{padding:0 40px}}figure h4{font-size:1rem;margin:0;margin-bottom:1em}figure h4::before{content:"в†і "}.highlight pre ::selection{background:rgba(255,255,255,.2);color:inherit}pre code{background-color:inherit;color:inherit;font-size:100%;padding:0}.content{margin-bottom:4em;margin-left:auto;margin-right:auto;max-width:900px;padding:0 1ch;word-wrap:break-word}header{display:flex;flex-wrap:wrap;justify-content:space-between;margin:1em 0}header .main{font-size:1.5rem}header a{border:none}header nav a{border-bottom-style:solid;border-bottom-width:1px;border-bottom-color:#98c379}footer a{border:none}h1,h2,h3,h4,h5,h6{font-size:1.2rem}footer{margin-top:1em}.title h1{margin-bottom:0}time{color:grey}.callout{background-color:#1e90ff;color:#fff;padding:1em}.callout p{margin:0}.callout a{border-bottom:3px solid #fff}.callout a:hover{background-color:#fff;color:#1e90ff}.site-description{display:flex;justify-content:space-between}.tags li::before{content:"рџЏ· "}svg{max-height:15px}.draft-label{text-decoration:none;padding:2px 4px;border-radius:4px;margin-left:6px}.highlight{position:relative;-webkit-overflow-scrolling:touch}.highlight pre code[class*=language-]{-webkit-overflow-scrolling:touch}.highlight pre code[class*=language-]::before{background:#000;border-radius:0 0 .25rem .25rem;color:#fff;font-size:12px;letter-spacing:.025rem;padding:.1rem .5rem;position:absolute;right:1rem;text-align:right;text-transform:uppercase;top:0}::-moz-selection{background:#98c379;color:#fff;text-shadow:none}::selection{background:#98c379;color:#fff;text-shadow:none}hr{border-top:3px dotted #8b8b97}code{background-color:#ad69af;color:#fff;text-decoration:bold;padding:.1em .2em}pre,#blob{background-color:#282a36;line-height:1.4;overflow-x:auto;font-size:.9em;padding:10px}.line{border:none}.A,span.i,pre a.i{color:#98c379}pre a.i:hover{color:#000}.D,span.d,pre a.d{color:#fd5656}pre a{border:none}blockquote{border-color:#7a9f60}h1,h2,h3,h4,h5,h6{color:#ddd}h1::before{color:#98c379;content:"# "}h2::before{color:#98c379;}h3::before{color:#98c379;content:"### "}h4::before{color:#98c379;content:"#### "}h5::before{color:#98c379;content:"##### "}h6::before{color:#98c379;content:"###### "}a{color:inherit}a:hover{background-color:#98c379;color:#000}.main a:hover{background-color:transparent}.site-description a{color:#ddd}.site-description a:hover{color:#000}.tags a:hover{background-color:#98c379;color:#000}.site-title a{color:#fff;text-decoration:none!important}.header nav,.footer{border-color:#333}.soc{margin-right:5px}.soc:hover{color:#000}.clone{color:grey;font-size:.7em;line-height:.8;padding-bottom:5px}.meta{color:grey}.draft-label{color:#98c379;background-color:blue}.highlight pre code[class=language-javaScript]::before,.highlight pre code[class=language-js]::before{content:"js";background:#f7df1e;color:#000}.highlight pre code[class*=language-yml]::before,.highlight pre code[class*=language-yaml]::before{content:"yaml";background:#f71e6a;color:#fff}.highlight pre code[class*=language-shell]::before,.highlight pre code[class*=language-bash]::before,.highlight pre code[class*=language-sh]::before{content:"shell";color:#fff}.highlight pre code[class*=language-json]::before{content:"json";background:#1e90ff;color:#000}.highlight pre code[class*=language-python]::before,.highlight pre code[class*=language-py]::before{content:"py";background:blue;color:#ff0}.highlight pre code[class*=language-css]::before{content:"css";background:cyan;color:#000}.highlight pre code[class*=language-go]::before{content:"Go";background:cyan;color:#4169e1}.highlight pre code[class*=language-md]::before,.highlight pre code[class*=language-md]::before{content:"Markdown";background:#4169e1;color:#f5f5f5}.md img{max-width:100%}.md table{border-spacing:0;border-collapse:collapse}.md table th,.md table td{padding:6px 13px;border:1px solid #3e4452}pre{line-height:125%}td.linenos .normal{color:inherit;background-color:transparent;padding-left:5px;padding-right:5px}span.linenos{color:inherit;background-color:transparent;padding-left:5px;padding-right:5px}td.linenos .special{color:#000;background-color:#ffffc0;padding-left:5px;padding-right:5px}span.linenos.special{color:#000;background-color:#ffffc0;padding-left:5px;padding-right:5px}.hll{background-color:#ffc}.c{color:#7f848e}.err{color:#abb2bf}.esc{color:#abb2bf}.g{color:#abb2bf}.k{color:#c678dd}.l{color:#abb2bf}.n{color:#e06c75}.o{color:#56b6c2}.x{color:#abb2bf}.p{color:#abb2bf}.ch{color:#7f848e}.cm{color:#7f848e}.cp{color:#7f848e}.cpf{color:#7f848e}.c1{color:#7f848e}.cs{color:#7f848e}.gd{color:#abb2bf}.ge{color:#abb2bf}.gr{color:#abb2bf}.gh{color:#abb2bf}.gi{color:#abb2bf}.go{color:#abb2bf}.gp{color:#abb2bf}.gs{color:#abb2bf}.gu{color:#abb2bf}.gt{color:#abb2bf}.kc{color:#e5c07b}.kd{color:#c678dd}.kn{color:#c678dd}.kp{color:#c678dd}.kr{color:#c678dd}.kt{color:#e5c07b}.ld{color:#abb2bf}.m{color:#d19a66}.s{color:#98c379}.na{color:#e06c75}.nb{color:#e5c07b}.nc{color:#e5c07b}.no{color:#e06c75}.nd{color:#61afef}.ni{color:#e06c75}.ne{color:#e06c75}.nf{color:#61afef;font-weight:700}.nl{color:#e06c75}.nn{color:#e06c75}.nx{color:#e06c75}.py{color:#e06c75}.nt{color:#e06c75}.nv{color:#e06c75}.ow{color:#56b6c2}.p-marker{color:#abb2bf}.w{color:#abb2bf}.mb{color:#d19a66}.mf{color:#d19a66}.mh{color:#d19a66}.mi{color:#d19a66}.mo{color:#d19a66}.sa{color:#98c379}.sb{color:#98c379}.sc{color:#98c379}.dl{color:#98c379}.sd{color:#98c379}.s2{color:#98c379}.se{color:#98c379}.sh{color:#98c379}.si{color:#98c379}.sx{color:#98c379}.sr{color:#98c379}.s1{color:#98c379}.ss{color:#98c379}.bp{color:#e5c07b}.fm{color:#56b6c2;font-weight:700}.vc{color:#e06c75}.vg{color:#e06c75}.vi{color:#e06c75}.vm{color:#e06c75}.il{color:#d19a66}.ascii_gallery{display:grid;grid-gap:10px;grid-template-columns:repeat(auto-fit,minmax(100px,1fr));margin-top:1.25rem}.ascii_gallery img{width:100%;display:block;max-height:120px;overflow:hidden;object-fit:cover}.ascii_gallery .ascii{margin-top:0;position:relative;overflow:hidden}.ascii_gallery .caption{font-size:14px;padding:.01em;position:absolute;bottom:0;width:100%;max-height:100%;background:rgba(0,0,0,.7);color:#fff}