83 lines
3 KiB
Python
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"])
|