diff --git a/Dockerfile b/Dockerfile index ffc826d..3985c26 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,8 @@ FROM tensorflow/tensorflow:2.2.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"] \ No newline at end of file +ENV PASTEY_DATA_DIRECTORY=/app/data +ENTRYPOINT ["python3", "app.py"] diff --git a/Dockerfile-conda b/Dockerfile-conda index 3e24888..ee7b0df 100644 --- a/Dockerfile-conda +++ b/Dockerfile-conda @@ -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"] \ No newline at end of file +ENV PASTEY_DATA_DIRECTORY=/app/data +ENTRYPOINT ["python3", "app.py"] diff --git a/app.py b/app.py index c233566..aff7923 100644 --- a/app.py +++ b/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 = [] diff --git a/pastey/routes.py b/pastey/routes.py index ebb8b9c..84a4c28 100644 --- a/pastey/routes.py +++ b/pastey/routes.py @@ -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/") 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//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/") @@ -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) diff --git a/static/img/language/Dark/docker.png b/static/img/language/Dark/dockerfile.png similarity index 100% rename from static/img/language/Dark/docker.png rename to static/img/language/Dark/dockerfile.png diff --git a/static/img/language/Light/302535_ini_file_icon.png b/static/img/language/Light/302535_ini_file_icon.png deleted file mode 100644 index 9ede796..0000000 Binary files a/static/img/language/Light/302535_ini_file_icon.png and /dev/null differ diff --git a/static/img/language/Light/docker.png b/static/img/language/Light/dockerfile.png similarity index 100% rename from static/img/language/Light/docker.png rename to static/img/language/Light/dockerfile.png diff --git a/templates/config.html b/templates/config.html index 589de05..0666e71 100644 --- a/templates/config.html +++ b/templates/config.html @@ -121,11 +121,55 @@

Download Script

Pastey provides a script that can be used to paste output directly from the command line:

-
$ cat /var/log/nginx.log | pastey
-
$ echo "Hello, Pastey!" | pastey
+
$ pastey -f /var/log/nginx.log
+
$ echo "Hello, Pastey!" | pastey -c -

Download the following, make it executable, and put it in your system PATH to be used anywhere!

+ + + +
+ + + +
+
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.
+
+ +
-
+

@@ -136,7 +180,7 @@
-

+

diff --git a/templates/pastey.sh b/templates/pastey.sh index d989825..c6d7fe6 100755 --- a/templates/pastey.sh +++ b/templates/pastey.sh @@ -7,7 +7,7 @@ # script framework based on https://betterdev.blog/minimal-safe-bash-script-template/ # initially adapted and written by Serge van Ginderachter -set -Eeuo pipefail +set -Eeo pipefail #execute=(echo popo)trap cleanup SIGINT SIGTERM ERR EXIT script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd -P) @@ -74,8 +74,8 @@ parse_params() { content= title= file= - single= - encrypt= + single="false" + encrypt="false" while (( "$#" )) do @@ -114,12 +114,12 @@ parse_params() { -s | --single) shift || : - single="-F single=" + single="true" ;; -e | --encrypt) shift || : - encrypt="-F encrypt=" + encrypt="true" ;; --) @@ -170,7 +170,7 @@ parse_options(){ content="$(

{{ paste.title }}

- Format: {{ paste.language }}
+ + Format: {{ paste.language }} + {% if not paste.encrypted %} +  ( View Raw) + {% endif %}
+ Date: {{ paste.timestamp }}
{% if paste.expiration is defined and paste.expiration != "" %} Expires: {{ paste.expiration }}
@@ -139,15 +144,15 @@
-
-
- {% if paste.language == "Plaintext" %} -
{{ paste.content }}
- {% else %} -
{{ paste.content }}
- {% endif %} -
-
+
+
+ {% if paste.language == "Plaintext" %} +
{{ paste.content }}
+ {% else %} +
{{ paste.content }}
+ {% endif %} +
+