コード例 #1
0
ファイル: main.py プロジェクト: bear/kaku
def handleMedia():
    # https://www.w3.org/TR/2016/CR-micropub-20160816/#media-endpoint
    current_app.logger.info('handleMedia [%s]' % request.method)
    me, client_id, scope, allowed = validateAccessToken(request.headers.get('Authorization'))
    if not allowed:
        return 'Not allowed', 401
    domain = baseDomain(me, includeScheme=False)
    if request.method == 'POST' and validateDomain(domain):
        item     = request.files.get('file')
        filename = secure_filename(item.filename)

        # TODO replace this with a plugin callable to retrieve what the file path and url should be
        item.save(os.path.join(current_app.config['MEDIA_FILES'], filename))
        location = '%s%s%s/%s' % (current_app.config['BASEURL'],
                                  current_app.config['BASEROUTE'],
                                  current_app.config['MEDIA_DIR'],
                                  filename)
        return ('Media successful for %s' % location, 201, {'Location': location})
    else:
        return 'Invalid request', 400
コード例 #2
0
def handleMedia():
    # https://www.w3.org/TR/2016/CR-micropub-20160816/#media-endpoint
    current_app.logger.info('handleMedia [%s]' % request.method)
    me, client_id, scope, allowed = validateAccessToken(
        request.headers.get('Authorization'))
    if not allowed:
        return 'Not allowed', 401
    domain = baseDomain(me, includeScheme=False)
    if request.method == 'POST' and validateDomain(domain):
        item = request.files.get('file')
        filename = secure_filename(item.filename)

        # TODO replace this with a plugin callable to retrieve what the file path and url should be
        item.save(os.path.join(current_app.config['MEDIA_FILES'], filename))
        location = '%s%s%s/%s' % (current_app.config['BASEURL'],
                                  current_app.config['BASEROUTE'],
                                  current_app.config['MEDIA_DIR'], filename)
        return ('Media successful for %s' % location, 201, {
            'Location': location
        })
    else:
        return 'Invalid request', 400
