def main(opts=None, cli_args=None, log_stream=sys.stdout): if opts is None: opts = argparse_get_parser()\ .parse_args(sys.argv[1:] if cli_args is None else cli_args) else: parser = None # to check and re-raise django CommandError if not isinstance(opts, argparse.Namespace): opts = argparse.Namespace(**opts) assert cli_args is None, cli_args command_logger_setup( log, opts, stream=log_stream, verbose_level=logging.EXTRA ) # Process --interval-parameters, --commit-interval try: if isinstance(opts.interval_parameters, types.StringTypes): params = cli_defaults['interval_parameters'].copy() for v in opts.interval_parameters.split(':'): k, vs = v.split('=') if k not in params: raise CommandError('Unrecognized interval parameter: {0}'.format(k)) if vs.lower() == 'true': v = True elif vs.lower() == 'false': v = False elif vs.lower() == 'none': v = 0 else: try: v = float(vs.rstrip('sdh')) except ValueError: raise CommandError('Unrecognized interval parameter value: {0}'.format(vs)) if vs.endswith('h'): v /= float(24) elif vs.endswith('s'): v /= float(3600 * 24) params[k] = v opts.interval_parameters = params if opts.commit_interval: if opts.commit_interval.isdigit(): opts.commit_interval = int(opts.commit_interval) elif opts.commit_interval.endswith('s'): opts.commit_interval = timedelta(0, int(opts.commit_interval[:-1])) else: raise CommandError( 'Invalid' ' interval value: {0}'.format(opts.commit_interval) ) if opts.report_after: try: v = float(opts.report_after.rstrip('sdh')) except ValueError: raise CommandError('Unrecognized timespan value: {0}'.format(opts.report_after)) if opts.report_after.endswith('h'): v /= float(24) elif opts.report_after.endswith('s'): v /= float(3600 * 24) opts.report_after = timedelta(v) except CommandError as err: if not parser: raise parser.error(*err.args) # Make sure logging won't choke on encoding import codecs codec = codecs.getwriter('utf-8') sys.stdout = codec(sys.stdout) sys.stderr = codec(sys.stderr) bulk_update(opts)
def handle(self, **opts): opts = type( b'Opts', (object, ), dict((k.replace('-', '_'), v) for k, v in opts.viewitems())) log = logging.getLogger('feedjack.purge') command_logger_setup(log, opts, stream=self.stdout) if not opts.feed and not opts.site: feeds = set(models.Feed.all()) log.info('All feeds will be affected (%s)', len(feeds)) else: feeds = set() if opts.feed: try: feeds.update( models.Feed.objects.get_by_string(name) for name in opts.feed) except (models.ObjectDoesNotExist, models.MultipleObjectsReturned) as err: raise CommandError(unicode(err)) if opts.site: try: sites = list( models.Site.objects.get_by_string(name) for name in opts.site) except (models.ObjectDoesNotExist, models.MultipleObjectsReturned) as err: raise CommandError(unicode(err)) for site in sites: feeds.update(site.feeds) if log.isEnabledFor(logging.INFO): if log.isEnabledFor(logging.DEBUG): log.debug('List of affected feeds (%s):', len(feeds)) for feed in sorted(feeds, key=op.attrgetter('pk')): log.debug(' - [%s] %s', feed.pk, feed) else: log.info( 'Number of affected feeds: %s (listed with more verbose logging)', len(feeds)) if opts.type == 'by-age': ts0, ts = timezone.localtime(timezone.now()), parse_timestamp( opts.time_spec) log.info('Parsed time spec %r as %s (delta: %s)', opts.time_spec, ts, naturaltime_diff(ts, ts0)) ts_field = 'date_{}'.format(opts.timestamp_type) ts_field_check = { '{}__{}'.format(ts_field, 'gt' if opts.newer else 'lt'): ts } log.debug('Timestamp field check: %s', ts_field_check) posts = models.Post.objects.filter(feed__in=feeds, **ts_field_check) if log.isEnabledFor(logging.INFO): if log.isEnabledFor(logging.DEBUG): log.debug('List of selected Posts (%s):', posts.count()) for post in posts.order_by('pk'): log.debug(' - [%s] %s', post.pk, post) else: log.info( 'Selected %s Post object(s) for' ' cleanup (listed with more verbose logging)', posts.count()) if not opts.dry_run: show_count = log.isEnabledFor(logging.INFO) and posts.count() if show_count: log.info('Removing %s entries', show_count) ts0 = time.time() posts.delete() if show_count: log.info('Finished removal of %s entries (time: %.2fs)', show_count, time.time() - ts0) else: raise ValueError(post.type)