Example #1
0
def boolean_radiobuttonlist(name, **kwargs):
    return RadioButtonList(
        name,
        options=lambda: ((True, _('Yes')), (False, _('No'))),
        validator=StringBool,
        **kwargs
    )
Example #2
0
def send_comment_notification(media_obj, comment):
    """
    Helper method to send a email notification that a comment has been posted.

    Sends to the address configured in the 'email_comment_posted' setting,
    if it is configured.

    :param media_obj: The media object to send a notification about.
    :type media_obj: :class:`~mediadrop.model.media.Media` instance

    :param comment: The newly posted comment.
    :type comment: :class:`~mediadrop.model.comments.Comment` instance
    """
    send_to = request.settings['email_comment_posted']
    if not send_to:
        # Comment notification emails are disabled!
        return

    author_name = media_obj.author.name
    comment_subject = comment.subject
    post_url = url_for_media(media_obj, qualified=True)
    comment_body = strip_xhtml(line_break_xhtml(line_break_xhtml(comment.body)))
    subject = _('New Comment: %(comment_subject)s') % locals()
    body = _("""A new comment has been posted!

Author: %(author_name)s
Post: %(post_url)s

Body: %(comment_body)s
""") % locals()

    send(send_to, request.settings['email_send_from'], subject, body)
Example #3
0
def send_comment_notification(media_obj, comment):
    """
    Helper method to send a email notification that a comment has been posted.

    Sends to the address configured in the 'email_comment_posted' setting,
    if it is configured.

    :param media_obj: The media object to send a notification about.
    :type media_obj: :class:`~mediadrop.model.media.Media` instance

    :param comment: The newly posted comment.
    :type comment: :class:`~mediadrop.model.comments.Comment` instance
    """
    send_to = request.settings['email_comment_posted']
    if not send_to:
        # Comment notification emails are disabled!
        return

    author_name = media_obj.author.name
    comment_subject = comment.subject
    post_url = url_for_media(media_obj, qualified=True)
    comment_body = strip_xhtml(line_break_xhtml(line_break_xhtml(
        comment.body)))
    subject = _('New Comment: %(comment_subject)s') % locals()
    body = _("""A new comment has been posted!

Author: %(author_name)s
Post: %(post_url)s

Body: %(comment_body)s
""") % locals()

    send(send_to, request.settings['email_send_from'], subject, body)
Example #4
0
    def _parse(self, url, **kwargs):
        """Return metadata for the given URL that matches :attr:`url_pattern`.

        :type url: unicode
        :param url: A remote URL string.

        :param \*\*kwargs: The named matches from the url match object.

        :rtype: dict
        :returns: Any extracted metadata.

        """
        id = kwargs['id']

        yt_service = gdata.youtube.service.YouTubeService()
        yt_service.ssl = False

        try:
            entry = yt_service.GetYouTubeVideoEntry(video_id=id)
        except gdata.service.RequestError, request_error:
            e = request_error.args[0]
            if e['status'] == 403 and e['body'] == 'Private video':
                raise UserStorageError(
                    _('This video is private and cannot be embedded.'))
            elif e['status'] == 400 and e['body'] == 'Invalid id':
                raise UserStorageError(
                    _('Invalid YouTube URL. This video does not exist.'))
            raise UserStorageError(_('YouTube Error: %s') % e['body'])
Example #5
0
    def _parse(self, url, **kwargs):
        """Return metadata for the given URL that matches :attr:`url_pattern`.

        :type url: unicode
        :param url: A remote URL string.

        :param \*\*kwargs: The named matches from the url match object.

        :rtype: dict
        :returns: Any extracted metadata.

        """
        id = kwargs['id']

        yt_service = gdata.youtube.service.YouTubeService()
        yt_service.ssl = False

        try:
            entry = yt_service.GetYouTubeVideoEntry(video_id=id)
        except gdata.service.RequestError, request_error:
            e = request_error.args[0]
            if e['status'] == 403 and e['body'] == 'Private video':
                raise UserStorageError(
                    _('This video is private and cannot be embedded.'))
            elif e['status'] == 400 and e['body'] == 'Invalid id':
                raise UserStorageError(
                    _('Invalid YouTube URL. This video does not exist.'))
            raise UserStorageError(_('YouTube Error: %s') % e['body'])
Example #6
0
class HTML5OrFlashPrefsForm(PlayerPrefsForm):
    fields = [
        RadioButtonList(
            'prefer_flash',
            options=lambda: (
                (False,
                 _('Yes, use the Flash Player when the device supports it.')),
                (True,
                 _('No, use the HTML5 Player when the device supports it.')),
            ),
            css_classes=['options'],
            label_text=N_('Prefer the Flash Player when possible'),
            validator=StringBool,
        ),
    ] + PlayerPrefsForm.buttons

    event = events.Admin.Players.HTML5OrFlashPrefsForm

    def display(self, value, player, **kwargs):
        value.setdefault('prefer_flash',
                         player.data.get('prefer_flash', False))
        return PlayerPrefsForm.display(self, value, player, **kwargs)

    def save_data(self, player, prefer_flash, **kwargs):
        player.data['prefer_flash'] = prefer_flash
Example #7
0
def boolean_radiobuttonlist(name, **kwargs):
    return RadioButtonList(
        name,
        options=lambda: ((True, _('Yes')), (False, _('No'))),
        validator=StringBool,
        **kwargs
    )
 def _retrieve_video_details(self, video_id, parts):
     search = self.youtube.videos().list(
         id=video_id,
         part=parts,
     )
     try:
         search_response = search.execute()
     except apiclient.errors.HttpError as api_error:
         response_content = api_error.content
         # LATER: log raw error content
         error_details = json.loads(response_content)['error']['errors'][0]
         reason = error_details['reason']
         youtube_reason = reason
         if 'message' in error_details:
             youtube_reason += ' / ' + error_details['message']
         message = _('unknown YouTube error: %(reason)s') % dict(reason=youtube_reason)
         if reason == 'keyInvalid':
             message = _('Invalid API key. Please check your Google API key in settings.')
         elif reason == 'accessNotConfigured':
             # Access Not Configured. The API (YouTube Data API) is not
             # enabled for your project. Please use the Google Developers
             # Console to update your configuration.
             message = error_details['message']
         return Result(False, message=message)
     videos = search_response.get('items', [])
     return videos
