示例#1
0
 def GET_AUTH(self, capsule_id, slide_id, channel):
     try:
         EditorCapsule.selectBy(id=int(capsule_id),
                                channel=channel).getOne()
         return EditorSlide.selectBy(
             id=int(slide_id),
             capsule=int(capsule_id)).getOne().to_json_api()
     except SQLObjectNotFound:
         raise web.notfound()
示例#2
0
 def runTest(self):
     """ Tests the GET endpoints. """
     self.channel.plugin_config['enable_rest_api'] = True
     self.channel.plugin_config['api_key'] = 'aaaaaaaa'
     validity_from = datetime(2018, 10, 2, 12, 00)
     validity_to = datetime(2018, 10, 2, 14, 00)
     api_capsule = EditorCapsule(name='api_capsule',
                                 channel=self.channel,
                                 creation_date=datetime.now(),
                                 c_order=0,
                                 validity_from=validity_from,
                                 validity_to=validity_to,
                                 theme='ictv')
     r = self.testApp.get('/channels/{}/api/capsules'.format(
         self.channel.id),
                          status=200,
                          headers={'X-ICTV-editor-API-Key': 'aaaaaaaa'})
     assert r.body.decode(
     ) == '[{"id": 1, "name": "api_capsule", "slides": [], "validity": [1538474400, 1538481600], "theme": "ictv"}]'
     EditorCapsule(name='api_capsule2',
                   channel=self.channel,
                   creation_date=datetime.now(),
                   c_order=1,
                   validity_from=validity_from + timedelta(minutes=1),
                   validity_to=validity_to,
                   theme='ictv')
     r = self.testApp.get('/channels/{}/api/capsules'.format(
         self.channel.id),
                          status=200,
                          headers={'X-ICTV-editor-API-Key': 'aaaaaaaa'})
     assert r.body.decode(
     ) == '[{"id": 1, "name": "api_capsule", "slides": [], "validity": [1538474400, 1538481600], "theme": "ictv"}, {"id": 2, "name": "api_capsule2", "slides": [], "validity": [1538474460, 1538481600], "theme": "ictv"}]'
     EditorSlide(duration=42,
                 s_order=0,
                 template='api-template',
                 capsule=api_capsule)
     r = self.testApp.get('/channels/{}/api/capsules'.format(
         self.channel.id),
                          status=200,
                          headers={'X-ICTV-editor-API-Key': 'aaaaaaaa'})
     assert r.body.decode(
     ) == '[{"id": 1, "name": "api_capsule", "slides": [{"id": 1, "duration": 42, "content": {}, "template": "api-template"}], "validity": [1538474400, 1538481600], "theme": "ictv"}, {"id": 2, "name": "api_capsule2", "slides": [], "validity": [1538474460, 1538481600], "theme": "ictv"}]'
     r = self.testApp.get('/channels/{}/api/capsules/1'.format(
         self.channel.id),
                          status=200,
                          headers={'X-ICTV-editor-API-Key': 'aaaaaaaa'})
     assert r.body.decode(
     ) == '{"id": 1, "name": "api_capsule", "slides": [{"id": 1, "duration": 42, "content": {}, "template": "api-template"}], "validity": [1538474400, 1538481600], "theme": "ictv"}'
     r = self.testApp.get('/channels/{}/api/capsules/1/slides/1'.format(
         self.channel.id),
                          status=200,
                          headers={'X-ICTV-editor-API-Key': 'aaaaaaaa'})
     assert r.body.decode(
     ) == '{"id": 1, "duration": 42, "content": {}, "template": "api-template"}'
