Esempio n. 1
0
def get_content(channel_id):
    channel = PluginChannel.get(channel_id)
    logger_extra = {'channel_name': channel.name, 'channel_id': channel.id}
    logger = get_logger('github_reader', channel)
    token = channel.get_config_param('token')
    duration = channel.get_config_param('duration') * 1000
    repo_url = channel.get_config_param('repo_url')
    had_organization = channel.get_config_param('had_organization')
    number_organizations = channel.get_config_param('number_organizations')
    orga_url = channel.get_config_param('orga_url')
    disp_commits = channel.get_config_param('disp_commits')
    number_commits = channel.get_config_param('number_commits')
    max_days_commit = channel.get_config_param('max_days_commit')
    disp_contributors = channel.get_config_param('disp_contributors')
    number_contributors = channel.get_config_param('number_contributors')
    disp_issues = channel.get_config_param('disp_issues')
    number_issues = channel.get_config_param('number_issues')
    disp_stat = channel.get_config_param('disp_stat')
    disp_releases = channel.get_config_param('disp_releases')
    number_releases = channel.get_config_param('number_releases')
    if not token or not repo_url:
        logger.warning('Some of the required parameters are empty',
                       extra=logger_extra)
        return []

    git_obj = Github(token)
    capsule = GithubReaderCapsule()

    #if disp_stat:
    #    stat = git_obj.get_stat()
    if disp_issues:
        capsule._slides.append(
            GithubReaderSlideIssue(repo_url, number_issues, duration, git_obj,
                                   logger, logger_extra))
    if disp_commits:
        capsule._slides.append(
            GithubReaderSlideCommit(repo_url, number_commits, duration,
                                    git_obj, max_days_commit, logger,
                                    logger_extra))
    if disp_releases:
        capsule._slides.append(
            GithubReaderSlideRelease(repo_url, number_releases, duration,
                                     git_obj, logger, logger_extra))
    if disp_contributors:
        capsule._slides.append(
            GithubReaderSlideContributor(repo_url, number_contributors,
                                         duration, git_obj, logger,
                                         logger_extra))
    if had_organization:
        capsule._slides.append(
            GithubReaderSlideOrganization(orga_url, number_organizations,
                                          duration, git_obj, logger,
                                          logger_extra))

    return [capsule]
Esempio n. 2
0
def get_content(channel_id):
    channel = PluginChannel.get(channel_id)
    logger_extra = {'channel_name': channel.name, 'channel_id': channel.id}
    logger = get_logger('i_like_trains', channel)
    departure_station = channel.get_config_param('departure_station')
    duration = channel.get_config_param('duration')*1000
    language = channel.get_config_param('language')
    nb_train = channel.get_config_param('nb_train')
    logo_1 = channel.get_config_param('logo_1')
    if not departure_station:
        logger.warning('Problem with the departure station', extra=logger_extra)
        return []
    else:
        base_url = "http://api.irail.be/"
        head = {'user-agent': 'ICTVbooyy/0.69 (ictv.github.con; [email protected])'}
        payload = {'station': departure_station, 'arrdep': 'departures', 'lang': language, 'format': 'json',
                   'alert': 'true'}

        r = requests.get(base_url + 'liveboard/', params=payload, headers=head)
        parsed = json.loads(r.text)
        return [ILikeTrainsCapsule(departure_station, duration, language, nb_train, parsed, logo_1)]