コード例 #3
0
def handleMicroPub():
    current_app.logger.info('handleMicroPub [%s]' % request.method)
    me, client_id, scope, allowed = validateAccessToken(
        request.headers.get('Authorization'))
    if not allowed:
        return 'Not allowed', 401
    domain = baseDomain(me, includeScheme=False)
    if request.method == 'POST' and validateDomain(domain):
        data = {
            'domain': domain,
            'app': client_id,
            'scope': scope,
        }
        payload = request.get_json()
        properties = {
            'type': 'h-entry',
            'action': 'create',
        }
        for _key in _property_keys:
            properties[_key] = None
        for _key in ('content', 'html', 'category', 'photo', 'photo_files'):
            properties[_key] = []

        for key in ('photo', 'photo[]'):
            items = request.files.getlist(key)
            for item in items:
                filename = secure_filename(item.filename)
                properties['photo_files'].append(filename)
                # TODO rectify why we save files here to uploads dir but media endpoint doesn't
                item.save(os.path.join(current_app.config['UPLOADS'],
                                       filename))

        # form encoded
        if payload is None:
            properties['type'] = 'h-%s' % request.form.get('h')
            for key, value in request.form.iteritems(multi=True):
                key = key.lower()
                if key == 'category':
                    properties[key].append(value)
                elif key == 'photo':
                    properties[key].append((request.form.get(key), ''))
                elif key == 'content':
                    properties[key] = request.form.get(key).replace(
                        '\r\n', '\n').split('\n')
                else:
                    properties[key] = value
                current_app.logger.info('      %s --> %s' % (key, value))

            # get any photos-as-array values
            properties['photo'] += list(
                zip(request.form.getlist('photo[value]'),
                    request.form.getlist('photo[alt]')))

            # get any categorties as array values
            for key, value in request.form.iteritems(multi=True):
                if key.lower().startswith('category['):
                    properties['category'].append(value)

            properties['html'] = request.form.getlist('content[html]')
        else:
            # json data
            if 'type' in payload:
                properties['type'] = payload['type'][0]
            if 'action' in payload:
                for key in ('action', 'url', 'replace', 'add', 'delete'):
                    if key in payload:
                        properties[key] = payload[key]
            if 'properties' in payload:
                for key in payload['properties']:
                    value = payload['properties'][key]
                    properties[key] = value
                    current_app.logger.info('      %s ==> %s' % (key, value))

            if type(properties['content']) is dict:
                if 'html' in properties['content']:
                    properties['html'] = properties['content']['html']
                    properties['content'] = []

            if 'photo' in properties:
                photos = []
                for item in properties['photo']:
                    alt = ''
                    if type(item) is dict:
                        photo = item['value']
                        if 'alt' in item:
                            alt = item['alt']
                    else:
                        photo = item
                    photos.append((photo, alt))
                properties['photo'] = photos

        data['properties'] = properties
        for key in data['properties']:
            current_app.logger.info('    %s = %s' %
                                    (key, data['properties'][key]))
        return micropub(request.method, data)
    elif request.method == 'GET':
        # https://www.w3.org/TR/2016/CR-micropub-20160816/#querying
        query = request.args.get('q')
        current_app.logger.info('query [%s]' % query)
        if query is not None:
            query = query.lower()
            respJson = {
                'media-endpoint': current_app.config['MEDIA_ENDPOINT'],
                'syndicate-to': current_app.config['SITE_SYNDICATE']
            }
            respParam = '&'.join(
                map('syndicate-to[]={0}'.format,
                    map(urllib.quote, current_app.config['SITE_SYNDICATE'])))
            respParam += '&media-endpoint=%s' % (
                current_app.config['MEDIA_ENDPOINT'])
            if query == 'config':
                # https://www.w3.org/TR/2016/CR-micropub-20160816/#configuration
                if request_wants_json:
                    resp = jsonify(respJson)
                    resp.status_code = 200
                    return resp
                else:
                    return (respParam, 200, {
                        'Content-Type': 'application/x-www-form-urlencoded'
                    })
            elif query == 'syndicate-to':
                # https://www.w3.org/TR/2016/CR-micropub-20160816/#syndication-targets
                if request_wants_json:
                    resp = jsonify(respJson)
                    resp.status_code = 200
                    return resp
                else:
                    return (respParam, 200, {
                        'Content-Type': 'application/x-www-form-urlencoded'
                    })
            elif query == 'source':
                # https://www.w3.org/TR/2016/CR-micropub-20160816/#source-content
                url = request.args.get('url')
                properties = []
                for key in ('properties', 'properties[]'):
                    item = request.args.getlist(key)
                    if len(item) > 0:
                        properties += item
                current_app.logger.info('url: %s properties: %d %s' %
                                        (url, len(properties), properties))

                # "If no properties are specified, then the response must include all properties,
                #  as well as a type property indicating the vocabulary of the post."
                # so this is a list of properties the code currently handles
                if len(properties) == 0:
                    properties = ['type', 'category', 'content', 'published']

                targetPath = urlparse(url).path
                pathItems = targetPath.split('.')
                current_app.logger.info('[%s] %s' % (targetPath, pathItems))

                # normalize the url target to remove any extension
                if pathItems[-1].lower() == 'html':
                    targetPath = '.'.join(pathItems[:-1])
                slug = targetPath.replace(current_app.config['BASEROUTE'], '')
                targetFile = '%s.json' % os.path.join(
                    current_app.config['SITE_CONTENT'], slug)
                current_app.logger.info('targetFile: %s' % targetFile)
                if os.path.exists(targetFile):
                    with open(targetFile, 'r') as h:
                        post = json.load(h)
                    respJson = {"type": ["h-entry"], "properties": {}}
                    if 'published' in properties:
                        respJson['properties']['published'] = [
                            post['published']
                        ]
                    if 'category' in properties and len(post['tags']) > 0:
                        respJson['properties']['category'] = post[
                            'tags'].split(',')
                    if 'content' in properties:
                        respJson['properties']['content'] = post[
                            'content'].split('\n')
                    current_app.logger.info(json.dumps(respJson))
                    resp = jsonify(respJson)
                    resp.status_code = 200
                    return resp
                else:
                    return 'not found', 404
            else:
                return 'not implemented', 501
        else:
            return 'not implemented', 501
    else:
        return 'not implemented', 501