示例#3
0
    def POST_AUTH(self, capsule_id, channel):
        try:
            post_data = flask.request.get_json(force=True)
        except JSONDecodeError:
            resp.badrequest()

        try:
            c = EditorCapsule.selectBy(id=int(capsule_id),
                                       channel=channel).getOne()
        except SQLObjectNotFound:
            resp.notfound()

        if {'duration', 'template', 'content'} != set(post_data.keys()):
            resp.badrequest()
        try:
            s = EditorSlide(s_order=c.slides.count(), capsule=c, **post_data)
        except SQLObjectIntegrityError:
            resp.badrequest()

        EditorSlide.rectify_s_order(c.id)
        response = resp.created()
        response.header[
            'Location'] = '/channels/{}/api/capsules/{}/slides/{}'.format(
                channel.id, capsule_id, s.id)
        return response
示例#4
0
 def render_page(self, channel, capsules=None):
     now = datetime.datetime.now()
     if capsules is None:
         capsules_all = EditorCapsule.selectBy(channel=channel.id)
         capsules = capsules_all.filter(EditorCapsule.q.validity_to > now)
         expired_capsules = capsules_all.filter(
             EditorCapsule.q.validity_to <= now)
     else:
         capsules_all = capsules
         expired_capsules = capsules_all.filter(
             EditorCapsule.q.validity_to <= now)
         capsules = capsules_all.filter(EditorCapsule.q.validity_to > now)
     if 'capsule_validity' in channel.plugin_config:
         validity = int(channel.plugin_config['capsule_validity'])
     else:
         validity = int(
             channel.plugin.channels_params['capsule_validity']['default'])
     vertical = channel.get_config_param('vertical')
     default_from = datetime.datetime.now()
     time_delta = datetime.timedelta(hours=validity)
     default_to = default_from + time_delta
     return self.renderer.capsules(
         channel=channel,
         capsules=capsules,
         expired_capsules=expired_capsules,
         capsules_all=capsules_all,
         default_from=default_from.replace(microsecond=0).isoformat(),
         default_to=default_to.replace(microsecond=0).isoformat(),
         vertical=vertical)
示例#5
0
 def DELETE_AUTH(self, capsule_id, channel):
     try:
         c = EditorCapsule.selectBy(id=int(capsule_id),
                                    channel=channel).getOne()
         c.destroySelf()
     except SQLObjectNotFound:
         raise web.notfound()
     raise web.nocontent()
示例#6
0
 def GET(self, channel):
     capsules = EditorCapsule.selectBy(channel=channel).filter(
         EditorCapsule.q.validity_to > datetime.now()).orderBy('c_order')
     list_to_render = []
     for c in capsules:
         list_to_render.append(c.to_plugin_capsule())
     PluginManager.dereference_assets(list_to_render)
     return self.ictv_renderer.preview_capsules(list_to_render)
示例#7
0
    def DELETE_AUTH(self, capsule_id, slide_id, channel):
        try:
            c = EditorCapsule.selectBy(id=int(capsule_id),
                                       channel=channel).getOne()
            EditorSlide.selectBy(id=int(slide_id),
                                 capsule=c).getOne().destroySelf()
        except SQLObjectNotFound:
            resp.notfound()

        resp.nocontent()
示例#8
0
 def get(self, capsuleid, channel):
     try:
         caps_db = EditorCapsule.get(int(capsuleid))
         if caps_db.channel != channel:
             return "there is no capsule with the id " + str(capsuleid) + " in the channel " + str(channel.id)
     except ValueError:
         return "this is not a valid capsule id"
     except SQLObjectNotFound:
         return "there is no capsule with the id " + str(capsuleid) + " in the channel " + str(channel.id)
     slides = EditorSlide.rectify_s_order(capsuleid)
     return self.render_page(channel=channel, capsule=caps_db, slides=slides)
