def bulk(self, type=None, ids=None, **kwargs): """Perform bulk operations on media items :param type: The type of bulk action to perform (delete) :param ids: A list of IDs. """ if not ids: ids = [] elif not isinstance(ids, list): ids = [ids] if type == 'delete': Category.query.filter(Category.id.in_(ids)).delete(False) DBSession.commit() success = True else: success = False return dict( success = success, ids = ids, parent_options = unicode(category_form.c['parent_id'].display()), )
def insert_settings(defaults): """Insert the given setting if they don't exist yet. XXX: Does not include any support for MultiSetting. This approach won't work for that. We'll need to use sqlalchemy-migrate. :type defaults: list :param defaults: Key and value pairs :rtype: list :returns: Any settings that have just been created. """ inserted = [] existing_settings = set(x[0] for x in DBSession.query(Setting.key) \ .filter(Setting.key \ .in_(key for key, value in defaults))) for key, value in defaults: if key in existing_settings: continue transaction = DBSession.begin_nested() try: s = Setting(key, value) DBSession.add(s) transaction.commit() inserted.append(s) except IntegrityError: transaction.rollback() if inserted: DBSession.commit() return inserted
def _autocommit_commit(req): try: DBSession.commit() except: _autocommit_rollback(req) raise else: _autocommit_fire_callbacks(req, req.commit_callbacks)
def _autocommit_commit(req): from mediacore.model.meta import DBSession try: DBSession.commit() except: _autocommit_rollback(req) raise else: _autocommit_fire_callbacks(req, req.commit_callbacks)
def setUp(self): super(DBTestCase, self).setUp() self.env_dir = self._create_environment_folders() self.pylons_config = setup_environment_and_database(self.env_dir, enabled_plugins=self.enabled_plugins) add_default_data() DBSession.commit() config.push_process_config(self.pylons_config)
def save(self, id, slug, title, author_name, author_email, description, notes, podcast, tags, categories, delete=None, **kwargs): """Save changes or create a new :class:`~mediacore.model.media.Media` instance. Form handler the :meth:`edit` action and the :class:`~mediacore.forms.admin.media.MediaForm`. Redirects back to :meth:`edit` after successful editing and :meth:`index` after successful deletion. """ media = fetch_row(Media, id) if delete: self._delete_media(media) DBSession.commit() redirect(action='index', id=None) if not slug: slug = title elif slug.startswith('_stub_'): slug = slug[len('_stub_'):] if slug != media.slug: media.slug = get_available_slug(Media, slug, media) media.title = title media.author = Author(author_name, author_email) media.description = description media.notes = notes media.podcast_id = podcast media.set_tags(tags) media.set_categories(categories) media.update_status() DBSession.add(media) DBSession.flush() if id == 'new' and not has_thumbs(media): create_default_thumbs_for(media) if request.is_xhr: status_form_xhtml = unicode(update_status_form.display( action=url_for(action='update_status', id=media.id), media=media)) return dict( media_id = media.id, values = {'slug': slug}, link = url_for(action='edit', id=media.id), status_form = status_form_xhtml, ) else: redirect(action='edit', id=media.id)
def save(self, id, slug, title, subtitle, author_name, author_email, description, details, feed, delete=None, **kwargs): """Save changes or create a new :class:`~mediacore.model.podcasts.Podcast` instance. Form handler the :meth:`edit` action and the :class:`~mediacore.forms.admin.podcasts.PodcastForm`. Redirects back to :meth:`edit` after successful editing and :meth:`index` after successful deletion. """ podcast = fetch_row(Podcast, id) if delete: file_paths = thumb_paths(podcast).values() DBSession.delete(podcast) DBSession.commit() helpers.delete_files(file_paths, Podcast._thumb_dir) redirect(action='index', id=None) if not slug: slug = title if slug != podcast.slug: podcast.slug = get_available_slug(Podcast, slug, podcast) podcast.title = title podcast.subtitle = subtitle podcast.author = Author(author_name, author_email) podcast.description = description podcast.copyright = details['copyright'] podcast.category = details['category'] podcast.itunes_url = feed['itunes_url'] podcast.feedburner_url = feed['feedburner_url'] podcast.explicit = { 'yes': True, 'clean': False }.get(details['explicit'], None) if id == 'new': DBSession.add(podcast) DBSession.flush() create_default_thumbs_for(podcast) redirect(action='edit', id=podcast.id)
def main(parser, options, args): if not options.uri: parser.print_help() sys.exit(1) d = feedparser.parse(options.uri) podcast = podcast_from_feed(d, tags=options.tags, save_files=options.save_files) DBSession.commit() print "Created podcast:", podcast print "Imported %d episodes." % len(podcast.media.all()) sys.exit(0)
def save(self, id, email_address, display_name, login_details, delete=None, **kwargs): """Save changes or create a new :class:`~mediacore.model.auth.User` instance. :param id: User ID. If ``"new"`` a new user is created. :type id: ``int`` or ``"new"`` :returns: Redirect back to :meth:`index` after successful save. """ user = fetch_row(User, id) if delete: DBSession.delete(user) redirect(action='index', id=None) user.display_name = display_name user.email_address = email_address user.user_name = login_details['user_name'] password = login_details['password'] if password is not None and password != '': user.password = password if login_details['group']: group = fetch_row(Group, login_details['group']) user.groups = [group] else: user.groups = [] DBSession.add(user) # Check if we're changing the logged in user's own password logged_in_user = request.environ['repoze.who.identity']['user'] if user.user_id == logged_in_user.user_id \ and password is not None and password != '': DBSession.commit() # repoze.who sees the Unauthorized response and clears the cookie, # forcing a fresh login with the new password raise webob.exc.HTTPUnauthorized().exception redirect(action='index', id=None)
def main(parser, options, args): if not options.uri: parser.print_help() sys.exit(1) d = feedparser.parse(options.uri) # FIXME: This script relies on the v0.8.2 models. # It should be updated for v0.9.0 print "I'm sorry, but this RSS import script is out of date." sys.exit(1) podcast = podcast_from_feed(d, tags=options.tags, save_files=options.save_files) DBSession.commit() print "Created podcast:", podcast print "Imported %d episodes." % len(podcast.media.all()) sys.exit(0)
def save( self, id, slug, title, subtitle, author_name, author_email, description, details, feed, delete=None, **kwargs ): """Save changes or create a new :class:`~mediacore.model.podcasts.Podcast` instance. Form handler the :meth:`edit` action and the :class:`~mediacore.forms.admin.podcasts.PodcastForm`. Redirects back to :meth:`edit` after successful editing and :meth:`index` after successful deletion. """ podcast = fetch_row(Podcast, id) if delete: file_paths = thumb_paths(podcast).values() DBSession.delete(podcast) DBSession.commit() helpers.delete_files(file_paths, Podcast._thumb_dir) redirect(action="index", id=None) if not slug: slug = title if slug != podcast.slug: podcast.slug = get_available_slug(Podcast, slug, podcast) podcast.title = title podcast.subtitle = subtitle podcast.author = Author(author_name, author_email) podcast.description = description podcast.copyright = details["copyright"] podcast.category = details["category"] podcast.itunes_url = feed["itunes_url"] podcast.feedburner_url = feed["feedburner_url"] podcast.explicit = {"yes": True, "clean": False}.get(details["explicit"], None) if id == "new": DBSession.add(podcast) DBSession.flush() create_default_thumbs_for(podcast) redirect(action="edit", id=podcast.id)
def main(parser, options): status = 0 output = [] if options.dump_to: s, o = dump_backup_file(options.dump_to) status += s output.append(o.strip()) DBSession.commit() # Commit and start a new transaction if options.read_from: s, o = restore_backup_file(options.read_from) status += s output.append(o.strip()) DBSession.commit() # Commit and start a new transaction if options.dump_files_dir: s, o = backup_files(options.dump_files_dir) status += s output.append(o.strip()) if options.restore_files_dir: s, o = restore_files(options.restore_files_dir) status += s output.append(o.strip()) if not any((options.dump_to, options.read_from, options.dump_files_dir, options.restore_files_dir)): parser.print_help() print "" status, output = 1, ['Incorrect or insufficient arguments provided.\n'] # print output and exit sys.stdout.write("\n---\n".join(output)) print "" if status == 0: print "Operation completed successfully." else: print "Error occurred in operation. You can use the --debug flag for more information." print "" sys.exit(status)
def setUp(self): super(DBTestCase, self).setUp() global_config = { 'plugins': '', # 'debug': 'true', # 'error_email_from': 'paste@localhost', # '__file__': '.../standalone.ini', # 'here': '...', # 'smtp_server': 'localhost' } local_config = { 'sqlalchemy.url': 'sqlite://', # 'full_stack': 'true', # 'image_dir': '.../data/images', # 'enable_gzip': 'true', # 'static_files': 'true', # 'external_template': 'false', # 'sqlalchemy.echo': 'False', # 'file_serve_method': 'default', # 'app_instance_uuid': '', str(uuid.uuid4()) # 'media_dir': '.../data/media', # 'sqlalchemy.pool_recycle': '3600', # 'layout_template': 'layout', # 'sa_auth.cookie_secret': 'superdupersecret', # 'cache_dir': '.../data', # 'external_template_url': 'http://some/valid_genshi_template.html', # 'external_template_timeout': '600', # 'beaker.session.key': 'mediacore', # 'external_template_name': 'external', # 'beaker.session.secret': 'superdupersecret' } self.pylons_config = load_environment(global_config, local_config) metadata.create_all(bind=DBSession.bind, checkfirst=True) add_default_data() DBSession.commit() config.push_process_config(self.pylons_config)
def save(self, id, slug, title, subtitle, author_name, author_email, description, details, feed, delete=None, **kwargs): """Save changes or create a new :class:`~mediacore.model.podcasts.Podcast` instance. Form handler the :meth:`edit` action and the :class:`~mediacore.forms.admin.podcasts.PodcastForm`. Redirects back to :meth:`edit` after successful editing and :meth:`index` after successful deletion. """ podcast = fetch_row(Podcast, id) if delete: DBSession.delete(podcast) DBSession.commit() delete_thumbs(podcast) redirect(action='index', id=None) if not slug: slug = title if slug != podcast.slug: podcast.slug = get_available_slug(Podcast, slug, podcast) podcast.title = title podcast.subtitle = subtitle podcast.author = Author(author_name, author_email) podcast.description = description podcast.copyright = details['copyright'] podcast.category = details['category'] podcast.itunes_url = feed['itunes_url'] podcast.feedburner_url = feed['feedburner_url'] podcast.explicit = {'yes': True, 'clean': False}.get(details['explicit'], None) if id == 'new': DBSession.add(podcast) DBSession.flush() create_default_thumbs_for(podcast) redirect(action='edit', id=podcast.id)
def insert_settings(defaults): """Insert the given setting if they don't exist yet. XXX: Does not include any support for MultiSetting. This approach won't work for that. We'll need to use sqlalchemy-migrate. :type defaults: list :param defaults: Key and value pairs :rtype: list :returns: Any settings that have just been created. """ inserted = [] try: settings_query = DBSession.query(Setting.key)\ .filter(Setting.key.in_([key for key, value in defaults])) existing_settings = set(x[0] for x in settings_query) except ProgrammingError: # If we are running paster setup-app on a fresh database with a # plugin which tries to use this function every time the # Environment.loaded event fires, the settings table will not # exist and this exception will be thrown, but its safe to ignore. # The settings will be created the next time the event fires, # which will likely be the first time the app server starts up. return inserted for key, value in defaults: if key in existing_settings: continue transaction = DBSession.begin_nested() try: s = Setting(key, value) DBSession.add(s) transaction.commit() inserted.append(s) except IntegrityError: transaction.rollback() if inserted: DBSession.commit() return inserted
def save(self, id, email_address, display_name, login_details, delete=None, **kwargs): """Save changes or create a new :class:`~mediacore.model.auth.User` instance. :param id: User ID. If ``"new"`` a new user is created. :type id: ``int`` or ``"new"`` :returns: Redirect back to :meth:`index` after successful save. """ user = fetch_row(User, id) if delete: DBSession.delete(user) redirect(action="index", id=None) user.display_name = display_name user.email_address = email_address user.user_name = login_details["user_name"] password = login_details["password"] if password is not None and password != "": user.password = password if login_details["groups"]: query = DBSession.query(Group).filter(Group.group_id.in_(login_details["groups"])) user.groups = list(query.all()) else: user.groups = [] DBSession.add(user) # Check if we're changing the logged in user's own password if user.id == request.perm.user.id and password is not None and password != "": DBSession.commit() # repoze.who sees the Unauthorized response and clears the cookie, # forcing a fresh login with the new password raise webob.exc.HTTPUnauthorized().exception redirect(action="index", id=None)
def __call__(self, environ, start_response): """Commit or rollback the DBSession for every request. Your controller may override this method and have it call :meth:`BareBonesController.__call__` directly to avoid this transaction management. """ try: app_iter = BareBonesController.__call__(self, environ, start_response) except: # An unexpected error has occurred that the WebError will catch DBSession.rollback() raise else: # webob.exc.HTTPException's are caught and turned into a regular # responses in WSGIController._inspect_call. Veto error responses: if 200 <= response.status_int < 400: DBSession.commit() else: DBSession.rollback() return app_iter
def main(parser, options): if options.dump_to: status, output = dump_backup_file(options.dump_to) if options.read_from: remove_unnecessary_files() status, output = restore_backup_file(options.read_from) DBSession.commit() # Create a new transaction, to reload the tables for restore_necessary_files() if not options.dump_to and not options.read_from: parser.print_help() print "" status, output = 1, 'Incorrect or insufficient arguments provided.\n' # print output and exit sys.stdout.write(output.strip()) print "" if status == 0: print "Operation completed successfully." else: print "Error occurred in operation. You can use the --debug flag for more information." print "" sys.exit(status)
def save(self, id, slug, title, author_name, author_email, description, notes, podcast, tags, categories, delete=None, **kwargs): """Save changes or create a new :class:`~mediacore.model.media.Media` instance. Form handler the :meth:`edit` action and the :class:`~mediacore.forms.admin.media.MediaForm`. Redirects back to :meth:`edit` after successful editing and :meth:`index` after successful deletion. """ media = fetch_row(Media, id) if delete: file_paths = thumb_paths(media).values() for f in media.files: file_paths.append(f.file_path) # Remove the file from the session so that SQLAlchemy doesn't # try to issue an UPDATE to set the MediaFile.media_id to None. # The database ON DELETE CASCADE handles everything for us. DBSession.expunge(f) DBSession.delete(media) DBSession.commit() helpers.delete_files(file_paths, Media._thumb_dir) redirect(action='index', id=None) if not slug: slug = title elif slug.startswith('_stub_'): slug = slug[len('_stub_'):] if slug != media.slug: media.slug = get_available_slug(Media, slug, media) media.title = title media.author = Author(author_name, author_email) media.description = description media.notes = notes media.podcast_id = podcast media.set_tags(tags) media.set_categories(categories) media.update_status() DBSession.add(media) DBSession.flush() if id == 'new': create_default_thumbs_for(media) if request.is_xhr: status_form_xhtml = unicode(update_status_form.display( action=url_for(action='update_status', id=media.id), media=media)) return dict( media_id = media.id, values = {'slug': slug}, link = url_for(action='edit', id=media.id), status_form = status_form_xhtml, ) else: redirect(action='edit', id=media.id)
def edit_file(self, id, file_id, file_type=None, duration=None, delete=None, **kwargs): """Save action for the :class:`~mediacore.forms.admin.media.EditFileForm`. Changes or delets a :class:`~mediacore.model.media.MediaFile`. TODO: Use the form validators to validate this form. We only POST one field at a time, so the validate decorator doesn't work, because it doesn't work for partial validation, because none of the kwargs are updated if an Invalid exception is raised by any validator. :param id: Media ID :type id: :class:`int` :rtype: JSON dict :returns: success bool message Error message, if unsuccessful status_form Rendered XHTML for the status form, updated to reflect the changes made. """ media = fetch_row(Media, id) data = dict(success=False) try: file = [file for file in media.files if file.id == file_id][0] except IndexError: file = None if file is None: data['message'] = _('File "%s" does not exist.') % file_id elif file_type: file.type = file_type data['success'] = True elif duration is not None: try: duration = helpers.duration_to_seconds(duration) except ValueError: data['message'] = _('Bad duration formatting, use Hour:Min:Sec') else: media.duration = duration data['success'] = True data['duration'] = helpers.duration_from_seconds(duration) elif delete: file_path = file.file_path DBSession.delete(file) DBSession.commit() if file_path: helpers.delete_files([file_path], Media._thumb_dir) media = fetch_row(Media, id) data['success'] = True else: data['message'] = _('No action to perform.') if data['success']: data['file_type'] = file.type media.update_status() DBSession.flush() # Return the rendered widget for injection status_form_xhtml = unicode(update_status_form.display( action=url_for(action='update_status'), media=media)) data['status_form'] = status_form_xhtml return data