コード例 #4
0
ファイル: main.py プロジェクト: bear/kaku
def handleMicroPub():
    current_app.logger.info('handleMicroPub [%s]' % request.method)
    me, client_id, scope, allowed = validateAccessToken(request.headers.get('Authorization'))
    if not allowed:
        return 'Not allowed', 401
    domain = baseDomain(me, includeScheme=False)
    if request.method == 'POST' and validateDomain(domain):
        data = { 'domain': domain,
                 'app':    client_id,
                 'scope':  scope,
               }
        payload = request.get_json()
        properties = { 'type':   'h-entry',
                       'action': 'create',
                     }
        for _key in _property_keys:
            properties[_key] = None
        for _key in ('content', 'html', 'category', 'photo', 'photo_files'):
            properties[_key] = []

        for key in ('photo', 'photo[]'):
            items = request.files.getlist(key)
            for item in items:
                filename = secure_filename(item.filename)
                properties['photo_files'].append(filename)
                # TODO rectify why we save files here to uploads dir but media endpoint doesn't
                item.save(os.path.join(current_app.config['UPLOADS'], filename))

        # form encoded
        if payload is None:
            properties['type'] = 'h-%s' % request.form.get('h')
            for key, value in request.form.iteritems(multi=True):
                key = key.lower()
                if key == 'category':
                    properties[key].append(value)
                elif key == 'photo':
                    properties[key].append((request.form.get(key), ''))
                elif key == 'content':
                    properties[key] = request.form.get(key).replace('\r\n', '\n').split('\n')
                else:
                    properties[key] = value
                current_app.logger.info('      %s --> %s' % (key, value))

            # get any photos-as-array values
            properties['photo'] += list(zip(request.form.getlist('photo[value]'),
                                            request.form.getlist('photo[alt]')))

            # get any categorties as array values
            for key, value in request.form.iteritems(multi=True):
                if key.lower().startswith('category['):
                    properties['category'].append(value)

            properties['html'] = request.form.getlist('content[html]')
        else:
            # json data
            if 'type' in payload:
                properties['type'] = payload['type'][0]
            if 'action' in payload:
                for key in ('action', 'url', 'replace', 'add', 'delete'):
                    if key in payload:
                        properties[key] = payload[key]
            if 'properties' in payload:
                for key in payload['properties']:
                    value           = payload['properties'][key]
                    properties[key] = value
                    current_app.logger.info('      %s ==> %s' % (key, value))

            if type(properties['content']) is dict:
                if 'html' in properties['content']:
                    properties['html']    = properties['content']['html']
                    properties['content'] = []

            if 'photo' in properties:
                photos = []
                for item in properties['photo']:
                    alt = ''
                    if type(item) is dict:
                        photo = item['value']
                        if 'alt' in item:
                            alt = item['alt']
                    else:
                        photo = item
                    photos.append((photo, alt))
                properties['photo'] = photos

        data['properties'] = properties
        for key in data['properties']:
            current_app.logger.info('    %s = %s' % (key, data['properties'][key]))
        return micropub(request.method, data)
    elif request.method == 'GET':
        # https://www.w3.org/TR/2016/CR-micropub-20160816/#querying
        query = request.args.get('q')
        current_app.logger.info('query [%s]' % query)
        if query is not None:
            query      = query.lower()
            respJson   = { 'media-endpoint': current_app.config['MEDIA_ENDPOINT'],
                           'syndicate-to': current_app.config['SITE_SYNDICATE'] }
            respParam  = '&'.join(map('syndicate-to[]={0}'.format, map(urllib.quote, current_app.config['SITE_SYNDICATE'])))
            respParam += '&media-endpoint=%s' % (current_app.config['MEDIA_ENDPOINT'])
            if query == 'config':
                # https://www.w3.org/TR/2016/CR-micropub-20160816/#configuration
                if request_wants_json:
                    resp             = jsonify(respJson)
                    resp.status_code = 200
                    return resp
                else:
                    return (respParam, 200, {'Content-Type': 'application/x-www-form-urlencoded'})
            elif query == 'syndicate-to':
                # https://www.w3.org/TR/2016/CR-micropub-20160816/#syndication-targets
                if request_wants_json:
                    resp             = jsonify(respJson)
                    resp.status_code = 200
                    return resp
                else:
                    return (respParam, 200, {'Content-Type': 'application/x-www-form-urlencoded'})
            elif query == 'source':
                # https://www.w3.org/TR/2016/CR-micropub-20160816/#source-content
                url        = request.args.get('url')
                properties = []
                for key in ('properties', 'properties[]'):
                    item = request.args.getlist(key)
                    if len(item) > 0:
                        properties += item
                current_app.logger.info('url: %s properties: %d %s' % (url, len(properties), properties))

                # "If no properties are specified, then the response must include all properties,
                #  as well as a type property indicating the vocabulary of the post."
                # so this is a list of properties the code currently handles
                if len(properties) == 0:
                    properties = ['type', 'category', 'content', 'published']

                targetPath = urlparse(url).path
                pathItems  = targetPath.split('.')
                current_app.logger.info('[%s] %s' % (targetPath, pathItems))

                # normalize the url target to remove any extension
                if pathItems[-1].lower() == 'html':
                    targetPath = '.'.join(pathItems[:-1])
                slug       = targetPath.replace(current_app.config['BASEROUTE'], '')
                targetFile = '%s.json' % os.path.join(current_app.config['SITE_CONTENT'], slug)
                current_app.logger.info('targetFile: %s' % targetFile)
                if os.path.exists(targetFile):
                    with open(targetFile, 'r') as h:
                        post = json.load(h)
                    respJson = { "type": ["h-entry"], "properties": {} }
                    if 'published' in properties:
                        respJson['properties']['published'] = [ post['published'] ]
                    if 'category' in properties and len(post['tags']) > 0:
                        respJson['properties']['category'] = post['tags'].split(',')
                    if 'content' in properties:
                        respJson['properties']['content'] = post['content'].split('\n')
                    current_app.logger.info(json.dumps(respJson))
                    resp = jsonify(respJson)
                    resp.status_code = 200
                    return resp
                else:
                    return 'not found', 404
            else:
                return 'not implemented', 501
        else:
            return 'not implemented', 501
    else:
        return 'not implemented', 501