Example #9
0
 def _retrieve_video_details(self, video_id, parts):
     search = self.youtube.videos().list(
         id=video_id,
         part=parts,
     )
     try:
         search_response = search.execute()
     except apiclient.errors.HttpError as api_error:
         response_content = api_error.content
         # LATER: log raw error content
         error_details = json.loads(response_content)['error']['errors'][0]
         reason = error_details['reason']
         youtube_reason = reason
         if 'message' in error_details:
             youtube_reason += ' / ' + error_details['message']
         message = _('unknown YouTube error: %(reason)s') % dict(
             reason=youtube_reason)
         if reason == 'keyInvalid':
             message = _(
                 'Invalid API key. Please check your Google API key in settings.'
             )
         elif reason == 'accessNotConfigured':
             # Access Not Configured. The API (YouTube Data API) is not
             # enabled for your project. Please use the Google Developers
             # Console to update your configuration.
             message = error_details['message']
         return Result(False, message=message)
     videos = search_response.get('items', [])
     return videos
Example #10
0
def send_media_notification_to_author(media_obj):
    """
    Send a creation notification email to author that a new Media object has been
    created.


    :param media_obj: The media object to send a notification about.
    :type media_obj: :class:`~mediadrop.model.media.Media` instance
	
    """
	
    send_to = [media_obj.author.email]
    if not send_to:
        # media notification emails are disabled!
        return
    #FIXME: extract host from env on production server
    edit_url = 'http://127.0.0.1/media/' + media_obj.slug
    clean_description = strip_xhtml(line_break_xhtml(line_break_xhtml(media_obj.description)))
    type = media_obj.type
    title = media_obj.title
    author_name = media_obj.author.name
    author_email = media_obj.author.email
    subject = _('New %(type)s: %(title)s') % locals()
    body = _("""A new %(type)s file has been uploaded!

Title: %(title)s

Author: %(author_name)s (%(author_email)s)

Video URL: %(edit_url)s

Description: %(clean_description)s
""") % locals()

    send(send_to, request.settings['email_send_from'], subject, body)
Example #11
0
def register_default_types():
    default_types = [
        (VIDEO, _('Video')),
        (AUDIO, _('Audio')),
        (AUDIO_DESC, _('Audio Description')),
        (CAPTIONS, _('Captions')),
    ]
    for t in default_types:
        yield t
Example #12
0
def register_default_types():
    default_types = [
        (VIDEO, _('Video')),
        (AUDIO, _('Audio')),
        (AUDIO_DESC, _('Audio Description')),
        (CAPTIONS, _('Captions')),
    ]
    for t in default_types:
        yield t
Example #13
0
    def index(self, page=1, show='latest', q=None, tag=None, **kwargs):
        """List media with pagination.

        The media paginator may be accessed in the template with
        :attr:`c.paginators.media`, see :class:`webhelpers.paginate.Page`.

        :param page: Page number, defaults to 1.
        :type page: int
        :param show: 'latest', 'popular' or 'featured'
        :type show: unicode or None
        :param q: A search query to filter by
        :type q: unicode or None
        :param tag: A tag slug to filter for
        :type tag: unicode or None
        :rtype: dict
        :returns:
            media
                The list of :class:`~mediadrop.model.media.Media` instances
                for this page.
            result_count
                The total number of media items for this query
            search_query
                The query the user searched for, if any

        """
        media = Media.query.published()

        media, show = helpers.filter_library_controls(media, show)

        if q:
            media = media.search(q, bool=True)

        if tag:
            tag = fetch_row(Tag, slug=tag)
            media = media.filter(Media.tags.contains(tag))

        if (request.settings['rss_display'] == 'True') and (not (q or tag)):
            if show == 'latest':
                response.feed_links.extend([
                    (url_for(controller='/sitemaps',
                             action='latest'), _(u'Latest RSS')),
                ])
            elif show == 'featured':
                response.feed_links.extend([
                    (url_for(controller='/sitemaps',
                             action='featured'), _(u'Featured RSS')),
                ])

        media = viewable_media(media)
        return dict(
            media=media,
            result_count=media.count(),
            search_query=q,
            show=show,
            tag=tag,
        )
Example #14
0
    def explore(self, **kwargs):
        """Display the most recent 15 media.

        :rtype: Dict
        :returns:
            latest
                Latest media
            popular
                Latest media

        """
        media = Media.query.published()

        latest = media.order_by(Media.publish_on.desc())
        popular = media.order_by(Media.popularity_points.desc())

        featured = None
        is_featured_item_enabled = request.settings[
            'appearance_enable_featured_items'] or request.settings[
                'appearance_enable_cooliris']
        if is_featured_item_enabled:
            featured_cat = helpers.get_featured_category()
            if featured_cat:
                featured = viewable_media(
                    latest.in_category(featured_cat)).first()
            if not featured:
                featured = viewable_media(popular).first()

        nr_latest_items = 8
        if is_featured_item_enabled:
            nr_popular_items = max(nr_latest_items - 3, 0)
        else:
            nr_popular_items = nr_latest_items
        popular = viewable_media(popular.exclude(featured))[:nr_popular_items]
        latest = viewable_media(latest.exclude(featured,
                                               popular))[:nr_latest_items]
        if request.settings['sitemaps_display'] == 'True':
            response.feed_links.extend([
                (url_for(controller='/sitemaps',
                         action='google'), _(u'Sitemap XML')),
                (url_for(controller='/sitemaps',
                         action='mrss'), _(u'Sitemap RSS')),
            ])
        if request.settings['rss_display'] == 'True':
            response.feed_links.extend([
                (url_for(controller='/sitemaps',
                         action='latest'), _(u'Latest RSS')),
            ])

        return dict(
            featured=featured,
            latest=latest,
            popular=popular,
            categories=Category.query.populated_tree(),
        )