Esempio n. 3
0
def get_content(channel_id):
    channel = PluginChannel.get(channel_id)
    logger_extra = {'channel_name': channel.name, 'channel_id': channel.id}
    logger = get_logger('img-grabber', channel)
    url = channel.get_config_param('url')
    image_selector = channel.get_config_param('image_selector')
    attr = channel.get_config_param('src_attr')
    qrcode = channel.get_config_param('qrcode')
    if not url or not image_selector or not attr:
        logger.warning('Some of the required parameters are empty',
                       extra=logger_extra)
        return []
    try:
        doc = PyQuery(url=url)
    except Exception as e:
        raise MisconfiguredParameters(
            'url', url, 'The following error was encountered: %s.' % str(e))
    img = doc(image_selector).eq(0).attr(attr)
    if not img:
        message = 'Could not find img with CSS selector %s and attribute %s' % (
            image_selector, attr)
        raise MisconfiguredParameters('image_selector', image_selector,
                                      message).add_faulty_parameter(
                                          'src_attr', attr, message)
    img = urljoin(url, img)
    duration = channel.get_config_param('duration') * 1000
    text = doc(channel.get_config_param('text_selector')).eq(0).text()
    alternative_text = channel.get_config_param('alternative_text')
    color = channel.get_config_param('color')
    return [
        ImgGrabberCapsule(img,
                          text if text else alternative_text,
                          duration,
                          color,
                          qrcode=url if qrcode else None)
    ]
Esempio n. 4
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)
Esempio n. 5
0
def get_content(channel_id, config=None):
    channel = Channel.get(channel_id)
    logger = get_logger('rss', channel)
    if not config:

        def get_param(x):
            return channel.get_config_param(x)
    else:

        def get_param(x):
            return config[x]

    url = get_param('url')
    parser_rules = get_param(
        'parser_rules'
    )  # A list of rules in the form slide_element;entry_item;regexp
    additional_rules = get_param(
        'additional_rules')  # A list of rules in the form entry_item;string
    filter = get_param('filter')
    exception_rules = get_param(
        'exception_rules')  # A list of rules in the form entry_item;string
    no_slides = get_param('no_slides')
    time_limit = get_param('time_limit')
    duration = get_param('duration') * 1000
    template = get_param('template')
    theme = get_param('theme')
    min_age = datetime.now() - timedelta(days=time_limit)

    entries = feedparser_parse(
        url)['entries'][:no_slides] if not config or not config.get(
            'feed') else config.get('feed')
    capsules = []
    last_entries = []

    with open(cache_path, 'r+') as f:
        fcntl.flock(f, fcntl.LOCK_EX)
        cache = json.load(f, cls=DateTimeDecoder)

        for entry in entries:
            if 'published_parsed' in entry:
                entry_age = datetime.fromtimestamp(
                    mktime(entry['published_parsed']))
                if entry_age >= min_age:
                    last_entries.append(entry)
            else:
                entry_hash = hash_dict(entry)
                if entry_hash in cache:
                    if cache[entry_hash] >= min_age:
                        last_entries.append(entry)
                else:
                    cache[entry_hash] = datetime.now()
        f.seek(0)
        json.dump(cache, f, cls=DateTimeEncoder)
        f.truncate()
        fcntl.flock(f, fcntl.LOCK_UN)

    for entry in last_entries:
        slide_content = {}
        link_page = None
        for slide_element, entry_item, regexp in [
                rule.split(';') for rule in parser_rules
        ]:
            field, input_type = slide_element.split(':')
            if field not in slide_content:
                slide_content[field] = {}

            if entry_item == 'link_page':
                if not link_page:
                    with urllib.request.urlopen(entry.link) as response:
                        link_page = response.read().decode(errors='ignore')
                        entry_item += "@" + response.geturl(
                        )  # in case of redirect(s), geturl() returns the final url of the page
                item = link_page
            else:
                item = deep_get(entry, *entry_item.split('.'))

            value = get_value(item, regexp)
            if input_type == 'src' and not _is_url(value):
                ref_url = entry.link
                if entry_item.startswith('link_page@'):
                    ref_url = entry_item.split('@')[1]
                value = urljoin(ref_url, value)

            slide_content[field].update({input_type: value})

        for slide_element, string in [
                rule.split(';') for rule in additional_rules
        ]:
            field, input_type = slide_element.split(':')
            if field not in slide_content:
                slide_content[field] = {}
            if string.lower() == 'qrcode':
                input_type = 'qrcode'
                string = entry.link
            slide_content[field].update({input_type: string})

        if len(exception_rules) == 1 and not exception_rules[0].strip():
            capsules.append(
                RssCapsule(theme=theme,
                           slides=[
                               RssSlide(content=slide_content,
                                        template=template,
                                        duration=duration)
                           ]))
        else:
            for entry_item, regexp in [
                    rule.split(';') for rule in exception_rules
            ]:
                if entry_item == 'link_page':
                    if not link_page:
                        with urllib.request.urlopen(entry.link) as response:
                            link_page = response.read().decode(errors='ignore')
                            entry_item += "@" + response.geturl(
                            )  # in case of redirect(s), geturl() returns the final url of the page
                    item = link_page
                else:
                    item = deep_get(entry, *entry_item.split('.'))

                value = get_value(item, regexp)

                if filter and value is None:
                    capsules.append(
                        RssCapsule(theme=theme,
                                   slides=[
                                       RssSlide(content=slide_content,
                                                template=template,
                                                duration=duration)
                                   ]))

                if not filter and value is not None:
                    capsules.append(
                        RssCapsule(theme=theme,
                                   slides=[
                                       RssSlide(content=slide_content,
                                                template=template,
                                                duration=duration)
                                   ]))

    return capsules