示例#9
0
    def POST_AUTH(self, channel):
        try:
            post_data = flask.request.get_json(force=True)
        except JSONDecodeError:
            resp.badrequest()

        if {'name', 'theme', 'validity'} != set(post_data.keys()):
            resp.badrequest()

        if 'name' in post_data and len(post_data['name']) < 3:
            resp.badrequest()

        validity_from, validity_to = post_data['validity']
        if not (type(validity_from) == type(validity_to) ==
                int) or validity_to < validity_from:
            resp.badrequest()
        try:
            validity_from, validity_to = datetime.fromtimestamp(
                validity_from), datetime.fromtimestamp(validity_to)
        except (TypeError, ValueError):
            resp.badrequest()

        try:
            c = EditorCapsule(
                name=post_data['name'],
                theme=post_data['theme'],
                validity_from=validity_from,
                validity_to=validity_to,
                channel=channel,
                c_order=EditorCapsule.selectBy(channel=channel).count())
        except DuplicateEntryError:
            resp.badrequest()
        EditorCapsule.rectify_c_order(channel.id)
        response = resp.created()
        response.headers['Location'] = '/channels/{}/api/capsules/{}'.format(
            channel.id, c.id)
        return response
示例#10
0
 def GET(self, capsuleid, template_name):
     if template_name not in self.slide_templates:
         return 'no such template : "' + template_name + '"'
     else:
         try:
             capsule = EditorCapsule.get(int(capsuleid))
         except ValueError:
             return 'This is not a valid capsule id'
         except SQLObjectNotFound:
             return 'There is no capsule with id ' + capsuleid
         return self.slide_renderer.render_template(
             template_name=template_name,
             content=None,
             theme_name=capsule.theme
             if capsule.theme in Themes else self.config['default_theme'])
示例#11
0
    def POST_AUTH(self, channel):
        try:
            post_data = json.loads(web.data().decode())
        except JSONDecodeError:
            raise web.badrequest()

        if {'name', 'theme', 'validity'} != set(post_data.keys()):
            raise web.badrequest()

        if 'name' in post_data and len(post_data['name']) < 3:
            raise web.badrequest()

        validity_from, validity_to = post_data['validity']
        if not (type(validity_from) == type(validity_to) ==
                int) or validity_to < validity_from:
            raise web.badrequest()
        try:
            validity_from, validity_to = datetime.fromtimestamp(
                validity_from), datetime.fromtimestamp(validity_to)
        except (TypeError, ValueError):
            raise web.badrequest()

        try:
            c = EditorCapsule(
                name=post_data['name'],
                theme=post_data['theme'],
                validity_from=validity_from,
                validity_to=validity_to,
                channel=channel,
                c_order=EditorCapsule.selectBy(channel=channel).count())
        except DuplicateEntryError:
            raise web.badrequest()
        EditorCapsule.rectify_c_order(channel.id)
        web.header('Location',
                   '/channels/{}/api/capsules/{}'.format(channel.id, c.id))
        raise web.created()
示例#12
0
    def PATCH_AUTH(self, capsule_id, channel):
        try:
            post_data = json.loads(web.data().decode())
        except JSONDecodeError:
            raise web.badrequest()

        try:
            c = EditorCapsule.selectBy(id=int(capsule_id),
                                       channel=channel).getOne()
        except SQLObjectNotFound:
            raise web.notfound()

        if 'name' in post_data and len(post_data['name']) < 3:
            raise web.badrequest()

        if 'validity' in post_data:
            validity_from, validity_to = post_data['validity']
            if not (type(validity_from) == type(validity_to) ==
                    int) or validity_to < validity_from:
                raise web.badrequest()
            try:
                validity_from, validity_to = datetime.fromtimestamp(
                    validity_from), datetime.fromtimestamp(validity_to)
            except (TypeError, ValueError):
                raise web.badrequest()
            post_data['validity_from'] = validity_from
            post_data['validity_to'] = validity_to
            del post_data['validity']

        update_dict = {
            k: v
            for k, v in filter(
                lambda x: x[0] in
                ['name', 'theme', 'validity_from', 'validity_to'],
                post_data.items())
        }
        try:
            c.set(**update_dict)
        except DuplicateEntryError:
            raise web.badrequest()

        raise web.nocontent()