Example #15
0
    def save_thumb(self, id, thumb=None, **kwargs):
        """Save a thumbnail uploaded with :class:`~mediadrop.forms.admin.ThumbForm`.

        :param id: Media ID. If ``"new"`` a new Media stub is created.
        :type id: ``int`` or ``"new"``
        :param file: The uploaded file
        :type file: :class:`cgi.FieldStorage` or ``None``
        :rtype: JSON dict
        :returns:
            success
                bool
            message
                Error message, if unsuccessful
            id
                The :attr:`~mediadrop.model.media.Media.id` which is
                important if a new media has just been created.

        """
        user = request.perm.user
        if id == 'new':
            media = Media()
            user = request.perm.user
            media.author = Author(user.display_name, user.email_address)
            media.title = os.path.basename(kwargs['file'].filename)
            media.slug = get_available_slug(Media, '_stub_' + media.title)
            DBSession.add(media)
            DBSession.flush()
        else:
            media = fetch_row(Media, id)
            group = request.perm.user.groups[0].group_name
            if media.author.name != user.display_name and group != 'admins':
                raise

        try:
            # Create JPEG thumbs
            create_thumbs_for(media, kwargs['file'].file,
                              kwargs['file'].filename)
            success = True
            message = None
        except IOError, e:
            success = False

            if id == 'new':
                DBSession.delete(media)

            if e.errno == 13:
                message = _('Permission denied, cannot write file')
            elif e.message == 'cannot identify image file':
                message = _('Unsupported image type: %s') \
                    % os.path.splitext(kwargs['file'].filename)[1].lstrip('.')
            elif e.message == 'cannot read interlaced PNG files':
                message = _('Interlaced PNGs are not supported.')
            else:
                raise
    def index(self, page=1, show='latest', q=None, tag=None, **kwargs):
        """List media with pagination.

        The media paginator may be accessed in the template with
        :attr:`c.paginators.media`, see :class:`webhelpers.paginate.Page`.

        :param page: Page number, defaults to 1.
        :type page: int
        :param show: 'latest', 'popular' or 'featured'
        :type show: unicode or None
        :param q: A search query to filter by
        :type q: unicode or None
        :param tag: A tag slug to filter for
        :type tag: unicode or None
        :rtype: dict
        :returns:
            media
                The list of :class:`~mediadrop.model.media.Media` instances
                for this page.
            result_count
                The total number of media items for this query
            search_query
                The query the user searched for, if any

        """
        media = Media.query.published()

        media, show = helpers.filter_library_controls(media, show)

        if q:
            media = media.search(q, bool=True)

        if tag:
            tag = fetch_row(Tag, slug=tag)
            media = media.filter(Media.tags.contains(tag))

        if (request.settings['rss_display'] == 'True') and (not (q or tag)):
            if show == 'latest':
                response.feed_links.extend([
                    (url_for(controller='/sitemaps', action='latest'), _(u'Latest RSS')),
                ])
            elif show == 'featured':
                response.feed_links.extend([
                    (url_for(controller='/sitemaps', action='featured'), _(u'Featured RSS')),
                ])

        media = viewable_media(media)
        return dict(
            media = media,
            result_count = media.count(),
            search_query = q,
            show = show,
            tag = tag,
        )
    def explore(self, **kwargs):
        """Display the most recent 15 media.

        :rtype: Dict
        :returns:
            latest
                Latest media
            popular
                Latest media

        """
        media = Media.query.published()

        latest = media.order_by(Media.publish_on.desc())
        popular = media.order_by(Media.popularity_points.desc())

        featured = None
        is_featured_item_enabled = request.settings['appearance_enable_featured_items'] or request.settings['appearance_enable_cooliris']
        if is_featured_item_enabled:
            featured_cat = helpers.get_featured_category()
            if featured_cat:
                featured = viewable_media(latest.in_category(featured_cat)).first()
            if not featured:
                featured = viewable_media(popular).first()

        nr_latest_items = 8
        if is_featured_item_enabled:
            nr_popular_items = max(nr_latest_items - 3, 0)
        else:
            nr_popular_items = nr_latest_items
        popular = viewable_media(popular.exclude(featured))[:nr_popular_items]
        latest = viewable_media(latest.exclude(featured, popular))[:nr_latest_items]
        if request.settings['sitemaps_display'] == 'True':
            response.feed_links.extend([
                (url_for(controller='/sitemaps', action='google'), _(u'Sitemap XML')),
                (url_for(controller='/sitemaps', action='mrss'), _(u'Sitemap RSS')),
            ])
        if request.settings['rss_display'] == 'True':
            response.feed_links.extend([
                (url_for(controller='/sitemaps', action='latest'), _(u'Latest RSS')),
            ])

        return dict(
            featured = featured,
            latest = latest,
            popular = popular,
            categories = Category.query.populated_tree(),
        )
Example #18
0
def best_translation(a, b):
    """Return the best translation given a preferred and a fallback string.

    If we have a translation for our preferred string 'a' or if we are using
    English, return 'a'. Otherwise, return a translation for the fallback string 'b'.

    :param a: The preferred string to translate.
    :param b: The fallback string to translate.
    :returns: The best translation
    :rtype: string
    """
    translated_a = _(a)
    if a != translated_a or translator.locale.language == 'en':
        return translated_a
    else:
        return _(b)
 def fetch_video_details(self, video_id):
     video_result = self._retrieve_video_details(video_id, 'snippet,contentDetails')
     # LATER: add debug logging for youtube response
     if video_result == False:
         return Result(
             False,
             meta_info=None,
             message=video_result.message
         )
     elif len(video_result) == 0:
         return Result(
             False,
             meta_info=None,
             message=_('Invalid YouTube URL. This video does not exist or is private and can not be embedded.')
         )
     video_details = video_result[0]
     iso8601_duration = video_details['contentDetails']['duration']
     duration = aniso8601.parse_duration(iso8601_duration)
     snippet = video_details['snippet']
     best_thumbnail = self._find_biggest_thumbnail(snippet['thumbnails'])
     meta_info = {
         'unique_id': video_details['id'],
         'duration': timedelta_to_seconds(duration),
         'display_name': snippet['title'],
         'description': snippet['description'],
         'thumbnail': {
             'width': best_thumbnail['width'],
             'height': best_thumbnail['height'],
             'url': best_thumbnail['url'],
         },
         'type': VIDEO,
     }
     return Result(True, meta_info=meta_info, message=None)
Example #20
0
    def _parse(self, url, id, **kwargs):
        """Return metadata for the given URL that matches :attr:`url_pattern`.

        :type url: unicode
        :param url: A remote URL string.

        :param \*\*kwargs: The named matches from the url match object.

        :rtype: dict
        :returns: Any extracted metadata.

        """
        if '?' in url:
            url += '&skin=api'
        else:
            url += '?skin=api'

        req = Request(url)

        try:
            temp_data = urlopen(req)
            xmlstring = temp_data.read()
            try:
                try:
                    xmltree = ElementTree.fromstring(xmlstring)
                except:
                    temp_data.close()
                    raise
            except SyntaxError:
                raise UserStorageError(
                    _('Invalid BlipTV URL. This video does not exist.'))
        except URLError, e:
            log.exception(e)
            raise
Example #21
0
    def _parse(self, url, **kwargs):
        """Return metadata for the given URL that matches :attr:`url_pattern`.

        :type url: unicode
        :param url: A remote URL string.

        :param \*\*kwargs: The named matches from the url match object.

        :rtype: dict
        :returns: Any extracted metadata.

        """
        id = kwargs['id']
        # Ensure the video uses the .com TLD for the API request.
        url = 'http://www.dailymotion.com/video/%s' % id
        data_url = 'http://www.dailymotion.com/services/oembed?' + \
            urlencode({'format': 'json', 'url': url})

        headers = {'User-Agent': USER_AGENT}
        req = Request(data_url, headers=headers)

        try:
            temp_data = urlopen(req)
            try:
                data_string = temp_data.read()
                if data_string == 'This video cannot be embeded.':
                    raise UserStorageError(
                        _('This DailyMotion video does not allow embedding.'))
                data = simplejson.loads(data_string)
            finally:
                temp_data.close()
        except URLError, e:
            log.exception(e)
            data = {}
