Skip to content

Commit

Permalink
Merge pull request #9 from kapsh/descriptions
Browse files Browse the repository at this point in the history
Add description field into API and web interface
  • Loading branch information
supakeen committed Jul 9, 2019
2 parents 43b18cb + e5efeec commit bade152
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 14 deletions.
26 changes: 26 additions & 0 deletions README.rst
Expand Up @@ -27,6 +27,32 @@ Prerequisites
Usage
=====

Enter text, click "Paste". Easy enough.

Using API is slightly more difficult but certainly recommended for programmatic usage.
``pinnwand`` accepts HTTP POST requests to ``/json/new`` with following body:

::

{
"code": "text to send",
"lexer": "text",
"expiry": "1day",
"filename": "source.txt"
}

``filename`` is optional here.

API will return JSON response with full URL for convenience and ``paste_id, removal_id`` keys.
Use first one to query existing records by GET request to ``/json/show/paste_id``.

To remove existing paste send POST request to ``/json/remove`` with data

::

{"removal_id": <removal_id>}


Reporting bugs
==============
Bugs are reported best at ``pinnwand``'s `project page`_ on github.
Expand Down
10 changes: 8 additions & 2 deletions pinnwand/database.py
Expand Up @@ -3,6 +3,7 @@
import os
import base64
import contextlib
from typing import Optional

import pygments.lexers
import pygments.formatters
Expand All @@ -27,7 +28,7 @@ def session() -> Session:

try:
yield a_session
except:
except Exception:
a_session.rollback()
raise
finally:
Expand Down Expand Up @@ -65,6 +66,8 @@ class Paste(Base): # type: ignore

exp_date = Column(DateTime)

filename = Column(String(250))

def create_hash(self) -> str:
# This should organically grow as more is used, probably depending
# on how often collissions occur.
Expand All @@ -82,7 +85,8 @@ def __init__(
raw: str,
lexer: str = "text",
expiry: datetime.timedelta = datetime.timedelta(days=7),
src: str = "web",
src: Optional[str] = None,
filename: Optional[str] = None,
) -> None:
self.pub_date = datetime.datetime.utcnow()
self.chg_date = datetime.datetime.utcnow()
Expand All @@ -97,6 +101,8 @@ def __init__(

self.src = src

self.filename = filename

self.lexer = lexer

lexer = pygments.lexers.get_lexer_by_name(lexer)
Expand Down
34 changes: 23 additions & 11 deletions pinnwand/http.py
@@ -1,12 +1,11 @@
import json
import logging
from urllib.parse import urljoin

import tornado.web
from tornado.escape import url_escape

from pinnwand import database
from pinnwand import utility
from pinnwand import path

from pinnwand import database, path, utility

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -61,7 +60,7 @@ async def post(self) -> None:
log.info("Paste.post: a paste was submitted with an invalid expiry")
raise tornado.web.HTTPError(400)

paste = database.Paste(raw, lexer, utility.expiries[expiry])
paste = database.Paste(raw, lexer, utility.expiries[expiry], "web")

with database.session() as session:
session.add(paste)
Expand Down Expand Up @@ -104,7 +103,7 @@ async def get(self, paste_id: str) -> None:
self.render(
"show.html",
paste=paste,
pagetitle="show",
pagetitle=paste.filename or "show",
can_delete=can_delete,
linenos=False,
)
Expand Down Expand Up @@ -174,6 +173,7 @@ async def get(self, paste_id: str) -> None:
"fmt": paste.fmt,
"lexer": paste.lexer,
"expiry": paste.exp_date.isoformat(),
"filename": paste.filename,
}
)

Expand All @@ -183,6 +183,7 @@ async def post(self) -> None:
lexer = self.get_body_argument("lexer")
raw = self.get_body_argument("code")
expiry = self.get_body_argument("expiry")
filename = self.get_body_argument("filename", None)

if not raw:
log.info("APINew.post: a paste was submitted without content")
Expand All @@ -198,14 +199,25 @@ async def post(self) -> None:
)
raise tornado.web.HTTPError(400)

paste = database.Paste(raw, lexer, utility.expiries[expiry])
paste = database.Paste(
raw, lexer, utility.expiries[expiry], "api", filename
)

with database.session() as session:
session.add(paste)
session.commit()

req_url = self.request.full_url()
location = paste.paste_id
if filename:
location += "#" + url_escape(filename)
self.write(
{"paste_id": paste.paste_id, "removal_id": paste.removal_id}
{
"paste_id": paste.paste_id,
"removal_id": paste.removal_id,
"paste_url": urljoin(req_url, f"/show/{location}"),
"raw_url": urljoin(req_url, f"/raw/{location}"),
}
)


Expand Down Expand Up @@ -276,15 +288,15 @@ def make_application() -> tornado.web.Application:
[
(r"/", CreatePaste),
(r"/\+(.*)", CreatePaste),
(r"/show/(.*)", ShowPaste),
(r"/raw/(.*)", RawPaste),
(r"/show/(.*)(?:#.+)?", ShowPaste),
(r"/raw/(.*)(?:#.+)?", RawPaste),
(r"/remove/(.*)", RemovePaste),
(r"/about", AboutPage),
(r"/removal", RemovalPage),
(r"/expiry", ExpiryPage),
(r"/json/new", APINew),
(r"/json/remove", APIRemove),
(r"/json/show/(.*)", APIShow),
(r"/json/show/(.*)(?:#.+)?", APIShow),
(r"/json/lexers", APILexers),
(r"/json/expiries", APIExpiries),
(
Expand Down
2 changes: 1 addition & 1 deletion pinnwand/template/new.html
Expand Up @@ -24,4 +24,4 @@
</select>
</div>
</form>
{% end %}
{% end %}
5 changes: 5 additions & 0 deletions pinnwand/template/show.html
Expand Up @@ -17,5 +17,10 @@
{% end %}
Pasted through <em>{{ paste.src }}</em>.
</p>
{% if paste.filename %}
<p>
Source: <span>{{ paste.filename }}</span>
</p>
{% end %}
</div>
{% end %}
22 changes: 22 additions & 0 deletions test/test_http.py
Expand Up @@ -85,6 +85,28 @@ def test_api_new_wrong_method(self) -> None:
response = self.fetch("/json/new")
assert response.code == 405

def test_api_return_filename(self) -> None:
response = self.fetch(
"/json/new",
method="POST",
body=urllib.parse.urlencode(
{
"lexer": "python",
"code": "foo",
"expiry": "1day",
"filename": "example.py",
}
),
)

assert response.code == 200
data = json.loads(response.body)

response = self.fetch(f"/json/show/{data['paste_id']}")
data = json.loads(response.body)

assert data["filename"] == "example.py"

def test_api_show(self) -> None:
response = self.fetch(
"/json/new",
Expand Down

0 comments on commit bade152

Please sign in to comment.