def handle(self, *args, **options): path = os.path.abspath(options['path']) self.update = options['update'] self.encoding = options['encoding'] self.dry_run = options['dry_run'] self.report = Reporter(options['verbosity']) if not os.path.exists(path): self.abort('Path does not exist: {}'.format(path)) self.ROOT = os.path.dirname(path) rows = list(self.load(path)) bar = Bar(total=sum(1 for i in rows)) for row in bar.iter(rows): self.add(row) print(self.report) if self.report.has_errors(): sys.exit(1)
class Command(BaseCommand): help = ('Batch import medias from CSV metadata. CSV file must contain ' 'columns "title", "summary", "path", "credits", "lang". Optional ' 'columns are , "preview", "kind", "tags".') def add_arguments(self, parser): parser.add_argument('path', help='Path to CSV metadata.') parser.add_argument('--update', action='store_true', default=False, help='Update instance when document with same ' 'title and kind is found in db.') parser.add_argument('--encoding', default='utf-8', help='Define csv encoding.') parser.add_argument('--dry-run', action='store_true', help='Only check data, do not save.') def abort(self, msg): self.stderr.write(msg) sys.exit(1) def load(self, path): with codecs.open(path, 'r', encoding=self.encoding) as f: content = f.read() try: dialect = csv.Sniffer().sniff(content) except csv.Error: dialect = csv.unix_dialect() return csv.DictReader(content.splitlines(), dialect=dialect) def handle(self, *args, **options): path = os.path.abspath(options['path']) self.update = options['update'] self.encoding = options['encoding'] self.dry_run = options['dry_run'] self.report = Reporter(options['verbosity']) if not os.path.exists(path): self.abort('Path does not exist: {}'.format(path)) self.ROOT = os.path.dirname(path) rows = list(self.load(path)) bar = Bar(total=sum(1 for i in rows)) for row in bar.iter(rows): self.add(row) print(self.report) if self.report.has_errors(): sys.exit(1) def add(self, metadata): title = metadata.get('title').strip() if not title: self.report.error('Missing title', metadata) return title = smart_truncate(title) metadata['title'] = title metadata['lang'] = metadata.get('lang', '').strip().lower() if not metadata['lang']: self.report.error('Missing lang', metadata) return original = metadata.get('path') if not original: self.report.error('Missing path', metadata) return kind = metadata.get('kind', '').strip().lower() content_type, encoding = mimetypes.guess_type(original) if not kind or not hasattr(Document, kind.upper()): kind = guess_kind_from_content_type(content_type) or Document.OTHER metadata['kind'] = kind instance = Document.objects.filter(title=title, kind=kind).last() if instance and not self.update: self.report.warning('Document exists (Use --update for reimport)', title) return original_path = os.path.join(self.ROOT, original) preview = metadata.get('preview') preview_path = os.path.join(self.ROOT, preview) if preview else None of = pf = None try: try: of = open(original_path, 'rb') except OSError as e: self.report.error("Cannot open path", e) if preview: try: pf = open(preview_path, 'rb') except OSError as e: self.report.error("Cannot open path", e) if not of: return if preview and not pf: return original = File(of, name=original) if pf: preview = File(pf, name=preview) self.save(metadata, original, instance, preview) else: self.save(metadata, original, instance) finally: if of is not None: of.close() if pf is not None: pf.close() def save(self, metadata, original, instance, preview=None): files = dict(original=original, preview=preview) form = DocumentForm(data=metadata, files=files, instance=instance) if form.is_valid(): if self.dry_run: self.report.notice('Metadata valid', metadata['title']) else: doc = form.save() self.report.notice('Uploaded media', str(doc)) else: for field, error in form.errors.items(): self.report.error('{}: {}'.format(field, error.as_text()), metadata)
class Command(BaseCommand): help = ('Batch import medias from CSV metadata. CSV file must contain ' 'columns "title", "summary", "path", "credits". Optional columns ' 'are "lang", "preview", "kind", "tags".') def add_arguments(self, parser): parser.add_argument('path', help='Path to CSV metadata.') parser.add_argument('--update', action='store_true', default=False, help='Update instance when document with same ' 'title and kind is found in db.') parser.add_argument('--encoding', default='utf-8', help='Define csv encoding.') parser.add_argument('--dry-run', action='store_true', help='Only check data, do not save.') def abort(self, msg): self.stderr.write(msg) sys.exit(1) def load(self, path): with codecs.open(path, 'r', encoding=self.encoding) as f: content = f.read() try: dialect = csv.Sniffer().sniff(content) except csv.Error: dialect = csv.unix_dialect() return csv.DictReader(content.splitlines(), dialect=dialect) def handle(self, *args, **options): path = os.path.abspath(options['path']) self.update = options['update'] self.encoding = options['encoding'] self.dry_run = options['dry_run'] self.report = Reporter(options['verbosity']) if not os.path.exists(path): self.abort('Path does not exist: {}'.format(path)) self.ROOT = os.path.dirname(path) rows = list(self.load(path)) bar = Bar(total=sum(1 for i in rows)) for row in bar.iter(rows): self.add(row) print(self.report) if self.report.has_errors(): sys.exit(1) def add(self, metadata): title = metadata.get('title').strip() if not title: self.report.error('Missing title', metadata) return title = smart_truncate(title) metadata['title'] = title lang = metadata.get('lang', '').strip().lower() if not lang: metadata['lang'] = settings.LANGUAGE_CODE original = metadata.get('path') if not original: self.report.error('Missing path', metadata) return kind = metadata.get('kind', '').strip().lower() content_type, encoding = mimetypes.guess_type(original) if not kind or not hasattr(Document, kind.upper()): kind = guess_kind_from_content_type(content_type) or Document.OTHER metadata['kind'] = kind instance = Document.objects.filter(title=title, kind=kind).last() if instance and not self.update: self.report.warning('Document exists (Use --update for reimport)', title) return original_path = os.path.join(self.ROOT, original) preview = metadata.get('preview') preview_path = os.path.join(self.ROOT, preview) if preview else None of = pf = None try: try: of = open(original_path, 'rb') except OSError as e: self.report.error("Cannot open path", e) if preview: try: pf = open(preview_path, 'rb') except OSError as e: self.report.error("Cannot open path", e) if not of: return if preview and not pf: return original = File(of, name=original) if pf: preview = File(pf, name=preview) self.save(metadata, original, instance, preview) else: self.save(metadata, original, instance) finally: if of is not None: of.close() if pf is not None: pf.close() def save(self, metadata, original, instance, preview=None): files = dict(original=original, preview=preview) form = DocumentForm(data=metadata, files=files, instance=instance) if form.is_valid(): if self.dry_run: self.report.notice('Metadata valid', metadata['title']) else: doc = form.save() self.report.notice('Uploaded media', str(doc)) else: for field, error in form.errors.items(): self.report.error('{}: {}'.format(field, error.as_text()), metadata)