Example #22
0
    def store(self, media_file, file=None, url=None, meta=None):
        """Store the given file or URL and return a unique identifier for it.

        :type media_file: :class:`~mediadrop.model.media.MediaFile`
        :param media_file: The associated media file object.

        :type file: :class:`cgi.FieldStorage` or None
        :param file: A freshly uploaded file object.

        :type url: unicode or None
        :param url: A remote URL string.

        :type meta: dict
        :param meta: The metadata returned by :meth:`parse`.

        :rtype: unicode or None
        :returns: The unique ID string. Return None if not generating it here.

        :raises SwiftUploadError: If storing the file fails.

        """
        file_name = safe_file_name(media_file, file.filename)

        swift = self._connect()

        try:
            swift.put_object(config['swift_container'], file_name, file.file)
            swift.close()
        except Exception, e:
            log.exception(e)
            swift.close()
            msg = _('Could not upload the file to your Swift server: %s')\
                % e.message
            raise SwiftUploadError(msg, None, None)
Example #23
0
    def _parse(self, url, **kwargs):
        """Return metadata for the given URL that matches :attr:`url_pattern`.

        :type url: unicode
        :param url: A remote URL string.

        :param \*\*kwargs: The named matches from the url match object.

        :rtype: dict
        :returns: Any extracted metadata.

        """
        id = kwargs['id']
        # Ensure the video uses the .com TLD for the API request.
        url = 'http://www.dailymotion.com/video/%s' % id
        data_url = 'http://www.dailymotion.com/services/oembed?' + \
            urlencode({'format': 'json', 'url': url})

        headers = {'User-Agent': USER_AGENT}
        req = Request(data_url, headers=headers)

        try:
            temp_data = urlopen(req)
            try:
                data_string = temp_data.read()
                if data_string == 'This video cannot be embeded.':
                    raise UserStorageError(
                        _('This DailyMotion video does not allow embedding.'))
                data = simplejson.loads(data_string)
            finally:
                temp_data.close()
        except URLError, e:
            log.exception(e)
            data = {}
Example #24
0
    def login(self, came_from=None, **kwargs):
        if request.environ.get('repoze.who.identity'):
            redirect(came_from or '/')

        # the friendlyform plugin requires that these values are set in the
        # query string
        form_url = url_for('/login/submit',
                           came_from=(came_from or '').encode('utf-8'),
                           __logins=str(self._is_failed_login()))

        login_errors = None
        if self._is_failed_login():
            login_errors = Invalid('dummy',
                                   None, {},
                                   error_dict={
                                       '_form':
                                       Invalid(
                                           _('Invalid username or password.'),
                                           None, {}),
                                       'login':
                                       Invalid('dummy', None, {}),
                                       'password':
                                       Invalid('dummy', None, {}),
                                   })
        return dict(
            login_form=login_form,
            form_action=form_url,
            form_values=kwargs,
            login_errors=login_errors,
        )
Example #25
0
def best_translation(a, b):
    """Return the best translation given a preferred and a fallback string.

    If we have a translation for our preferred string 'a' or if we are using
    English, return 'a'. Otherwise, return a translation for the fallback string 'b'.

    :param a: The preferred string to translate.
    :param b: The fallback string to translate.
    :returns: The best translation
    :rtype: string
    """
    translated_a = _(a)
    if a != translated_a or translator.locale.language == 'en':
        return translated_a
    else:
        return _(b)
Example #26
0
 def fetch_video_details(self, video_id):
     video_result = self._retrieve_video_details(video_id,
                                                 'snippet,contentDetails')
     # LATER: add debug logging for youtube response
     if video_result == False:
         return Result(False, meta_info=None, message=video_result.message)
     elif len(video_result) == 0:
         return Result(
             False,
             meta_info=None,
             message=
             _('Invalid YouTube URL. This video does not exist or is private and can not be embedded.'
               ))
     video_details = video_result[0]
     iso8601_duration = video_details['contentDetails']['duration']
     duration = aniso8601.parse_duration(iso8601_duration)
     snippet = video_details['snippet']
     best_thumbnail = self._find_biggest_thumbnail(snippet['thumbnails'])
     meta_info = {
         'unique_id': video_details['id'],
         'duration': timedelta_to_seconds(duration),
         'display_name': snippet['title'],
         'description': snippet['description'],
         'thumbnail': {
             'width': best_thumbnail['width'],
             'height': best_thumbnail['height'],
             'url': best_thumbnail['url'],
         },
         'type': VIDEO,
     }
     return Result(True, meta_info=meta_info, message=None)
Example #27
0
    def _parse(self, url, **kwargs):
        """Return metadata for the given URL that matches :attr:`url_pattern`.

        :type url: unicode
        :param url: A remote URL string.

        :param \*\*kwargs: The named matches from the url match object.

        :rtype: dict
        :returns: Any extracted metadata.

        """
        video_id = kwargs['id']
        youtube = build_youtube_client()
        if youtube is None:
            msg = _(
                'No API key configured for YouTube (use Google\'s developer console to create one)'
            )
            raise UserStorageError(msg)
        yt_result = youtube.fetch_video_details(video_id)
        if not yt_result:
            raise UserStorageError(yt_result.message)
        video_info = yt_result.meta_info.copy()
        video_info['thumbnail_url'] = yt_result.meta_info['thumbnail']['url']
        del video_info['thumbnail']
        return video_info
Example #28
0
class WXHValidator(FancyValidator):
    """
    width by height validator.
    example input 1: "800x600"
    example output 2: (800, 600)

    example input 2: ""
    example output 2: (None, None)

    example input 3: "0x0"
    example output 3:" (None, None)
    """
    def _to_python(self, value, state=None):
        if not value.strip():
            return (None, None)

        try:
            width, height = value.split('x')
        except ValueError, e:
            raise Invalid(
                _('Value must be in the format wxh; e.g. 200x300'),
                value, state)
        errors = []
        try:
            width = int(width)
        except ValueError, e:
            errors.append(_('Width must be a valid integer'))
Example #29
0
    def _parse(self, url, id, **kwargs):
        """Return metadata for the given URL that matches :attr:`url_pattern`.

        :type url: unicode
        :param url: A remote URL string.

        :param \*\*kwargs: The named matches from the url match object.

        :rtype: dict
        :returns: Any extracted metadata.

        """
        if '?' in url:
            url += '&skin=api'
        else:
            url += '?skin=api'

        req = Request(url)

        try:
            temp_data = urlopen(req)
            xmlstring = temp_data.read()
            try:
                try:
                    xmltree = ElementTree.fromstring(xmlstring)
                except:
                    temp_data.close()
                    raise
            except SyntaxError:
                raise UserStorageError(
                    _('Invalid BlipTV URL. This video does not exist.'))
        except URLError, e:
            log.exception(e)
            raise
