#!/usr/bin/python3
+import asyncio
import datetime
+import io
+import logging
import magic
+import tornado.iostream
+import tornado.tcpserver
+from . import base
from .misc import Object
+# Setup logging
+log = logging.getLogger(__name__)
+
+CHUNK_SIZE = 1024 ** 2
+
class Nopaste(Object):
def create(self, content, subject=None, mimetype=None, expires=None, account=None, address=None):
self._cleanup_database()
WHEN time_expires IS NULL \
THEN time_lastseen + INTERVAL '6 months' <= NOW() \
ELSE NOW() >= time_expires END)")
+
+
+class Paste(Object):
+ def init(self, id, data):
+ self.id, self.data = id, data
+
+ # UUID
+
+ @property
+ def uuid(self):
+ return self.data.uuid
+
+ # Subject
+
+ @property
+ def subject(self):
+ return self.data.subject
+
+ # Created At
+
+ @property
+ def created_at(self):
+ return self.data.created_at
+
+ time_created = created_at
+
+ # Expires At
+
+ @property
+ def expires_at(self):
+ return self.data.expires_at
+
+ time_expires = expires_at
+
+ # Blob
+
+ @lazy_property
+ def blob(self):
+ return self.backend.nopaste._fetch_blob(self.data.blob_id)
+
+ content = blob
+
+ # Size
+
+ @property
+ def size(self):
+ return self.data.size
+
+ # Address
+
+ @property
+ def address(self):
+ return self.data.address
+
+ # Location
+
+ @lazy_property
+ def location(self):
+ return self.backend.location.lookup("%s" % self.address)
+
+ # ASN
+
+ @lazy_property
+ def asn(self):
+ if self.location and self.location.asn:
+ return self.backend.location.get_asn(self.location.asn)
+
+ # Country
+
+ @lazy_property
+ def country(self):
+ if self.location and self.location.country_code:
+ return self.backend.location.get_country(self.location.country_code)
+
+
+class Service(tornado.tcpserver.TCPServer):
+ def __init__(self, config, **kwargs):
+ # Initialize backend
+ self.backend = base.Backend(config)
+
+ super().__init__(**kwargs)
+
+ async def handle_stream(self, stream, address):
+ buffer = io.BytesIO()
+
+ # Read the entire stream
+ try:
+ while True:
+ chunk = await stream.read_bytes(CHUNK_SIZE, partial=True)
+
+ log.debug("Read a chunk of %s byte(s)" % len(chunk))
+
+ # Write the chunk into the buffer
+ buffer.write(chunk)
+
+ # If we have read less then we have reached the end
+ if len(chunk) < CHUNK_SIZE:
+ break
+
+ # End if the stream closed unexpectedly
+ except tornado.iostream.StreamClosedError as e:
+ return
+
+ log.debug("Finished reading payload")
+
+ # Process address
+ address, port = address
+
+ # Store this into the database
+ with self.backend.db.transaction():
+ uuid = self.backend.nopaste.create(
+ buffer.getvalue(),
+ subject="Streamed Upload",
+ address=address,
+ )
+
+ # Format a response message
+ message = "https://nopaste.ipfire.org/view/%s\n" % uuid
+
+ # Send the message
+ await stream.write(message.encode("utf-8"))
+
+ # We are done, close the stream
+ stream.close()
tornado.options.define("debug", type=bool, default=False, help="Enable debug mode")
tornado.options.define("port", type=int, default=8001, help="Port to listen on")
+import ipfire.nopaste
from ipfire.web import Application
async def run():
debug=tornado.options.options.debug)
app.listen(tornado.options.options.port, xheaders=True)
+ # Initialize the nopaste service
+ nopaste = ipfire.nopaste.Service("@configsdir@/@PACKAGE_NAME@.conf")
+ nopaste.listen(tornado.options.options.port + 1000)
+
# Wait for forever
await asyncio.Event().wait()