示例#13
0
    def PATCH_AUTH(self, capsule_id, slide_id, channel):
        try:
            post_data = json.loads(web.data().decode())
        except JSONDecodeError:
            raise web.badrequest()

        try:
            c = EditorCapsule.selectBy(id=int(capsule_id),
                                       channel=channel).getOne()
            s = EditorSlide.selectBy(id=int(slide_id), capsule=c).getOne()
        except SQLObjectNotFound:
            raise web.notfound()

        update_dict = {
            k: v
            for k, v in filter(
                lambda x: x[0] in ['duration', 'template', 'content'],
                post_data.items())
        }
        s.set(**update_dict)

        raise web.nocontent()
示例#14
0
 def POST(self, capsuleid, channel):
     form = web.input()
     content, assets = update_slide(form=form,
                                    storage_manager=StorageManager(
                                        channel.id),
                                    user_id=self.session['user']['id'])
     template = form['template']
     try:
         capsule = EditorCapsule.get(capsuleid)
         if capsule.channel != channel:
             return 'there is no capsule with id ' + capsuleid + ' in channel ' + channel.name
     except SQLObjectNotFound:
         return 'there is no capsule with id ' + capsuleid
     s = EditorSlide(
         duration=-1,
         content=content,
         s_order=EditorSlide.selectBy(capsule=capsuleid).count(),
         template=template,
         capsule=capsuleid)
     list(capsule.slides).append(s)
     for asset in assets:
         mapping = AssetSlideMapping(assetID=asset.id, slideID=s.id)
     raise seeother(channel.id, '/capsules/' + str(capsuleid))
示例#15
0
    def GET(self, capsule_id, slide_id=None, template=None):
        capsule = EditorCapsule.get(capsule_id)
        theme = capsule.theme if capsule.theme in Themes else self.config[
            'default_theme']
        if slide_id:
            slide = EditorSlide.get(slide_id)

            capsule = type('DummyCapsule', (PluginCapsule, object), {
                'get_slides': lambda: [slide],
                'get_theme': lambda: theme
            })
            self.plugin_manager.dereference_assets([capsule])

            content = slide.get_content()
            duration = slide.duration
            t = template if template else slide.get_template()
            slide = type(
                'DummySlide', (PluginSlide, object), {
                    'get_duration': lambda: duration,
                    'get_content': lambda: content,
                    'get_template': lambda: t
                })
        else:
            slide = type(
                'DummySlide', (PluginSlide, object), {
                    'get_duration': lambda: 5000,
                    'get_content': lambda: {},
                    'get_template': lambda: template
                })

        if template:
            content = self.get_slide_defaults(slide)
            deep_update(content, Themes.get_slide_defaults(theme))
            deep_update(content, slide.get_content())
            slide.get_content = lambda: content

        return self.ictv_renderer.preview_slide(slide, theme, small_size=True)
示例#16
0
 def GET(self, capsuleid, channel):
     try:
         capsule = EditorCapsule.get(capsuleid)
         if capsule.channel != channel:
             return 'there is no capsule with id ' + capsuleid + ' in channel ' + channel.name
     except SQLObjectNotFound:
         return 'there is no capsule with id ' + capsuleid
     capsule_theme = capsule.get_theme() if capsule.get_theme(
     ) in Themes else self.app.config['default_theme']
     vertical = channel.get_config_param('vertical')
     templates = self.slide_templates
     template = channel.get_config_param('default_template')
     if vertical:
         templates = {
             'template-image-bg':
             templates['template-image-bg'],
             'template-background-text-center':
             self.slide_templates['template-background-text-center']
         }
         default_template = channel.get_config_param('default_template')
         template = template if default_template in [
             "template-image-bg", 'template-background-text-center'
         ] else 'template-background-text-center'
     return self.renderer.editor(
         capsule=capsule,
         channel=channel,
         slide=None,
         old_content=Themes.get_slide_defaults(capsule_theme),
         template=template,
         templates=templates,
         theme=capsule_theme,
         theme_palette=Themes[capsule_theme].get('ckeditor_palette'),
         themes=Themes.prepare_for_css_inclusion([capsule_theme]),
         theme_defaults=json.dumps(
             Themes.get_slide_defaults(capsule_theme)),
         vertical=vertical)