Example #30
0
class AddFileForm(ListForm):
    template = 'admin/media/file-add-form.html'
    id = 'add-file-form'
    submit_text = None

    event = events.Admin.AddFileForm

    fields = [
        FileField(
            'file',
            label_text=N_(
                'Select an encoded video or audio file on your computer'),
            validator=FieldStorageUploadConverter(not_empty=False,
                                                  label_text=N_('Upload'))),
        SubmitButton('add_url',
                     default=N_('Add URL'),
                     named_button=True,
                     css_class='btn grey btn-add-url f-rgt'),
        TextField('url',
                  validator=URIValidator,
                  suppress_label=True,
                  attrs=lambda:
                  {'title': _('YouTube, Vimeo, Amazon S3 or any other link')},
                  maxlength=255),
    ]
Example #31
0
def send_support_request(email, url, description, get_vars, post_vars):
    """
    Helper method to send a Support Request email in response to a server
    error.

    Sends to the address configured in the 'email_support_requests' setting,
    if it is configured.

    :param email: The requesting user's email address.
    :type email: unicode

    :param url: The url that the user requested assistance with.
    :type url: unicode

    :param description: The user's description of their problem.
    :type description: unicode

    :param get_vars: The GET variables sent with the failed request.
    :type get_vars: dict of str -> str

    :param post_vars: The POST variables sent with the failed request.
    :type post_vars: dict of str -> str
    """
    send_to = request.settings['email_support_requests']
    if not send_to:
        return

    get_vars = "\n\n  ".join(x + " :  " + get_vars[x] for x in get_vars)
    post_vars = "\n\n  ".join([x + " :  " + post_vars[x] for x in post_vars])
    subject = _('New Support Request: %(email)s') % locals()
    body = _("""A user has asked for support

Email: %(email)s

URL: %(url)s

Description: %(description)s

GET_VARS:
%(get_vars)s


POST_VARS:
%(post_vars)s
""") % locals()

    send(send_to, request.settings['email_send_from'], subject, body)
Example #32
0
def send_support_request(email, url, description, get_vars, post_vars):
    """
    Helper method to send a Support Request email in response to a server
    error.

    Sends to the address configured in the 'email_support_requests' setting,
    if it is configured.

    :param email: The requesting user's email address.
    :type email: unicode

    :param url: The url that the user requested assistance with.
    :type url: unicode

    :param description: The user's description of their problem.
    :type description: unicode

    :param get_vars: The GET variables sent with the failed request.
    :type get_vars: dict of str -> str

    :param post_vars: The POST variables sent with the failed request.
    :type post_vars: dict of str -> str
    """
    send_to = request.settings['email_support_requests']
    if not send_to:
        return

    get_vars = "\n\n  ".join(x + " :  " + get_vars[x] for x in get_vars)
    post_vars = "\n\n  ".join([x + " :  " + post_vars[x] for x in post_vars])
    subject = _('New Support Request: %(email)s') % locals()
    body = _("""A user has asked for support

Email: %(email)s

URL: %(url)s

Description: %(description)s

GET_VARS:
%(get_vars)s


POST_VARS:
%(post_vars)s
""") % locals()

    send(send_to, request.settings['email_send_from'], subject, body)
Example #33
0
    def save_thumb(self, id, thumb, **kwargs):
        """Save a thumbnail uploaded with :class:`~mediadrop.forms.admin.ThumbForm`.

        :param id: Media ID. If ``"new"`` a new Media stub is created.
        :type id: ``int`` or ``"new"``
        :param file: The uploaded file
        :type file: :class:`cgi.FieldStorage` or ``None``
        :rtype: JSON dict
        :returns:
            success
                bool
            message
                Error message, if unsuccessful
            id
                The :attr:`~mediadrop.model.media.Media.id` which is
                important if a new media has just been created.

        """
        if id == 'new':
            media = Media()
            user = request.perm.user
            media.author = Author(user.display_name, user.email_address)
            media.title = os.path.basename(thumb.filename)
            media.slug = get_available_slug(Media, '_stub_' + media.title)
            DBSession.add(media)
            DBSession.flush()
        else:
            media = fetch_row(Media, id)

        try:
            # Create JPEG thumbs
            create_thumbs_for(media, thumb.file, thumb.filename)
            success = True
            message = None
        except IOError, e:
            success = False
            if id == 'new':
                DBSession.delete(media)
            if e.errno == 13:
                message = _('Permission denied, cannot write file')
            elif e.message == 'cannot identify image file':
                message = _('Unsupported image type: %s') \
                    % os.path.splitext(thumb.filename)[1].lstrip('.')
            elif e.message == 'cannot read interlaced PNG files':
                message = _('Interlaced PNGs are not supported.')
            else:
                raise
Example #34
0
 def _to_python(self, value, state=None):
     try:
         return helpers.duration_to_seconds(value)
     except ValueError:
         msg = _('Bad duration formatting, use Hour:Min:Sec')
         # Colons have special meaning in error messages
         msg.replace(':', ':')
         raise Invalid(msg, value, state)
 def _to_python(self, value, state=None):
     try:
         return helpers.duration_to_seconds(value)
     except ValueError:
         msg = _('Bad duration formatting, use Hour:Min:Sec')
         # Colons have special meaning in error messages
         msg.replace(':', ':')
         raise Invalid(msg, value, state)
Example #36
0
    def parse(self, file=None, url=None):
        """Return metadata for the given file or raise an error.

        :type file: :class:`cgi.FieldStorage` or None
        :param file: A freshly uploaded file object.
        :type url: unicode or None
        :param url: A remote URL string.
        :rtype: dict
        :returns: Any extracted metadata.
        :raises UnsuitableEngineError: If file information cannot be parsed.

        """
        if url is None:
            raise UnsuitableEngineError

        if url.startswith('rtmp://'):
            known_server_uris = self._data.setdefault(RTMP_SERVER_URIS, ())

            if RTMP_URI_DIVIDER in url:
                # Allow the user to explicitly mark the server/file separation
                parts = url.split(RTMP_URI_DIVIDER)
                server_uri = parts[0].rstrip('/')
                file_uri = ''.join(parts[1:]).lstrip('/')
                if server_uri not in known_server_uris:
                    known_server_uris.append(server_uri)
            else:
                # Get the rtmp server from our list of known servers or fail
                for server_uri in known_server_uris:
                    if url.startswith(server_uri):
                        file_uri = url[len(server_uri.rstrip('/') + '/'):]
                        break
                else:
                    raise UserStorageError(
                        _('This RTMP server has not been configured. Add it '
                          'by going to Settings > Storage Engines > '
                          'Remote URLs.'))
            unique_id = ''.join((server_uri, RTMP_URI_DIVIDER, file_uri))
        else:
            unique_id = url

        filename = os.path.basename(url)
        name, ext = os.path.splitext(filename)
        ext = unicode(ext).lstrip('.').lower()

        container = guess_container_format(ext)

        # FIXME: Replace guess_container_format with something that takes
        #        into consideration the supported formats of all the custom
        #        players that may be installed.
