Compare commits

...

4 Commits

Author SHA1 Message Date
Cesura c14625b26e Bump tensorflow base image to 2.5.0
2 years ago
Cesura 0eff189cd9 Make script use json endpoint + add support for raw viewing
2 years ago
Serge van Ginderachter 3ae36db717
new, improved pastey cli command (#12)
2 years ago
WolfwithSword 914a250a40
Updated Guesslang version (#17)
2 years ago

@ -1,6 +1,8 @@
FROM tensorflow/tensorflow:2.2.0
FROM tensorflow/tensorflow:2.5.0
WORKDIR /app
COPY requirements.txt /app
RUN mkdir -p /app/data && pip install -r /app/requirements.txt
COPY . /app/
RUN pip install -r /app/requirements.txt
EXPOSE 5000
WORKDIR /app
ENTRYPOINT ["python3","app.py"]
ENV PASTEY_DATA_DIRECTORY=/app/data
ENTRYPOINT ["python3", "app.py"]

@ -2,7 +2,8 @@ FROM continuumio/conda-ci-linux-64-python3.8
USER root
COPY . /app/
RUN conda install -c anaconda tensorflow=2.2.0 pip
RUN pip install -r /app/requirements.txt
RUN mkdir -p /app/data && pip install -r /app/requirements.txt
EXPOSE 5000
WORKDIR /app
ENTRYPOINT ["python3","app.py"]
ENV PASTEY_DATA_DIRECTORY=/app/data
ENTRYPOINT ["python3", "app.py"]

@ -6,7 +6,7 @@ from os import environ
from distutils.util import strtobool
from threading import Thread
pastey_version = "0.4.2"
pastey_version = "0.5"
loaded_config = {}
loaded_themes = []

@ -34,6 +34,8 @@ def get_icon(language):
return "cplusplus"
elif language == "Jupyter Notebook":
return "jupyter"
elif language == "Visual Basic":
return "vb"
else:
return language.lower()

@ -1,11 +1,12 @@
from __main__ import app, limiter, loaded_config
from . import config, common, functions
from flask import Flask, render_template, request, redirect, abort
from flask import Flask, render_template, request, redirect, abort, make_response
from urllib.parse import quote
from datetime import datetime
from os import environ
import json
from base64 import b64decode
# Load themes
loaded_themes = common.get_themes()
@ -64,17 +65,29 @@ def config_page():
# View paste page
@app.route("/view/<unique_id>")
def view(unique_id):
content = functions.get_paste(unique_id)
paste = functions.get_paste(unique_id)
if content is not None:
if paste is not None:
return render_template("view.html",
paste=content,
paste=paste,
url=common.build_url(request, "/view/" + unique_id),
whitelisted=common.verify_whitelist(common.get_source_ip(request)),
active_theme=common.set_theme(request),
themes=loaded_themes)
else:
abort(404)
# View paste page (raw)
@app.route("/view/<unique_id>/raw")
def view_raw(unique_id):
paste = functions.get_paste(unique_id)
if paste is not None:
response = make_response(paste['content'], 200)
response.mimetype = "text/plain"
return response
else:
abort(404)
# Delete paste
@app.route("/delete/<unique_id>")
@ -88,7 +101,7 @@ def delete(unique_id):
# Script download
@app.route("/pastey")
def pastey_script():
return render_template('pastey.sh', endpoint=common.build_url(request, "/raw")), 200, {
return render_template('pastey.sh', endpoint=common.build_url(request, "/paste")), 200, {
'Content-Disposition': 'attachment; filename="pastey"',
'Content-Type': 'text/plain'
}
@ -176,6 +189,12 @@ def paste_json():
abort(400)
content = paste['content']
# Check if content was base64 encoded (from the CLI client typically)
from_client = False
if 'base64' in paste and paste['base64'] == True:
from_client = True
content = b64decode(content).decode("utf-8")
# Optional fields
title = paste['title'] if ('title' in paste and paste['title'].strip() != "") else "Untitled"
single = paste['single'] if ('single' in paste and type(paste['single']) == bool) else False
@ -186,13 +205,19 @@ def paste_json():
# Create paste
unique_id, key = functions.new_paste(title, content, source_ip, expires=expiration, single=single, encrypt=encrypt, language=language)
if encrypt:
return {
"link": common.build_url(request, "/view/" + unique_id + "#" + quote(key))
}, 200
if from_client:
return common.build_url(request, "/view/" + unique_id + "#" + quote(key)), 200
else:
return {
"link": common.build_url(request, "/view/" + unique_id + "#" + quote(key))
}, 200
else:
return {
"link": common.build_url(request, "/view/" + unique_id)
}, 200
if from_client:
return common.build_url(request, "/view/" + unique_id), 200
else:
return {
"link": common.build_url(request, "/view/" + unique_id)
}, 200
# Custom 404 handler
@app.errorhandler(404)

@ -1,4 +1,4 @@
Flask==1.1.2
Flask-Limiter==1.4
guesslang==2.0.1
guesslang==2.2.1
cryptography==3.4.7

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

@ -121,11 +121,55 @@
<div class="col-md-12">
<h1 class="mb-3 h4">Download Script</h1>
<p>Pastey provides a script that can be used to paste output directly from the command line:</p>
<pre>$ cat /var/log/nginx.log | pastey</pre>
<pre>$ echo "Hello, Pastey!" | pastey</pre>
<pre>$ pastey -f /var/log/nginx.log</pre>
<pre>$ echo "Hello, Pastey!" | pastey -c -</pre>
<p style="font-weight:bold;">Download the following, make it executable, and put it in your system PATH to be used anywhere!</p>
<!-- Help button -->
<br />
<a
class="btn btn-primary"
data-mdb-toggle="collapse"
href="#script-help"
role="button"
aria-expanded="false"
aria-controls="script-help"
>
<i class="fas fa-info"></i>&nbsp;&nbsp;&nbsp;Show script usage
</a>
<div class="collapse mt-3" style="text-align: left !important; margin-left:25%;" id="script-help">
<br /><pre>Usage: pastey [-h] [-v] [-f] -p param_value arg1 [arg2...]
Script description here.
Available options:
-h, --help Print this help and exit
-v, --verbose Print script debug info
-c, --content Pass the content of the paste in a simple argument
-e, --encrypt Encrypt the paste content
-f, --file Read the content from this file. If file is "-", read from stdin
-s, --single Create a paste that expires after the first view
-t, --title Set the title of the paste
-x, --expiration
Set the time in hours after which the paste expires
-- Stop further option parsing
Arguments passed after the -- option are evaluated
as a command, and that command's output is pasted.
The full command is used a the title.
If zero arguments are passed,
or none of --content, --file or -- are passed,
content is read from stdin.</pre>
</div>
</div>
</div><br />
</div><br /><br />
<div class="row justify-content-md-center">
<div class="col-md-4">
@ -136,7 +180,7 @@
<button type="button" class="btn btn-success text-nowrap"><i class="fas fa-download"></i>&nbsp;&nbsp;&nbsp;Download</button>
</a>
</div>
</div><br />
</div><br /><br />
<div class="row text-center">
<div class="col-md-12">

@ -119,7 +119,7 @@
<div class="row">
<div class="col-md-4 mb-4">
<div class="bg-image hover-overlay shadow-1-strong rounded ripple pastey-preview-image" data-mdb-ripple-color="light">
<img src="/static/img/language/{{ active_theme }}/{{ paste.icon }}.png" class="img-fluid" />
<img src="/static/img/language/{{ active_theme }}/{{ paste.icon }}.png" onerror="this.src='/static/img/language/{{ active_theme }}/plaintext.png'" class="img-fluid" />
<a href="/view/{{ paste.unique_id }}">
<div class="mask" style="background-color: rgba(251, 251, 251, 0.15);"></div>
</a>

@ -1,19 +1,234 @@
#!/bin/bash
#!/usr/bin/env bash
# Install this script into your PATH and chmod +x
# Usage example:
# $ cat /var/log/nginx.log | pastey
# c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t
# vi: set shiftwidth=4 tabstop=4 noexpandtab:
# :indentSize=4:tabSize=4:noTabs=false:
if ! command -v curl &> /dev/null ; then
echo "Please install curl to use this script"
exit 1
fi
# script framework based on https://betterdev.blog/minimal-safe-bash-script-template/
# initially adapted and written by Serge van Ginderachter <serge@vanginderachter.be>
set -Eeo pipefail
#execute=(echo popo)trap cleanup SIGINT SIGTERM ERR EXIT
script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd -P)
# your custom endpoint
PASTEY_ENDPOINT="{{ endpoint }}"
PASTEY_CONTENT=$(</dev/stdin)
# Submit paste
PASTEY_LINK=$(curl -s -X POST -H "Content-Type: text/plain" --data "${PASTEY_CONTENT}" "${PASTEY_ENDPOINT}")
#
## functions
usage() {
cat <<-EOF
Usage: $(basename "${BASH_SOURCE[0]}") [-h] [-v] [-f] -p param_value arg1 [arg2...]
Script description here.
Available options:
-h, --help Print this help and exit
-v, --verbose Print script debug info
-c, --content Pass the content of the paste in a simple argument
-e, --encrypt Encrypt the paste content
-f, --file Read the content from this file. If file is "-", read from stdin
-s, --single Create a paste that expires after the first view
-t, --title Set the title of the paste
-x, --expiration
Set the time in hours after which the paste expires
-- Stop further option parsing
Arguments passed after the -- option are evaluated
as a command, and that command's output is pasted.
The full command is used a the title.
If zero arguments are passed,
or none of --content, --file or -- are passed,
content is read from stdin.
EOF
exit
}
cleanup() {
trap - SIGINT SIGTERM ERR EXIT
msg "Some unhandled error happened.\n"
usage
}
msg() {
echo >&2 -e "${1-}"
}
die() {
local msg=$1
local code=${2-1} # default exit status 1
msg "$msg\n"
exit "$code"
}
parse_params() {
# check required params and arguments
expiration=
content=
title=
file=
single="false"
encrypt="false"
while (( "$#" ))
do
case "${1-}" in
-h | --help)
usage
;;
-v | --verbose)
set -x
;;
-t | --title)
shift || :
title="${1}"
shift || :
;;
-c | --content)
shift || :
content="${1}"
shift || :
;;
-f | --file)
shift || :
file="${1}"
shift || :
;;
-x | --expiration)
shift || :
expiration="${1}"
shift || :
;;
-s | --single)
shift || :
single="true"
;;
-e | --encrypt)
shift || :
encrypt="true"
;;
--)
shift || :
execute=($*)
shift $#
;;
-?*)
die "Unknown option: $1"
shift || :
;;
*)
if [[ -n "${1:-}" ]]
then
die "Unknown parameter: $1"
fi
;;
esac
done
}
parse_options(){
# warn if both single and expiration are set
if [[ -n "${expiration}" ]] && [[ -n "${single}" ]]
then
die "option -x|--expiration and -s|--single are mutually exclusive"
fi
# warn if more than 1 source
if [[ -n "${content}" && -n "${file}" ]] ||
[[ -n "${content}" && -n "${execute[*]}" ]] ||
[[ -n "${execute[*]}" && -n "${file}" ]]
then
die "option -c|--content, -f|--file and -- <command> are mutually exclusive"
fi
if [[ -z "${content}" ]]
then
if [[ -n "${file}" ]]
then
if [[ ${file} = "-" ]]
then
content="$(</dev/stdin)"
elif [ -r ${file} ]
then
content="$(cat ${file} | tr -d '\0')"
else
die "Could not read from ${file}"
fi
elif [[ -n "${execute[*]}" ]]
then
content="$( bash -c "${execute[*]}" 2>&1 ||: )"
else
content="$(</dev/stdin)"
fi
fi
# expiration needs to be set to disabled
if [ -z "${expiration}" ]
then
expiration="-1"
fi
# alternative titles if possible
if [ -z "${title}" ]
then
if [ -n "${file}" ]
then
title="${file}"
elif [ -n "${execute[*]}" ]
then
title="${execute[@]}"
fi
fi
}
# just do it now
paste_it() {
content=$(echo -n "${content}" | base64)
payload="{
\"content\": \"${content}\",
\"title\": \"${title}\",
\"expiration\": \"${expiration}\",
\"encrypt\": ${encrypt},
\"single\": ${single},
\"base64\": true
}"
echo -n $payload | curl \
-X POST \
-H "Content-Type: application/json" \
--data-binary @- \
${PASTEY_ENDPOINT}; echo
}
## main execution
parse_params $*
parse_options
paste_it
# Print link
echo "${PASTEY_LINK}"
# exit cleanly
trap - SIGINT SIGTERM ERR EXIT
exit 0