示例#17
0
    def POST_AUTH(self, capsule_id, channel):
        try:
            post_data = json.loads(web.data().decode())
        except JSONDecodeError:
            raise web.badrequest()

        try:
            c = EditorCapsule.selectBy(id=int(capsule_id),
                                       channel=channel).getOne()
        except SQLObjectNotFound:
            raise web.notfound()

        if {'duration', 'template', 'content'} != set(post_data.keys()):
            raise web.badrequest()
        try:
            s = EditorSlide(s_order=c.slides.count(), capsule=c, **post_data)
        except SQLObjectIntegrityError:
            raise web.badrequest()

        EditorSlide.rectify_s_order(c.id)
        web.header(
            'Location', '/channels/{}/api/capsules/{}/slides/{}'.format(
                channel.id, capsule_id, s.id))
        raise web.created()
示例#18
0
 def GET_AUTH(self, capsule_id, channel):
     try:
         return EditorCapsule.selectBy(
             id=int(capsule_id), channel=channel).getOne().to_json_api()
     except SQLObjectNotFound:
         resp.notfound()
示例#19
0
    def post(self, capsuleid, channel):
        try:
            caps_db = EditorCapsule.get(int(capsuleid))
            slides = caps_db.slides
            form = self.form

            logger_extra = {'channel_name': channel.name, 'channel_id': channel.id}
            logger = get_logger('editor', channel)
            if caps_db.channel != channel:
                return "there is no capsule with the id " + str(capsuleid) + " in the channel " + str(channel.id)
            if form.action == 'delete':
                try:
                    slide = EditorSlide.get(int(form.id))
                except ValueError:
                    return "this is not a valid slide id"
                except SQLObjectNotFound:
                    return "there is no slide with the id " + form.id + " in the channel " + str(channel.id)
                slide.destroySelf()
                slides = EditorSlide.rectify_s_order(capsuleid)
            elif form.action == 'duplicate':
                try:
                    slide = EditorSlide.get(int(form.id))
                except ValueError:
                    return "this is not a valid slide id"
                except SQLObjectNotFound:
                    return "there is no slide with the id " + form.id + " in the channel " + str(channel.id)
                duplicate = slide.duplicate(s_order=-1)
                caps_db.insert_slide_at(duplicate, slide.s_order + 1)
                slides = caps_db.slides
            elif form.action == 'order':
                try:
                    new_order = json.loads(form.order)
                except AttributeError:
                    return "you seem to try to change the order of slides that doesn't exist..."
                except JSONDecodeError:
                    return "invalid changes"
                for k, v in new_order.items():
                    try:
                        slide = EditorSlide.get(int(k))
                        if slide.capsule.id != int(capsuleid):
                            return "you try to change the order of a slide in a different capsule..."
                        slide.s_order = int(v)
                    except ValueError:
                        return "invalid changes"
                    except SQLObjectNotFound:
                        return "You try to change the order of slides that doesn't exist..."
                slides = EditorSlide.rectify_s_order(capsuleid)
            elif form.action == 'theme':
                caps_db = EditorCapsule.get(int(capsuleid))
                if caps_db.channel != channel:
                    return "there is no capsule with the id " + str(capsuleid) + " in the channel " + str(channel.id)

                if form.theme not in Themes:
                    raise ImmediateFeedback(form.action, 'not_existing_theme')
                caps_db.theme = form.theme
            elif form.action == 'edit':
                try:
                    name = form.name.strip()
                    capsule = caps_db
                    if not name:
                        raise ValueError('name')

                    date_from = datetime.datetime.strptime(form['date-from'], "%Y-%m-%dT%H:%M:%S%z")
                    date_to = datetime.datetime.strptime(form['date-to'], "%Y-%m-%dT%H:%M:%S%z")
                    if date_to <= date_from:
                        raise ValueError('dates')

                    capsule.name = name
                    capsule.validity_from = date_from
                    capsule.validity_to = date_to
                except SQLObjectNotFound:
                    return seeother(channel.id, '/')
                except DuplicateEntryError:
                    raise ImmediateFeedback(form.action, 'name_already_exists')
                except ValueError as e:
                    raise ImmediateFeedback(form.action, 'invalid_name' if e.args[0] == 'name' else 'dates_inverted')
            elif form.action.startswith('import'):
                storage_manager = StorageManager(channel.id)
                capsule = caps_db
                background_color = 'white' if 'white-background' in form and form['white-background'] == 'on' else 'black'
                offset = EditorSlide.selectBy(capsule=capsule).max('s_order')
                offset = offset + 1 if offset is not None else 0

                if form.action == 'import-slides' and 'pdf' in form:
                    slide_files = []
                    try:
                        with Color(background_color) as bg:
                            with Image(blob=form.pdf.read(), resolution=150) as pdf:
                                for i, page in enumerate(pdf.sequence):
                                    img_page = Image(image=page)
                                    img_page.background_color = bg
                                    img_page.alpha_channel = False
                                    img_page.format = 'jpeg'
                                    img_page.transform(resize='1920x1080>')
                                    asset = storage_manager.store_file(img_page.make_blob('jpeg'),
                                                                       filename='import-capsule-%d-slide-%d.jpeg' % (capsule.id, offset + i),
                                                                       user=self.session['user']['id'])
                                    slide_files.append(asset)
                        slide_duration = channel.get_config_param('duration') * 1000
                        for i, slide_file in enumerate(slide_files):
                            s = EditorSlide(duration=slide_duration,
                                            content={'background-1': {'file': slide_file.id,
                                                                      'size': 'contain',
                                                                      'color': background_color}},
                                            s_order=offset + i, template='template-image-bg', capsule=capsule)

                            AssetSlideMapping(assetID=slide_file.id, slideID=s.id)
                    except (ValueError, TypeError):
                        logger.warning('An Exception has been encountered when importing PDF file:', extra=logger_extra,
                                       exc_info=True)
                elif form.action == 'import-video' and 'video' in form:
                    try:
                        video_slide = EditorSlide.from_video(form.video, storage_manager, self.transcoding_queue, capsule, self.session['user']['id'], background_color)
                        if type(video_slide) is str:  # Video is being transcoded
                            raise ImmediateFeedback(form.action, 'video_transcoding', video_slide)
                    except TypeError as e:
                        raise ImmediateFeedback(form.action, 'invalid_video_format', e.type)
                else:
                    resp.badrequest()
            elif form.action == 'duration':
                try:
                    slide_id = int(form.id)
                    slide = EditorSlide.get(slide_id)
                    if "duration" in form:
                        duration = float(form.duration)*1000
                        if duration < 0:
                            raise ImmediateFeedback(form.action, "negative_slide_duration")
                    else:
                        duration = -1
                    slide.duration = duration
                except SQLObjectNotFound:
                    return seeother(channel.id, '/')
                except ValueError:
                    raise ImmediateFeedback(form.action, 'invalid_slide_duration')
            add_feedback(form.action, 'ok')
        except ValueError:
            return "this is not a valid capsule id"
        except SQLObjectNotFound:
            return "there is no capsule with the id " + str(capsuleid) + " in the channel " + str(channel.id)
        except ImmediateFeedback:
            store_form(form)
        return self.render_page(channel=channel, capsule=caps_db, slides=caps_db.slides)