#        if not container or container == 'unknown':
#            raise UnsuitableEngineError

        return {
            'type': guess_media_type(ext),
            'container': container,
            'display_name': u'%s.%s' % (name, container or ext),
            'unique_id': unique_id,
        }
Example #37
0
    def _to_python(self, value, state=None):
        if not value.strip():
            return (None, None)

        try:
            width, height = value.split('x')
        except ValueError, e:
            raise Invalid(_('Value must be in the format wxh; e.g. 200x300'),
                          value, state)
Example #38
0
    def _to_python(self, value, state):
        id = request.environ['pylons.routes_dict']['id']

        query = DBSession.query(Group).filter_by(group_name=value)
        if id != 'new':
            query = query.filter(Group.group_id != id)

        if query.count() != 0:
            raise Invalid(_('Group name already exists'), value, state)
        return value
    def _to_python(self, value, state=None):
        if not value.strip():
            return (None, None)

        try:
            width, height = value.split('x')
        except ValueError, e:
            raise Invalid(
                _('Value must be in the format wxh; e.g. 200x300'),
                value, state)
Example #40
0
    def save_thumb(self, id, thumb, **values):
        """Save a thumbnail uploaded with :class:`~mediadrop.forms.admin.ThumbForm`.

        :param id: Media ID. If ``"new"`` a new Podcast stub is created.
        :type id: ``int`` or ``"new"``
        :param file: The uploaded file
        :type file: :class:`cgi.FieldStorage` or ``None``
        :rtype: JSON dict
        :returns:
            success
                bool
            message
                Error message, if unsuccessful
            id
                The :attr:`~mediadrop.model.podcasts.Podcast.id` which is
                important if a new podcast has just been created.

        """
        if id == 'new':
            return dict(
                success=False,
                message=
                u'You must first save the podcast before you can upload a thumbnail',
            )

        podcast = fetch_row(Podcast, id)

        try:
            # Create JPEG thumbs
            create_thumbs_for(podcast, thumb.file, thumb.filename)
            success = True
            message = None
        except IOError, e:
            success = False
            if e.errno == 13:
                message = _('Permission denied, cannot write file')
            elif e.message == 'cannot identify image file':
                message = _('Unsupport image type: %s') \
                    % os.path.splitext(thumb.filename)[1].lstrip('.')
            elif e.message == 'cannot read interlaced PNG files':
                message = _('Interlaced PNGs are not supported.')
            else:
                raise
Example #41
0
    def _to_python(self, value, state):
        id = request.environ["pylons.routes_dict"]["id"]

        query = DBSession.query(Group).filter_by(group_name=value)
        if id != "new":
            query = query.filter(Group.group_id != id)

        if query.count() != 0:
            raise Invalid(_("Group name already exists"), value, state)
        return value
Example #42
0
    def _to_python(self, value, state):
        id = request.environ['pylons.routes_dict']['id']

        query = DBSession.query(User).filter_by(user_name=value)
        if id != 'new':
            query = query.filter(User.id != id)

        if query.count() != 0:
            raise Invalid(_('User name already exists'), value, state)
        return value
Example #43
0
    def save_thumb(self, id, thumb, **values):
        """Save a thumbnail uploaded with :class:`~mediadrop.forms.admin.ThumbForm`.

        :param id: Media ID. If ``"new"`` a new Podcast stub is created.
        :type id: ``int`` or ``"new"``
        :param file: The uploaded file
        :type file: :class:`cgi.FieldStorage` or ``None``
        :rtype: JSON dict
        :returns:
            success
                bool
            message
                Error message, if unsuccessful
            id
                The :attr:`~mediadrop.model.podcasts.Podcast.id` which is
                important if a new podcast has just been created.

        """
        if id == 'new':
            return dict(
                success = False,
                message = u'You must first save the podcast before you can upload a thumbnail',
            )

        podcast = fetch_row(Podcast, id)

        try:
            # Create JPEG thumbs
            create_thumbs_for(podcast, thumb.file, thumb.filename)
            success = True
            message = None
        except IOError, e:
            success = False
            if e.errno == 13:
                message = _('Permission denied, cannot write file')
            elif e.message == 'cannot identify image file':
                message = _('Unsupport image type: %s') \
                    % os.path.splitext(thumb.filename)[1].lstrip('.')
            elif e.message == 'cannot read interlaced PNG files':
                message = _('Interlaced PNGs are not supported.')
            else:
                raise
Example #44
0
def doc_link(page=None, anchor="", text=N_("Help"), **kwargs):
    """Return a link (anchor element) to the documentation on the project site.

    XXX: Target attribute is not XHTML compliant.
    """
    attrs = {"href": "http://mediadrop.net/docs/user/%s.html#%s" % (page, anchor), "target": "_blank"}
    if kwargs:
        attrs.update(kwargs)
    attrs_string = " ".join(['%s="%s"' % (key, attrs[key]) for key in attrs])
    out = "<a %s>%s</a>" % (attrs_string, _(text))
    return literal(out)
Example #45
0
def send_media_notification(media_obj):
    """
    Send a creation notification email that a new Media object has been
    created.

    Sends to the address configured in the 'email_media_uploaded' address,
    if one has been created.

    :param media_obj: The media object to send a notification about.
    :type media_obj: :class:`~mediadrop.model.media.Media` instance
    """
    send_to = request.settings['email_media_uploaded']
    if not send_to:
        # media notification emails are disabled!
        return

    edit_url = url_for(controller='/admin/media',
                       action='edit',
                       id=media_obj.id,
                       qualified=True)

    clean_description = strip_xhtml(
        line_break_xhtml(line_break_xhtml(media_obj.description)))

    type = media_obj.type
    title = media_obj.title
    author_name = media_obj.author.name
    author_email = media_obj.author.email
    subject = _('New %(type)s: %(title)s') % locals()
    body = _("""A new %(type)s file has been uploaded!

Title: %(title)s

Author: %(author_name)s (%(author_email)s)

Admin URL: %(edit_url)s

Description: %(clean_description)s
""") % locals()

    send(send_to, request.settings['email_send_from'], subject, body)
