src/web/handlers_fireinfo.py \
src/web/handlers_iuse.py \
src/web/handlers_mirrors.py \
- src/web/handlers_nopaste.py \
src/web/location.py \
src/web/newsletter.py \
+ src/web/nopaste.py \
src/web/people.py \
src/web/ui_modules.py
templates_newsletterdir = $(templatesdir)/newsletter
+templates_nopaste_DATA = \
+ src/templates/nopaste/create.html \
+ src/templates/nopaste/view.html
+
+templates_nopastedir = $(templatesdir)/nopaste
+
templates_people_DATA = \
src/templates/people/base.html \
src/templates/people/conferences.html \
if account:
uid = account.uid
- # Escape any backslashes. PostgreSQL tends to think that they lead octal
- # values or something that confuses the convertion from text to bytea.
if type == "text":
- content = content.replace("\\", "\\\\")
mimetype = "text/plain"
elif type == "file":
- content = buffer(content)
mimetype = self._guess_mimetype(content)
# http://blog.00null.net/easily-generating-random-strings-in-postgresql/
# Return the mime type
ms.setflags(magic.MAGIC_MIME_TYPE)
- buf = "%s" % buf
-
try:
return ms.buffer(buf)
finally:
WHERE uuid = %s", uuid)
if res:
- return res.content
+ return bytes(res.content)
def _update_lastseen(self, uuid):
self.db.execute("UPDATE nopaste SET time_lastseen = NOW(), views = views + 1 \
<div class="container d-flex justify-content-between">
© {{ year }} - {{ _("IPFire is free software written by the IPFire Project") }}
- {% if not current_user and hostname in ("blog.ipfire.org") %}
+ {% if not current_user and hostname in ("blog.ipfire.org", "nopaste.ipfire.org") %}
<a href="/login">{{ _("Login") }}</a>
{% elif current_user %}
<span>
{% end %}
{% end block %}
-{% block container %}
+{% block content %}
+ <div class="row justify-content-center">
+ <div class="col-12 col-md-8">
+ {% if mode == "paste" %}
+ <h1>{{ _("New Paste") }}</h2>
+ {% elif mode == "upload" %}
+ <h1>{{ _("Upload File") }}</h3>
+ {% end %}
-<div class="container">
- <section class="features-content col-12">
- {% if mode == "paste" %}
- <h2 class="display-2 text-center">{{ _("New Paste") }}</h2>
- {% elif mode == "upload" %}
- <h2 class="display-2 text-center">{{ _("Upload File") }}</h3>
- {% end %}
-
- <div class="row">
- <div class="col">
- <form class="form-horizontal" action="" method="POST" enctype="multipart/form-data">
+ <form class="form-horizontal" action="" method="POST" enctype="multipart/form-data">
+ {% raw xsrf_form_html() %}
+
+ <input type="hidden" name="mode" value="{{ mode }}">
+
+ {% if mode == "paste" %}
<div class="form-group">
- <input type="hidden" name="mode" value="{{ mode }}">
-
- {% if mode == "paste" %}
- <div class="col">
- <textarea class="form-control" rows="12" name="content"
- placeholder="{{ _("Please paste your content here...") }}"></textarea>
- </div>
- {% elif mode == "upload" %}
- <label for="inputFile" class="col-2 control-label">{{ _("File") }}</label>
- <div class="col-10">
- <input type="file" id="inputFile" name="file">
-
- {% if max_size %}
- <p class="help-block">
- {{ _("You may upload up to %s.") % format_size(max_size) }}
- </p>
- {% end %}
- </div>
- {% end %}
+ <label>{{ _("Subject") }}</label>
+ <input type="text" class="form-control" name="subject"
+ placeholder="{{ _("Subject") }} ({{ _("optional") }})">
</div>
-
+ {% end %}
+
+ <div class="form-group">
{% if mode == "paste" %}
- <div class="form-group">
- <label for="inputSubject" class="col-2 control-label">{{ _("Subject") }}</label>
- <div class="col-10">
- <input type="subject" class="form-control" id="inputSubject"
- name="subject" placeholder="{{ _("Subject") }} ({{ _("optional") }})">
- </div>
- </div>
+ <textarea class="form-control" rows="12" name="content"
+ placeholder="{{ _("Please paste your content here...") }}"></textarea>
+ {% elif mode == "upload" %}
+ <label>{{ _("File") }}</label>
+ <input type="file" name="file" class="form-control-file">
+
+ {% if max_size %}
+ <small class="form-text text-muted">
+ {{ _("You may upload up to %s") % format_size(max_size) }}
+ </small>
+ {% end %}
{% end %}
-
- <div class="form-group">
- <label for="inputExpires" class="col-2 control-label">{{ _("Expires") }}</label>
- <div class="col-10">
- <select class="form-control" id="inputExpires" name="expires">
- <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 class="form-group">
- <div class="col-10">
- <button type="submit" class="btn btn-primary">{{ _("Submit") }}</button>
- </div>
- </div>
-
- {% raw xsrf_form_html() %}
- </form>
- </div>
- </div>
- </section>
-</div>
+ </div>
+ <div class="form-group">
+ <label>{{ _("Expires") }}</label>
+
+ <select class="form-control" name="expires">
+ <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>
+
+ <button type="submit" class="btn btn-primary btn-block">{{ _("Submit") }}</button>
+ </form>
+ </div>
+ </div>
{% end block %}
{% block title %}{{ entry.subject or _("Paste %s") % entry.uuid }}{% end block %}
-{% block container %}
- <section class="container content-section">
- <div class="page-header">
- <h3 class="text-center">{{ entry.subject or _("Paste %s") % entry.uuid }}</h3>
- </div>
-
- {% if content %}
- <pre class="prettyprint linenums" style="min-height: 25em">{{ content }}</pre>
+{% block content %}
+ <div class="row justify-content-center">
+ <div class="col col-md-10">
+ <div class="card">
+ <div class="card-body">
+ <h3 class="card-title mb-1">{{ entry.subject or _("Paste %s") % entry.uuid }}</h3>
+ <h6 class="card-subtitle text-muted mb-3">
+ {{ _("Uploaded %s") % locale.format_date(entry.time_created) }}
- <link rel="stylesheet" href="{{ static_url("css/prettify.css") }}">
- <script src="{{ static_url("js/prettify.js") }}"></script>
- <script>prettyPrint()</script>
- {% else %}
- <div class="ac">
- <br><br>
+ {% if entry.account %}
+ {{ _("by") }}
- <a class="btn btn-primary btn-lg" href="/raw/{{ entry.uuid }}">
- <span class="glyphicon glyphicon-download"></span>
- {{ _("Download File") }}
- </a>
+ <img src="{{ entry.account.avatar_url(14) }}" alt="{{ entry.account }}">
- <p class="text-muted">
- {{ _("Filesize: %s") % format_size(entry.size) }}
- </p>
+ <a href="https://people.ipfire.org/users/{{ entry.account.uid }}">
+ {{ entry.account }}
+ </a>,
+ {% else %}
+ {{ _("from %s") % entry.address }},
+ {% end %}
- <br><br>
- </div>
+ {{ _("One View", "%(num)s Views", entry.views) % { "num" : entry.views } }}
+ </h6>
- <hr>
- {% end %}
+ <div class="row mb-1">
+ <div class="col-12 text-md-right">
+ {% if content %}
+ <a class="btn btn-primary mr-2 mb-2" href="/raw/{{ entry.uuid }}">
+ <span class="fas fa-file-download mr-2"></span>
+ {{ _("Download") }}
+ </a>
+ {% end %}
- <div class="row">
- <div class="col-md-6">
- <dl class="dl-horizontal">
- {% if entry.account %}
- <dt>{{ _("Uploaded by") }}</dt>
- <dd>
- <img src="{{ entry.account.avatar_url(14) }}" alt="{{ entry.account.name }}">
- {{ entry.account.name }}
- </dd>
- {% elif current_user and entry.address %}
- <dt>{{ _("Uploaded from") }}</dt>
- <dd>{{ entry.address }}</dd>
- {% end %}
+ <a class="btn btn-warning mb-2" href="mailto:abuse@ipfire.org?subject={{ "nopaste.ipfire.org: %s" % entry.uuid }}">
+ <span class="fas fa-exclamation-triangle mr-2"></span>
+ {{ _("Report abuse") }}
+ </a>
+ </div>
+ </div>
- <dt>{{ _("Created") }}</dt>
- <dd>{{ locale.format_date(entry.time_created) }}</dd>
+ <hr>
- <dt>{{ _("Views") }}</dt>
- <dd>{{ entry.views }}</dd>
+ {% if content %}
+ <pre class="prettyprint linenums" style="min-height: 25em">{{ content }}</pre>
- <dt>{{ _("Expires") }}</dt>
- <dd>
- {% if entry.time_expires %}
- {{ locale.format_date(entry.time_expires) }}
- {% else %}
- {{ _("never") }}
- {% end %}
- </dd>
- </dl>
- </div>
+ <link rel="stylesheet" href="{{ static_url("css/prettify.css") }}">
+ <script src="{{ static_url("js/prettify.js") }}"></script>
+ <script>prettyPrint()</script>
- <div class="col-md-6 ar">
- <ul class="list-inline">
- <li>
- <span class="glyphicon glyphicon-link"></span>
- <a href="/view/{{ entry.uuid }}">{{ _("Link") }}</a>
- </li>
- <li>
- <span class="glyphicon glyphicon-download"></span>
- <a href="/raw/{{ entry.uuid }}">{{ _("Download") }}</a>
- </li>
- <li>
- <span class="glyphicon glyphicon-alert text-warning"></span>
- <a class="text-warning" href="mailto:abuse@ipfire.org?subject={{ "nopaste.ipfire.org: %s" % entry.uuid }}">
- {{ _("Report abuse") }}
- </a>
- </li>
- </ul>
+ {% elif entry.mimetype.startswith("image/") %}
+ <img class="img-fluid" src="/raw/{{ entry.uuid }}">
+ {% else %}
+ <div class="row justify-content-center my-5">
+ <div class="col-12 col-md-6 text-center">
+ <a class="btn btn-primary btn-lg btn-block" href="/raw/{{ entry.uuid }}">
+ <span class="fas fa-file-download"></span>
+ {{ _("Download") }} ({{ format_size(entry.size) }})
+ </a>
+ </div>
+ </div>
+ {% end %}
+ </div>
</div>
</div>
- </section>
+ </div>
{% end block %}
from . import download
from . import location
from . import newsletter
+from . import nopaste
from . import people
from . import ui_modules
# nopaste.ipfire.org
self.add_handlers(r"nopaste(\.dev)?\.ipfire\.org", [
- (r"/", NopasteCreateHandler),
- (r"/raw/(.*)", NopasteRawHandler),
- (r"/view/(.*)", NopasteViewHandler),
+ (r"/", nopaste.CreateHandler),
+ (r"/raw/(.*)", nopaste.RawHandler),
+ (r"/view/(.*)", nopaste.ViewHandler),
] + authentication_handlers)
# location.ipfire.org
import tornado.web
-from .handlers_base import *
+from . import handlers_base as base
-class NopasteCreateHandler(BaseHandler):
+class CreateHandler(base.BaseHandler):
MODES = ("paste", "upload")
def get(self):
@property
def _max_size(self):
- # Authenticated users are allowed to upload up to 10MB
+ # Authenticated users are allowed to upload up to 25MB
if self.current_user:
return 25 * (1024 ** 2)
return 2 * (1024 ** 2)
-class NopasteRawHandler(BaseHandler):
+class RawHandler(base.BaseHandler):
def get(self, uid):
entry = self.backend.nopaste.get(uid)
if not entry:
self.set_header("Content-Type", entry.mimetype)
# Set expiry headers
- expires = entry.time_expires or \
- (datetime.datetime.utcnow() + datetime.timedelta(days=30))
-
- # For HTTP/1.0
- self.set_header("Expires", expires)
-
- # For HTTP/1.1
- max_age = expires - datetime.datetime.utcnow()
- self.set_header("Cache-Control", "public,max-age=%d" % max_age.total_seconds())
+ self.set_expires(3600)
# Send content
content = self.backend.nopaste.get_content(entry.uuid)
self.finish(content)
-class NopasteViewHandler(BaseHandler):
+class ViewHandler(base.BaseHandler):
def get(self, uid):
entry = self.backend.nopaste.get(uid)
if not entry: