lib.itmens/journal/importers/opml.py

83 lines
3 KiB
Python

import listparser
from django.utils.translation import gettext as _
from loguru import logger
from catalog.common import *
from catalog.common.downloaders import *
from catalog.sites.rss import RSS
from journal.models import *
from users.models.task import Task
class OPMLImporter(Task):
class Meta:
app_label = "journal" # workaround bug in TypedModel
TaskQueue = "import"
DefaultMetadata = {
"total": 0,
"mode": 0,
"processed": 0,
"skipped": 0,
"imported": 0,
"failed": 0,
"visibility": 0,
"failed_urls": [],
"file": None,
}
@classmethod
def validate_file(cls, f):
try:
return bool(listparser.parse(f.read()).feeds)
except Exception:
return False
def run(self):
with open(self.metadata["file"], "r") as f:
feeds = listparser.parse(f.read()).feeds
self.metadata["total"] = len(feeds)
self.message = f"Processing {self.metadata['total']} feeds."
self.save(update_fields=["metadata", "message"])
collection = None
if self.metadata["mode"] == 1:
title = _("{username}'s podcast subscriptions").format(
username=self.user.display_name
)
collection = Collection.objects.create(
owner=self.user.identity,
title=title,
visibility=self.metadata["visibility"],
)
for feed in feeds:
logger.info(f"{self.user} import {feed.url}")
try:
res = RSS(feed.url).get_resource_ready()
except Exception:
res = None
if not res or not res.item:
logger.warning(f"{self.user} feed error {feed.url}")
self.metadata["failed"] += 1
continue
item = res.item
if self.metadata["mode"] == 0:
mark = Mark(self.user.identity, item)
if mark.shelfmember:
logger.info(f"{self.user} marked, skip {feed.url}")
self.metadata["skipped"] += 1
else:
self.metadata["imported"] += 1
mark.update(
ShelfType.PROGRESS,
None,
None,
visibility=self.metadata["visibility"],
)
elif self.metadata["mode"] == 1 and collection:
self.metadata["imported"] += 1
collection.append_item(item)
self.metadata["processed"] += 1
self.save(update_fields=["metadata"])
self.message = f"{self.metadata['imported']} feeds imported, {self.metadata['skipped']} skipped, {self.metadata['failed']} failed."
self.save(update_fields=["message"])