2017-12-18 00:32:29 -05:00
|
|
|
import json
|
2017-11-03 05:45:29 -04:00
|
|
|
from django.http import HttpResponse
|
|
|
|
from django.urls import reverse
|
2017-11-08 21:55:44 -05:00
|
|
|
from django.utils.decorators import method_decorator
|
|
|
|
from django.views import View
|
2017-11-03 05:45:29 -04:00
|
|
|
from django.views.decorators.csrf import csrf_exempt
|
|
|
|
from urllib.parse import urljoin
|
|
|
|
|
2017-11-06 05:08:02 -05:00
|
|
|
from entries.jobs import ping_hub, send_mentions
|
2017-11-19 19:19:08 -05:00
|
|
|
from entries.models import Cat, Entry
|
2017-11-12 23:55:34 -05:00
|
|
|
from entries.kinds import Article, Note, Reply, Like, Repost
|
2017-11-03 05:45:29 -04:00
|
|
|
from lemoncurry import utils
|
|
|
|
from lemonauth import tokens
|
|
|
|
|
|
|
|
|
2017-12-18 00:32:29 -05:00
|
|
|
def form_to_mf2(request):
|
2017-12-17 19:56:04 -05:00
|
|
|
properties = {}
|
2017-12-18 00:32:29 -05:00
|
|
|
post = request.POST
|
2017-12-17 19:56:04 -05:00
|
|
|
for key in post.keys():
|
|
|
|
if key.endswith('[]'):
|
|
|
|
key = key[:-2]
|
|
|
|
if key == 'access_token':
|
|
|
|
continue
|
|
|
|
properties[key] = post.getlist(key) + post.getlist(key + '[]')
|
|
|
|
|
|
|
|
type = []
|
|
|
|
if 'h' in properties:
|
|
|
|
type = ['h-' + p for p in properties['h']]
|
|
|
|
del properties['h']
|
|
|
|
return {'type': type, 'properties': properties}
|
|
|
|
|
|
|
|
|
2017-11-08 21:55:44 -05:00
|
|
|
@method_decorator(csrf_exempt, name='dispatch')
|
|
|
|
class MicropubView(View):
|
|
|
|
def post(self, request):
|
2017-12-17 17:51:06 -05:00
|
|
|
token = tokens.auth(request)
|
|
|
|
if hasattr(token, 'content'):
|
|
|
|
return token
|
2017-11-08 21:55:44 -05:00
|
|
|
|
2017-12-18 00:32:29 -05:00
|
|
|
normalise = {
|
|
|
|
'application/json': json.load,
|
|
|
|
'application/x-www-form-urlencoded': form_to_mf2,
|
|
|
|
}
|
|
|
|
if request.content_type not in normalise:
|
|
|
|
return HttpResponse(
|
|
|
|
'unsupported request type {0}'.format(request.content_type),
|
|
|
|
content_type='text/plain',
|
|
|
|
status=415,
|
|
|
|
)
|
|
|
|
body = normalise[request.content_type](request)
|
|
|
|
if 'type' not in body:
|
|
|
|
return utils.bad_req('mf2 object type required')
|
|
|
|
if body['type'] != ['h-entry']:
|
|
|
|
return utils.bad_req('only h-entry supported')
|
|
|
|
|
2017-12-17 17:51:06 -05:00
|
|
|
entry = Entry(author=token.user)
|
2017-12-18 00:32:29 -05:00
|
|
|
props = body.get('properties', {})
|
2017-11-08 21:55:44 -05:00
|
|
|
kind = Note
|
2017-12-18 00:32:29 -05:00
|
|
|
if 'name' in props:
|
|
|
|
entry.name = '\n'.join(props['name'])
|
2017-11-08 21:55:44 -05:00
|
|
|
kind = Article
|
2017-12-18 00:32:29 -05:00
|
|
|
if 'content' in props:
|
|
|
|
entry.content = '\n'.join(props['content'])
|
|
|
|
if 'in-reply-to' in props:
|
|
|
|
entry.in_reply_to = props['in-reply-to']
|
2017-11-12 23:55:34 -05:00
|
|
|
kind = Reply
|
2017-12-18 00:32:29 -05:00
|
|
|
if 'like-of' in props:
|
|
|
|
entry.like_of = props['like-of']
|
2017-11-12 23:55:34 -05:00
|
|
|
kind = Like
|
2017-12-18 00:32:29 -05:00
|
|
|
if 'repost-of' in props:
|
|
|
|
entry.repost_of = props['repost-of']
|
2017-11-12 23:55:34 -05:00
|
|
|
kind = Repost
|
2017-11-08 21:55:44 -05:00
|
|
|
|
2017-12-18 00:32:29 -05:00
|
|
|
cats = [Cat.objects.from_name(c) for c in props.get('category', [])]
|
2017-11-19 19:19:08 -05:00
|
|
|
|
2017-11-08 21:55:44 -05:00
|
|
|
entry.kind = kind.id
|
|
|
|
entry.save()
|
2017-11-19 19:19:08 -05:00
|
|
|
entry.cats = cats
|
|
|
|
entry.save()
|
2017-11-08 21:55:44 -05:00
|
|
|
|
|
|
|
base = utils.origin(request)
|
|
|
|
perma = urljoin(base, entry.url)
|
2017-11-19 19:21:28 -05:00
|
|
|
others = [urljoin(base, url) for url in (
|
2017-11-08 21:55:44 -05:00
|
|
|
reverse('home:index'),
|
|
|
|
reverse('entries:atom'),
|
|
|
|
reverse('entries:rss'),
|
|
|
|
reverse('entries:' + kind.index),
|
|
|
|
reverse('entries:' + kind.atom),
|
|
|
|
reverse('entries:' + kind.rss),
|
2017-11-19 19:21:28 -05:00
|
|
|
)] + [urljoin(base, cat.url) for cat in cats]
|
2017-11-08 21:55:44 -05:00
|
|
|
ping_hub.delay(perma, *others)
|
|
|
|
send_mentions.delay(perma)
|
|
|
|
|
|
|
|
res = HttpResponse(status=201)
|
|
|
|
res['Location'] = perma
|
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
|
|
micropub = MicropubView.as_view()
|