示例#20
0
    def POST(self, channel):
        form = web.input(
            pdf={}, video={}
        )  # Force CGI FieldStorage object to be created for large files
        logger_extra = {'channel_name': channel.name, 'channel_id': channel.id}
        logger = get_logger('editor', channel)
        capsules = None
        try:
            if form['action'] == 'delete':
                try:
                    capsule_id = int(form['id'])
                except ValueError:
                    raise ImmediateFeedback(form.action, 'invalid_id')
                try:
                    capsule = EditorCapsule.get(capsule_id)
                except SQLObjectNotFound:
                    raise ImmediateFeedback(form.action, 'no_id_matching')

                if channel != capsule.channel:
                    raise ImmediateFeedback(form.action, 'wrong_channel')
                if capsule is None:
                    raise ImmediateFeedback(form.action, 'no_id_matching')
                capsule.destroySelf()
                capsules = EditorCapsule.rectify_c_order(channel.id)

            elif form['action'] == 'duplicate':
                try:
                    capsule_id = int(form['id'])
                except ValueError:
                    raise ImmediateFeedback(form.action, 'invalid_id')
                try:
                    capsule = EditorCapsule.get(capsule_id)
                except SQLObjectNotFound:
                    raise ImmediateFeedback(form.action, 'no_id_matching')

                if channel != capsule.channel:
                    raise ImmediateFeedback(form.action, 'wrong_channel')
                if capsule is None:
                    raise ImmediateFeedback(form.action, 'no_id_matching')
                capsule.duplicate(owner_id=self.session['user']['id'])
                capsules = EditorCapsule.rectify_c_order(channel.id)

            elif form.action == 'order':
                try:
                    new_order = json.loads(form.order)
                except AttributeError:
                    return "you seem to try to change the order of slides that doesn't exist..."
                except JSONDecodeError:
                    return "invalid changes"
                capsules_to_reorder = {}
                for k in new_order.keys():
                    try:
                        capsule = EditorCapsule.get(int(k))
                        capsules_to_reorder[k] = capsule
                        if capsule.channel.id != channel.id:
                            return "you try to change the order of a capsule in a different channel..."
                    except SQLObjectNotFound:
                        return "You try to change the order of slides that doesn't exist..."
                sorted_list = sorted(capsules_to_reorder.values(),
                                     key=lambda caps: caps.c_order)
                new_to_old_order = {}
                i = 0
                for elem in sorted_list:
                    new_to_old_order[i] = elem.c_order
                    i += 1
                try:
                    for k, v in new_order.items():
                        capsules_to_reorder[k].c_order = new_to_old_order[int(
                            v)]
                except ValueError:
                    return "invalid changes"
                capsules = EditorCapsule.rectify_c_order(channel.id)

            elif form['action'] == 'create' or form['action'].startswith(
                    'import'):
                name = form['name'].strip()
                if not name:
                    raise ImmediateFeedback(form.action, 'invalid_name')
                try:
                    if 'date-from' in form and 'date-to' in form:
                        try:
                            date_from = datetime.datetime.strptime(
                                form['date-from'], "%Y-%m-%dT%H:%M:%S%z")
                            date_to = datetime.datetime.strptime(
                                form['date-to'], "%Y-%m-%dT%H:%M:%S%z")
                        except ValueError:
                            raise ImmediateFeedback(form.action,
                                                    'wrong_date_values')
                    else:
                        if 'capsule_validity' in channel.plugin_config:
                            validity = int(
                                channel.plugin_config['capsule_validity'])
                        else:
                            validity = int(
                                channel.plugin.
                                channels_params['capsule_validity']['default'])
                        date_from = datetime.datetime.now()
                        time_delta = datetime.timedelta(hours=validity)
                        date_to = date_from + time_delta
                    if date_to <= date_from:
                        raise ImmediateFeedback(form.action, 'dates_inverted')
                    capsule = EditorCapsule(
                        name=form['name'],
                        channel=channel,
                        ownerID=self.session['user']['id'],
                        creation_date=datetime.datetime.now(),
                        c_order=EditorCapsule.select().count(),
                        validity_from=date_from,
                        validity_to=date_to)
                    if form.action.startswith('import'):
                        storage_manager = StorageManager(channel.id)
                        background_color = 'white' if 'white-background' in form and form[
                            'white-background'] == 'on' else 'black'

                        if form.action == 'import-capsule' and 'pdf' in form:

                            slide_files = []
                            try:
                                with Color(background_color) as bg:
                                    with Image(blob=form.pdf.file.read(),
                                               resolution=150) as pdf:
                                        for i, page in enumerate(pdf.sequence):
                                            img_page = Image(image=page)
                                            img_page.background_color = bg
                                            img_page.alpha_channel = False
                                            img_page.format = 'jpeg'
                                            img_page.transform(
                                                resize='1920x1080>')
                                            slide_files.append(
                                                storage_manager.store_file(
                                                    img_page.make_blob('jpeg'),
                                                    filename=
                                                    'import-capsule-%d-slide-%d.jpeg'
                                                    % (capsule.id, i),
                                                    user=self.session['user']
                                                    ['id']))
                                slide_duration = channel.get_config_param(
                                    'duration') * 1000
                                for i, slide_file in enumerate(slide_files):
                                    s = EditorSlide(
                                        duration=slide_duration,
                                        content={
                                            'background-1': {
                                                'file': slide_file.id,
                                                'size': 'contain',
                                                'color': background_color
                                            }
                                        },
                                        s_order=i,
                                        template='template-image-bg',
                                        capsule=capsule)
                                    AssetSlideMapping(assetID=slide_file.id,
                                                      slideID=s.id)
                            except (ValueError, TypeError):
                                logger.warning(
                                    'An Exception has been encountered when importing PDF file:',
                                    extra=logger_extra,
                                    exc_info=True)
                        elif form.action == 'import-video' and 'video' in form:
                            try:
                                video_slide = EditorSlide.from_video(
                                    form.video, storage_manager,
                                    self.transcoding_queue, capsule,
                                    self.session['user']['id'],
                                    background_color)
                                if type(video_slide
                                        ) is str:  # Video is being transcoded
                                    raise ImmediateFeedback(
                                        form.action, 'video_transcoding',
                                        video_slide)
                            except TypeError as e:
                                capsule.destroySelf()
                                raise ImmediateFeedback(
                                    form.action, 'invalid_video_format',
                                    e.type if hasattr(e, 'type') else None)
                        else:
                            raise web.badrequest()

                except DuplicateEntryError:
                    raise ImmediateFeedback(form.action, 'name_already_exists')
            elif form['action'] == 'edit':
                name = form['name'].strip()
                if not name:
                    raise ImmediateFeedback(form.action, 'invalid_name')
                try:
                    capsule_id = int(form['id'])
                except ValueError:
                    raise ImmediateFeedback(form.action, 'invalid_id')
                try:
                    capsule = EditorCapsule.get(capsule_id)
                except SQLObjectNotFound:
                    raise ImmediateFeedback(form.action, 'no_id_matching')

                if channel != capsule.channel:
                    raise ImmediateFeedback(form.action, 'wrong_channel')
                try:
                    capsule.name = name
                except DuplicateEntryError:
                    raise ImmediateFeedback(form.action, 'name_already_exists')
                try:
                    date_from = datetime.datetime.strptime(
                        form['date-from'], "%Y-%m-%dT%H:%M:%S%z")
                    date_to = datetime.datetime.strptime(
                        form['date-to'], "%Y-%m-%dT%H:%M:%S%z")
                except ValueError:
                    raise ImmediateFeedback(form.action, 'wrong_date_values')
                if date_to <= date_from:
                    raise ImmediateFeedback(form.action, 'dates_inverted')
                capsule.validity_from = date_from
                capsule.validity_to = date_to
            add_feedback(form.action, 'ok')
        except ImmediateFeedback:
            pass
        store_form(form)
        return self.render_page(channel, capsules)
示例#21
0
 def GET(self, channel):
     capsules = EditorCapsule.rectify_c_order(channel.id)
     return self.render_page(channel, capsules=capsules)
示例#22
0
 def GET_AUTH(self, channel):
     return [
         c.to_json_api() for c in EditorCapsule.selectBy(channel=channel)
     ]