return self.db.fetch_one(Paste, query, *args, **kwargs)
def create(self, content, subject=None, mimetype=None, expires=None, account=None, address=None):
+ # Convert any text to bytes
+ if isinstance(content, str):
+ content = content.encode("utf-8")
+
# Store the blob
blob_id = self._store_blob(content)
{% extends "../base.html" %}
-{% block title %}
- {% if mode == "paste" %}
- {{ _("New Paste") }}
- {% elif mode == "upload" %}
- {{ _("Upload File") }}
- {% end %}
-{% end block %}
+{% block title %}{{ _("New Paste") }}{% end block %}
{% block container %}
<section class="hero is-primary">
<div class="hero-body">
<div class="container">
- <nav class="breadcrumb" aria-label="breadcrumbs">
- <ul>
- <li>
- <a href="/">Home</a>
- </li>
- <li class="is-active">
- <a href="#" aria-current="page">Nopaste</a>
- </li>
- </ul>
- </nav>
- <h1 class="title">
- {% if mode == "paste" %}
- {{ _("New Paste") }}
- {% elif mode == "upload" %}
- {{ _("Upload File") }}
- {% end %}
- </h1>
+ <h1 class="title">{{ _("New Paste") }}</h1>
</div>
</div>
</section>
<div class="container">
<div class="columns">
<div class="column is-8">
- <form class="form-horizontal" action="" method="POST" enctype="multipart/form-data">
+ <form action="" method="POST">
{% raw xsrf_form_html() %}
- <input type="hidden" name="mode" value="{{ mode }}">
+ <div class="field">
+ <label class="label">{{ _("Subject") }}</label>
- {% if mode == "paste" %}
- <div class="block">
+ <div class="control">
<input class="input" type="text" name="subject"
placeholder="{{ _("Subject") }} ({{ _("optional") }})">
</div>
- {% end %}
+ </div>
- <div class="block">
- {% if mode == "paste" %}
- <textarea class="textarea" rows="12" name="content"
+ <div class="field">
+ <div class="control">
+ <textarea class="textarea" rows="12" name="content" required
placeholder="{{ _("Paste your content here...") }}"></textarea>
- {% elif mode == "upload" %}
- <p class="is-size-4">{{ _("File") }}</p>
- <div class="file has-name is-fullwidth">
- <label class="file-label">
- <input class="file-input" type="file" name="file">
- <span class="file-cta">
- <span class="file-icon">
- <i class="fas fa-upload"></i>
- </span>
- <span class="file-label">
- Choose a file…
- </span>
- </span>
- <span class="file-name">
- <!-- hier müsste man irgendwie den filenamen anzeigen-->
- </span>
- </label>
- </div>
-
- {% if max_size %}
- <p class="is-size-6">
- {{ _("You may upload up to %s") % format_size(max_size) }}
- </p>
- {% end %}
- {% end %}
+ </div>
</div>
- <div class="block">
- <p class="is-size-5">Expires</p>
+ <div class="field">
+ <label class="label">{{ _("Expires After") }}</label>
- <div class="select" name="expires">
- <select>
- <option value="0">{{ _("never") }}</option>
- <option value="600">{{ _("after ten minutes") }}</option>
- <option value="3600">{{ _("after one hour") }}</option>
- <option value="{{ 24 * 3600 }}">{{ _("after one day") }}</option>
- <option value="{{ 7 * 24 * 3600 }}">{{ _("after one week") }}</option>
- <option value="{{ 30 * 24 * 3600 }}" selected>{{ _("after one month") }}</option>
- </select>
+ <div class="control">
+ <div class="select is-fullwidth" name="expires">
+ <select>
+ <option value="0">{{ _("never") }}</option>
+ <option value="600">{{ _("after ten minutes") }}</option>
+ <option value="3600">{{ _("after one hour") }}</option>
+ <option value="{{ 24 * 3600 }}">{{ _("after one day") }}</option>
+ <option value="{{ 7 * 24 * 3600 }}">{{ _("after one week") }}</option>
+ <option value="{{ 30 * 24 * 3600 }}" selected>{{ _("after one month") }}</option>
+ </select>
+ </div>
</div>
</div>
- <div class="block">
- <button type="submit" class="button is-primary has-text-weight-bold">
- <i class="fa-solid fa-upload"></i>{{ _("Upload") }}
- </button>
+ <div class="field">
+ <div class="control">
+ <button type="submit" class="button is-primary has-text-weight-bold">
+ <i class="fa-solid fa-upload"></i>{{ _("Upload") }}
+ </button>
+ </div>
</div>
</form>
</div>
# Serve any static files
(r"/static/(.*)", tornado.web.StaticFileHandler, { "path" : self.settings.get("static_path") }),
- ])
+ ] + authentication_handlers)
# location.ipfire.org
self.add_handlers(r"location\.([a-z]+\.dev\.)?ipfire\.org", [
from . import ui_modules
class CreateHandler(base.AnalyticsMixin, base.BaseHandler):
- MODES = ("paste", "upload")
-
+ @tornado.web.authenticated
def get(self):
- mode = self.get_argument("mode", "paste")
- if not mode in self.MODES:
- raise tornado.web.HTTPError(400)
-
- self.render("nopaste/create.html", mode=mode,
- max_size=self._max_size)
+ self.render("nopaste/create.html")
+ @tornado.web.authenticated
@base.ratelimit(minutes=15, requests=5)
def post(self):
- mode = self.get_argument("mode")
- if not mode in self.MODES:
- raise tornado.web.HTTPError(400)
-
- mimetype = "text/plain"
-
- if mode == "paste":
- subject = self.get_argument("subject", None)
- content = self.get_argument("content", "").encode("utf-8")
-
- elif mode == "upload":
- for f in self.request.files.get("file"):
- subject = f.filename
- content = f.body
- mimetype = f.content_type
- break
-
- # Check maximum size
- if len(content) > self._max_size:
- raise tornado.web.HTTPError(400,
- "You cannot upload more than %s bytes" % self._max_size)
-
- expires = self.get_argument("expires", "0")
- try:
- expires = int(expires)
- except (TypeError, ValueError):
- expires = None
-
- paste = self.backend.nopaste.create(content, subject=subject, mimetype=mimetype,
- expires=expires, account=self.current_user, address=self.get_remote_ip())
-
- # Redirect the user
- return self.redirect("/view/%s" % paste.uuid)
+ subject = self.get_argument("subject", None)
+ content = self.get_argument("content")
- @property
- def _max_size(self):
- # Authenticated users are allowed to upload up to 25MB
- if self.current_user:
- return 25 * (1024 ** 2)
+ # Fetch expires time
+ expires = self.get_argument_int("expires", "0")
- # The rest is only allowed to upload up to 2MB
- return 2 * (1024 ** 2)
+ with self.db.transaction():
+ paste = self.backend.nopaste.create(content, subject=subject, expires=expires,
+ account=self.current_user, address=self.get_remote_ip())
+
+ # Redirect to the paste
+ return self.redirect("/view/%s" % paste.uuid)
class RawHandler(base.AnalyticsMixin, base.BaseHandler):