Esempio n. 6
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)
Esempio n. 7
0
def get_content(channel_id):
    channel = PluginChannel.get(channel_id)
    logger_extra = {'channel_name': channel.name, 'channel_id': channel.id}
    logger = get_logger('github', channel)
    token = channel.get_config_param('token')
    duration = channel.get_config_param('duration') * 1000
    repo_url = channel.get_config_param('repo_url')
    had_organization = channel.get_config_param('had_organization')
    number_organizations = channel.get_config_param('number_organizations')
    orga_url = channel.get_config_param('orga_url')
    disp_commits = channel.get_config_param('disp_commits')
    number_commits = channel.get_config_param('number_commits')
    max_days_commit = channel.get_config_param('max_days_commit')
    disp_contributors = channel.get_config_param('disp_contributors')
    number_contributors = channel.get_config_param('number_contributors')
    disp_issues = channel.get_config_param('disp_issues')
    number_issues = channel.get_config_param('number_issues')
    disp_stat = channel.get_config_param('disp_stat')
    disp_releases = channel.get_config_param('disp_releases')
    number_releases = channel.get_config_param('number_releases')
    if not token or not repo_url:
        logger.warning('Some of the required parameters are empty',
                       extra=logger_extra)
        return []

    git_obj = GithubAPI(token)
    capsule = GithubReaderCapsule()

    if disp_issues:
        try:
            capsule.slides.append(
                GithubReaderSlideIssue(repo_url, number_issues, duration,
                                       git_obj, logger, logger_extra))
        except NoContentError:
            pass
        except:
            logger.info(
                'An exception occurred when generating the issues slide',
                exc_info=True,
                extra=logger_extra)
    if disp_commits:
        try:
            capsule.slides.append(
                GithubReaderSlideCommit(repo_url, number_commits, duration,
                                        git_obj, max_days_commit, logger,
                                        logger_extra))
        except NoContentError:
            pass
        except:
            logger.info(
                'An exception occurred when generating the commits slide',
                exc_info=True,
                extra=logger_extra)
    if disp_releases:
        try:
            capsule.slides.append(
                GithubReaderSlideRelease(repo_url, number_releases, duration,
                                         git_obj, logger, logger_extra))
        except NoContentError:
            pass
        except:
            logger.info(
                'An exception occurred when generating the releases slide',
                exc_info=True,
                extra=logger_extra)
    if disp_contributors:
        try:
            capsule.slides.append(
                GithubReaderSlideContributor(repo_url, number_contributors,
                                             duration, git_obj, logger,
                                             logger_extra))
        except NoContentError:
            pass
        except:
            logger.info(
                'An exception occurred when generating the contributors slide',
                exc_info=True,
                extra=logger_extra)
    if had_organization:
        try:
            capsule.slides.append(
                GithubReaderSlideOrganization(orga_url, number_organizations,
                                              duration, git_obj, logger,
                                              logger_extra))
        except NoContentError:
            pass
        except:
            logger.info(
                'An exception occurred when generating the organisation slide',
                exc_info=True,
                extra=logger_extra)

    return [capsule]