Example #46
0
def send_media_notification(media_obj):
    """
    Send a creation notification email that a new Media object has been
    created.

    Sends to the address configured in the 'email_media_uploaded' address,
    if one has been created.

    :param media_obj: The media object to send a notification about.
    :type media_obj: :class:`~mediadrop.model.media.Media` instance
    """
    send_to = request.settings['email_media_uploaded']
    if not send_to:
        # media notification emails are disabled!
        return

    edit_url = url_for(controller='/admin/media', action='edit',
                       id=media_obj.id, qualified=True)

    clean_description = strip_xhtml(line_break_xhtml(line_break_xhtml(media_obj.description)))

    type = media_obj.type
    title = media_obj.title
    author_name = media_obj.author.name
    author_email = media_obj.author.email
    subject = _('New %(type)s: %(title)s') % locals()
    body = _("""A new %(type)s file has been uploaded!

Title: %(title)s

Author: %(author_name)s (%(author_email)s)

Admin URL: %(edit_url)s

Description: %(clean_description)s
""") % locals()

    send(send_to, request.settings['email_send_from'], subject, body)
Example #47
0
def doc_link(page=None, anchor='', text=N_('Help'), **kwargs):
    """Return a link (anchor element) to the documentation on the project site.

    XXX: Target attribute is not XHTML compliant.
    """
    attrs = {
        'href': 'http://mediadrop.video/docs/user/%s.html#%s' % (page, anchor),
        'target': '_blank',
    }
    if kwargs:
        attrs.update(kwargs)
    attrs_string = ' '.join(['%s="%s"' % (key, attrs[key]) for key in attrs])
    out = '<a %s>%s</a>' % (attrs_string, _(text))
    return literal(out)
Example #48
0
def doc_link(page=None, anchor='', text=N_('Help'), **kwargs):
    """Return a link (anchor element) to the documentation on the project site.

    XXX: Target attribute is not XHTML compliant.
    """
    attrs = {
        'href': 'http://mediadrop.net/docs/user/%s.html#%s' % (page, anchor),
        'target': '_blank',
    }
    if kwargs:
        attrs.update(kwargs)
    attrs_string = ' '.join(['%s="%s"' % (key, attrs[key]) for key in attrs])
    out = '<a %s>%s</a>' % (attrs_string, _(text))
    return literal(out)
Example #49
0
    def display_name(self):
        """Return the user-friendly display name for this player class.

        This string is expected to be i18n-ready. Simply wrap it in a
        call to :func:`mediadrop.lib.i18n._`.

        :rtype: unicode
        :returns: A i18n-ready string name.
        """
        if self.player_cls is None:
            # do not break the admin interface (admin/settings/players) if the
            # player is still in the database but the actual player class is not
            # available anymore (this can happen especially for players provided
            # by external plugins.
            return _(u'%s (broken)') % self.name
        return self.player_cls.display_name
Example #50
0
    def display_name(self):
        """Return the user-friendly display name for this player class.

        This string is expected to be i18n-ready. Simply wrap it in a
        call to :func:`mediadrop.lib.i18n._`.

        :rtype: unicode
        :returns: A i18n-ready string name.
        """
        if self.player_cls is None:
            # do not break the admin interface (admin/settings/players) if the
            # player is still in the database but the actual player class is not
            # available anymore (this can happen especially for players provided
            # by external plugins.
            return _(u'%s (broken)') % self.name
        return self.player_cls.display_name
Example #51
0
    def display(self, value=None, **kwargs):
        if value:
            # XXX: First, try to translate this string. This is necessary for
            #      the "Legal Wording" section of the Upload settings. The
            #      default string was extracted correctly but not translated.
            value = _(value)

            value = line_break_xhtml(value)

        # Enable the rich text editor, if dictated by the settings:
        if tiny_mce_condition():
            if 'css_classes' in kwargs:
                kwargs['css_classes'].append('tinymcearea')
            else:
                kwargs['css_classes'] = ['tinymcearea']

        return TextArea.display(self, value, **kwargs)
Example #52
0
    def _verify_upload_integrity(self, file, file_url):
        """Download the given file from the URL and compare the SHA1s.

        :type file: :class:`cgi.FieldStorage`
        :param file: A freshly uploaded file object, that has just been
            sent to the FTP server.

        :type file_url: str
        :param file_url: A publicly accessible URL where the uploaded file
            can be downloaded.

        :returns: `True` if the integrity check succeeds or is disabled.

        :raises FTPUploadError: If the file cannot be downloaded after
            the max number of retries, or if the the downloaded file
            doesn't match the original.

        """
        max_tries = int(self._data[FTP_MAX_INTEGRITY_RETRIES])
        if max_tries < 1:
            return True

        file.seek(0)
        orig_hash = sha1(file.read()).hexdigest()

        # Try to download the file. Increase the number of retries, or the
        # timeout duration, if the server is particularly slow.
        # eg: Akamai usually takes 3-15 seconds to make an uploaded file
        #     available over HTTP.
        for i in xrange(max_tries):
            try:
                temp_file = urlopen(file_url)
                dl_hash = sha1(temp_file.read()).hexdigest()
                temp_file.close()
            except HTTPError, http_err:
                # Don't raise the exception now, wait until all attempts fail
                time.sleep(3)
            else:
                # If the downloaded file matches, success! Otherwise, we can
                # be pretty sure that it got corrupted during FTP transfer.
                if orig_hash == dl_hash:
                    return True
                else:
                    msg = _('The file transferred to your FTP server is '\
                            'corrupted. Please try again.')
                    raise FTPUploadError(msg, None, None)
Example #53
0
    def _verify_upload_integrity(self, file, file_url):
        """Download the given file from the URL and compare the SHA1s.

        :type file: :class:`cgi.FieldStorage`
        :param file: A freshly uploaded file object, that has just been
            sent to the FTP server.

        :type file_url: str
        :param file_url: A publicly accessible URL where the uploaded file
            can be downloaded.

        :returns: `True` if the integrity check succeeds or is disabled.

        :raises FTPUploadError: If the file cannot be downloaded after
            the max number of retries, or if the the downloaded file
            doesn't match the original.

        """
        max_tries = int(self._data[FTP_MAX_INTEGRITY_RETRIES])
        if max_tries < 1:
            return True

        file.seek(0)
        orig_hash = sha1(file.read()).hexdigest()

        # Try to download the file. Increase the number of retries, or the
        # timeout duration, if the server is particularly slow.
        # eg: Akamai usually takes 3-15 seconds to make an uploaded file
        #     available over HTTP.
        for i in xrange(max_tries):
            try:
                temp_file = urlopen(file_url)
                dl_hash = sha1(temp_file.read()).hexdigest()
                temp_file.close()
            except HTTPError, http_err:
                # Don't raise the exception now, wait until all attempts fail
                time.sleep(3)
            else:
                # If the downloaded file matches, success! Otherwise, we can
                # be pretty sure that it got corrupted during FTP transfer.
                if orig_hash == dl_hash:
                    return True
                else:
                    msg = _('The file transferred to your FTP server is '\
                            'corrupted. Please try again.')
                    raise FTPUploadError(msg, None, None)
