def _add_new_media_file(media, original_filename, file): # FIXME: I think this will raise a KeyError if the uploaded # file doesn't have an extension. file_ext = os.path.splitext(original_filename)[1].lower()[1:] # set the file paths depending on the file type media_file = MediaFile() media_file.type = file_ext media_file.url = 'dummy_url' # model requires that url not NULL media_file.is_original = True media_file.enable_player = media_file.is_playable media_file.enable_feed = not media_file.is_embeddable media_file.size = os.fstat(file.fileno())[6] # update media relations media.files.append(media_file) # add the media file (and its media, if new) to the database to get IDs DBSession.add(media_file) DBSession.flush() # copy the file to its permanent location file_name = '%d_%d_%s.%s' % (media.id, media_file.id, media.slug, file_ext) file_url = _store_media_file(file, file_name) media_file.url = file_url return media_file
def add_file(self, id, file=None, url=None, **kwargs): """Save action for the :class:`~mediacore.forms.media.AddFileForm`. Creates a new :class:`~mediacore.model.media.MediaFile` from the uploaded file or the local or remote URL. :param id: Media ID. If ``"new"`` a new Media stub is created with :func:`~mediacore.model.media.create_media_stub`. :type id: :class:`int` or ``"new"`` :param file: The uploaded file :type file: :class:`cgi.FieldStorage` or ``None`` :param url: A URL to a recognizable audio or video file :type url: :class:`unicode` or ``None`` :rtype: JSON dict :returns: success bool message Error message, if unsuccessful media_id The :attr:`~mediacore.model.media.Media.id` which is important if new media has just been created. file_id The :attr:`~mediacore.model.media.MediaFile.id` for the newly created file. edit_form The rendered XHTML :class:`~mediacore.forms.media.EditFileForm` for this file. status_form The rendered XHTML :class:`~mediacore.forms.media.UpdateStatusForm` """ if id == 'new': media = create_media_stub() else: media = fetch_row(Media, id, incl_trash=True) try: if file is not None: # Create a media object, add it to the video, and store the file permanently. media_file = _add_new_media_file(media, file.filename, file.file) elif url: media_file = MediaFile() # Parse the URL checking for known embeddables like YouTube for type, info in config.embeddable_filetypes.iteritems(): match = re.match(info['pattern'], url) if match: media_file.type = type media_file.url = match.group('id') media_file.enable_feed = False break else: # Check for types we can play ourselves type = os.path.splitext(url)[1].lower()[1:] for playable_types in config.playable_types.itervalues(): if type in playable_types: media_file.type = type media_file.url = url break else: raise Exception, 'Unsupported URL %s' % url else: raise Exception, 'Given no action to perform.' media.files.append(media_file) media.update_type() media.update_status() DBSession.add(media) DBSession.flush() # Render some widgets so the XHTML can be injected into the page edit_form_xhtml = unicode(edit_file_form.display( action=url_for(action='edit_file', id=media.id), file=media_file)) status_form_xhtml = unicode(update_status_form.display( action=url_for(action='update_status', id=media.id), media=media)) return dict( success = True, media_id = media.id, file_id = media_file.id, edit_form = edit_form_xhtml, status_form = status_form_xhtml, ) except Exception, e: return dict( success = False, message = e.message, )