@ -98,7 +98,12 @@
<div class="pastey-title">
<h1 class="mb-3 h2" id="pastey-title">{{ paste.title }}</h1>
</div>
<span style="font-weight:bold;">Format: </span><span>{{ paste.language }}</span><br />
<span style="font-weight:bold;">Format: </span>{{ paste.language }}</span>
{% if not paste.encrypted %}
<span>&nbsp;(<a href='{{ url }}/raw' target='_blank'><i class="fas fa-eye"></i>&nbsp;View Raw</a>)</span>
{% endif %}<br />
<span style="font-weight:bold;">Date: </span><span>{{ paste.timestamp }}</span><br />
{% if paste.expiration is defined and paste.expiration != "" %}
<span style="font-weight:bold;">Expires: </span><span>{{ paste.expiration }}</span><br />
@ -139,15 +144,15 @@
<!--Main layout-->
<main class="my-5">
<div class="container">
<div class="row">
<div class="col-md-12 mb-4">
{% if paste.language == "Plaintext" %}
<pre class="prettyprint nocode" id="pastey-content">{{ paste.content }}</pre>
{% else %}
<pre class="prettyprint linenums" id="pastey-content">{{ paste.content }}</pre>
{% endif %}
</div>
</div>
<div class="row">
<div class="col-md-12 mb-4">
{% if paste.language == "Plaintext" %}
<pre class="prettyprint nocode" id="pastey-content">{{ paste.content }}</pre>
{% else %}
<pre class="prettyprint linenums" id="pastey-content">{{ paste.content }}</pre>
{% endif %}
</div>
</div>
<!-- QR Modal -->
<div

Loading…
Cancel
Save