]> git.ipfire.org Git - ipfire.org.git/commitdiff
nopaste: Create an extra object for pastes
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 22 Feb 2024 18:50:07 +0000 (18:50 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 22 Feb 2024 18:50:07 +0000 (18:50 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/backend/nopaste.py
src/web/nopaste.py

index 42b5fab92147ff09fd6e29a990a3c08528c4afa7..1d7ecad01faefdd656c3328471857c88be1b061f 100644 (file)
@@ -10,6 +10,7 @@ import tornado.tcpserver
 
 from . import base
 from .misc import Object
+from .decorators import *
 
 # Setup logging
 log = logging.getLogger(__name__)
@@ -17,6 +18,9 @@ log = logging.getLogger(__name__)
 CHUNK_SIZE = 1024 ** 2
 
 class Nopaste(Object):
+       def _get_paste(self, query, *args, **kwargs):
+               return self.db.fetch_one(Paste, query, *args, **kwargs)
+
        def create(self, content, subject=None, mimetype=None, expires=None, account=None, address=None):
                self._cleanup_database()
 
@@ -35,7 +39,7 @@ class Nopaste(Object):
                        expires = datetime.datetime.utcnow() + datetime.timedelta(seconds=expires)
 
                # http://blog.00null.net/easily-generating-random-strings-in-postgresql/
-               res = self.db.get("""
+               paste = self._get_paste("""
                        INSERT INTO
                                nopaste
                        (
@@ -54,12 +58,30 @@ class Nopaste(Object):
                                random_slug(), %s, %s, %s, %s, %s, %s, %s, %s
                        )
                        RETURNING
-                               uuid
+                               *
                        """, subject, content, expires or None, address, uid, mimetype, len(content), blob_id,
                )
 
-               if res:
-                       return res.uuid
+               # Log result
+               log.info("Created a new paste (%s) of %s byte(s) from %s (%s - %s)" % (
+                       paste.uuid, paste.size, paste.address, paste.asn or "N/A", paste.country or "N/A",
+               ))
+
+               return paste
+
+       def _fetch_blob(self, id):
+               blob = self.db.get("""
+                       SELECT
+                               data
+                       FROM
+                               nopaste_blobs
+                       WHERE
+                               id = %s
+                       """, id,
+               )
+
+               if blob:
+                       return blob.data
 
        def _store_blob(self, data):
                """
@@ -90,20 +112,22 @@ class Nopaste(Object):
                return blob.id
 
        def get(self, uuid):
-               res = self.db.get("SELECT uuid, subject, time_created, time_expires, address, uid, \
-                       mimetype, views, size FROM nopaste WHERE uuid = %s AND (CASE WHEN time_expires \
-                       IS NULL THEN TRUE ELSE NOW() < time_expires END)", uuid)
-
-               if res:
-                       # Get the account that uploaded this if available
-                       res.account = None
-                       if res.uid:
-                               res.account = self.backend.accounts.get_by_uid(res.uid)
-
-                       # Touch the entry so it won't be deleted when it is still used
-                       self._update_lastseen(uuid)
+               paste = self._get_paste("""
+                       SELECT
+                               *
+                       FROM
+                               nopaste
+                       WHERE
+                               uuid = %s
+                       AND (
+                               expires_at >= CURRENT_TIMESTAMP
+                       OR
+                               expires_at IS NULL
+                       )
+                       """, uuid,
+               )
 
-               return res
+               return paste
 
        def get_content(self, uuid):
                res = self.db.get("SELECT content FROM nopaste \
@@ -171,6 +195,12 @@ class Paste(Object):
        def size(self):
                return self.data.size
 
+       # MIME Type
+
+       @property
+       def mimetype(self):
+               return self.data.mimetype or "application/octet-stream"
+
        # Address
 
        @property
@@ -197,6 +227,12 @@ class Paste(Object):
                if self.location and self.location.country_code:
                        return self.backend.location.get_country(self.location.country_code)
 
+       # Legacy
+
+       @property
+       def account(self):
+               return None
+
 
 class Service(tornado.tcpserver.TCPServer):
        def __init__(self, config, **kwargs):
index cfedc9c31b9433bc270739f491b67357df9102de..4791e9b9b6765075959e0f54938e757b64d3c2d1 100644 (file)
@@ -46,13 +46,11 @@ class CreateHandler(base.AnalyticsMixin, base.BaseHandler):
                except (TypeError, ValueError):
                        expires = None
 
-               uid = self.backend.nopaste.create(content, subject=subject, mimetype=mimetype,
+               paste = self.backend.nopaste.create(content, subject=subject, mimetype=mimetype,
                        expires=expires, account=self.current_user, address=self.get_remote_ip())
 
-               if uid:
-                       return self.redirect("/view/%s" % uid)
-
-               raise tornado.web.HTTPError(500)
+               # Redirect the user
+               return self.redirect("/view/%s" % paste.uuid)
 
        @property
        def _max_size(self):