Example #54
0
    def display(self, value=None, **kwargs):
        if value:
            # XXX: First, try to translate this string. This is necessary for
            #      the "Legal Wording" section of the Upload settings. The
            #      default string was extracted correctly but not translated.
            value = _(value)

            value = line_break_xhtml(value)

        # Enable the rich text editor, if dictated by the settings:
        if tiny_mce_condition():
            if 'css_classes' in kwargs:
                kwargs['css_classes'].append('tinymcearea')
            else:
                kwargs['css_classes'] = ['tinymcearea']

        return TextArea.display(self, value, **kwargs)
Example #55
0
    def store(self, media_file, file=None, url=None, meta=None):
        """Store the given file or URL and return a unique identifier for it.

        :type media_file: :class:`~mediadrop.model.media.MediaFile`
        :param media_file: The associated media file object.

        :type file: :class:`cgi.FieldStorage` or None
        :param file: A freshly uploaded file object.

        :type url: unicode or None
        :param url: A remote URL string.

        :type meta: dict
        :param meta: The metadata returned by :meth:`parse`.

        :rtype: unicode or None
        :returns: The unique ID string. Return None if not generating it here.

        :raises FTPUploadError: If storing the file fails.

        """
        file_name = safe_file_name(media_file, file.filename)

        file_url = os.path.join(self._data[HTTP_DOWNLOAD_URI], file_name)
        upload_dir = self._data[FTP_UPLOAD_DIR]
        stor_cmd = 'STOR ' + file_name

        ftp = self._connect()
        try:
            if upload_dir:
                ftp.cwd(upload_dir)
            ftp.storbinary(stor_cmd, file.file)

            # Raise a FTPUploadError if the file integrity check fails
            # TODO: Delete the file if the integrity check fails
            self._verify_upload_integrity(file.file, file_url)
            ftp.quit()
        except ftp_errors, e:
            log.exception(e)
            ftp.quit()
            msg = _('Could not upload the file from your FTP server: %s')\
                % e.message
            raise FTPUploadError(msg, None, None)
Example #56
0
    def document(self, *args, **kwargs):
        """Render the error document for the general public.

        Essentially, when an error occurs, a second request is initiated for
        the URL ``/error/document``. The URL is set on initialization of the
        :class:`pylons.middleware.StatusCodeRedirect` object, and can be
        overridden in :func:`tg.configuration.add_error_middleware`. Also,
        before this method is called, some potentially useful environ vars
        are set in :meth:`pylons.middleware.StatusCodeRedirect.__call__`
        (access them via :attr:`tg.request.environ`).

        :rtype: Dict
        :returns:
            prefix
                The environ SCRIPT_NAME.
            vars
                A dict containing the first 2 KB of the original request.
            code
                Integer error code thrown by the original request, but it can
                also be overriden by setting ``tg.request.params['code']``.
            message
                A message to display to the user. Pulled from
                ``tg.request.params['message']``.

        """
        request = self._py_object.request
        environ = request.environ
        original_request = environ.get('pylons.original_request', None)
        original_response = environ.get('pylons.original_response', None)
        default_message = '<p>%s</p>' % _("We're sorry but we weren't able "
                                          "to process this request.")

        message = request.params.get('message', default_message)
        message = clean_xhtml(message)

        return dict(
            prefix=environ.get('SCRIPT_NAME', ''),
            code=int(
                request.params.get(
                    'code', getattr(original_response, 'status_int', 500))),
            message=message,
            vars=dict(POST_request=unicode(original_request)[:2048]),
        )
Example #57
0
    def store(self, media_file, file=None, url=None, meta=None):
        """Store the given file or URL and return a unique identifier for it.

        :type media_file: :class:`~mediadrop.model.media.MediaFile`
        :param media_file: The associated media file object.

        :type file: :class:`cgi.FieldStorage` or None
        :param file: A freshly uploaded file object.

        :type url: unicode or None
        :param url: A remote URL string.

        :type meta: dict
        :param meta: The metadata returned by :meth:`parse`.

        :rtype: unicode or None
        :returns: The unique ID string. Return None if not generating it here.

        :raises FTPUploadError: If storing the file fails.

        """
        file_name = safe_file_name(media_file, file.filename)

        file_url = os.path.join(self._data[HTTP_DOWNLOAD_URI], file_name)
        upload_dir = self._data[FTP_UPLOAD_DIR]
        stor_cmd = 'STOR ' + file_name

        ftp = self._connect()
        try:
            if upload_dir:
                ftp.cwd(upload_dir)
            ftp.storbinary(stor_cmd, file.file)

            # Raise a FTPUploadError if the file integrity check fails
            # TODO: Delete the file if the integrity check fails
            self._verify_upload_integrity(file.file, file_url)
            ftp.quit()
        except ftp_errors, e:
            log.exception(e)
            ftp.quit()
            msg = _('Could not upload the file from your FTP server: %s')\
                % e.message
            raise FTPUploadError(msg, None, None)
Example #58
0
    def document(self, *args, **kwargs):
        """Render the error document for the general public.

        Essentially, when an error occurs, a second request is initiated for
        the URL ``/error/document``. The URL is set on initialization of the
        :class:`pylons.middleware.StatusCodeRedirect` object, and can be
        overridden in :func:`tg.configuration.add_error_middleware`. Also,
        before this method is called, some potentially useful environ vars
        are set in :meth:`pylons.middleware.StatusCodeRedirect.__call__`
        (access them via :attr:`tg.request.environ`).

        :rtype: Dict
        :returns:
            prefix
                The environ SCRIPT_NAME.
            vars
                A dict containing the first 2 KB of the original request.
            code
                Integer error code thrown by the original request, but it can
                also be overriden by setting ``tg.request.params['code']``.
            message
                A message to display to the user. Pulled from
                ``tg.request.params['message']``.

        """
        request = self._py_object.request
        environ = request.environ
        original_request = environ.get('pylons.original_request', None)
        original_response = environ.get('pylons.original_response', None)
        default_message = '<p>%s</p>' % _("We're sorry but we weren't able "
                                          "to process this request.")

        message = request.params.get('message', default_message)
        message = clean_xhtml(message)

        return dict(
            prefix = environ.get('SCRIPT_NAME', ''),
            code = int(request.params.get('code', getattr(original_response,
                                                          'status_int', 500))),
            message = message,
            vars = dict(POST_request=unicode(original_request)[:2048]),
        )
Example #59
0
    def index(self, slug=None, **kwargs):
        media = Media.query.published()

        if c.category:
            media = media.in_category(c.category)

            response.feed_links.append(
                (
                    url_for(controller="/categories", action="feed", slug=c.category.slug),
                    _("Latest media in %s") % c.category.name,
                )
            )

        latest = media.order_by(Media.publish_on.desc())
        popular = media.order_by(Media.popularity_points.desc())

        latest = viewable_media(latest)[:5]
        popular = viewable_media(popular.exclude(latest))[:5]

        return dict(latest=latest, popular=popular)