2022-03-26 20:07:35 +00:00
|
|
|
import base64
|
|
|
|
import argparse
|
|
|
|
import os
|
|
|
|
import sqlite3
|
|
|
|
import textwrap
|
|
|
|
import sys
|
|
|
|
|
|
|
|
from voussoirkit import betterhelp
|
|
|
|
from voussoirkit import pipeable
|
|
|
|
from voussoirkit import vlogging
|
|
|
|
from voussoirkit import interactive
|
|
|
|
from voussoirkit import niceprints
|
|
|
|
|
|
|
|
import bringrss
|
|
|
|
|
|
|
|
log = vlogging.getLogger(__name__, 'import_quiterss')
|
|
|
|
|
|
|
|
def import_quiterss_argparse(args):
|
|
|
|
if not os.path.isfile(args.feedsdb):
|
2022-07-16 05:12:58 +00:00
|
|
|
pipeable.stderr(f'{args.feedsdb} is not a file.')
|
2022-03-26 20:07:35 +00:00
|
|
|
return 1
|
|
|
|
|
2022-07-16 05:12:58 +00:00
|
|
|
bringdb = bringrss.bringdb.BringDB.closest_bringdb()
|
2022-03-26 20:07:35 +00:00
|
|
|
message = textwrap.dedent('''
|
|
|
|
You should make a backup of your BringRSS database before doing this.
|
|
|
|
Do not perform this import more than once. We will not search for duplicate data.
|
|
|
|
If you need to try the import again, restore from your backup first.
|
|
|
|
|
|
|
|
Only feeds and news are imported. Filters are not. Sorry for the inconvenience.
|
|
|
|
''').strip()
|
|
|
|
|
|
|
|
pipeable.stderr()
|
|
|
|
pipeable.stderr(niceprints.in_box(message, title='Importing from QuiteRSS'))
|
|
|
|
|
|
|
|
if not interactive.getpermission('Are you ready?'):
|
|
|
|
return 1
|
|
|
|
|
2022-07-16 05:12:58 +00:00
|
|
|
with bringdb.transaction:
|
|
|
|
import_quiterss(feedsdb, bringdb)
|
|
|
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
def import_quiterss(feedsdb, bringdb):
|
|
|
|
quite_sql = sqlite3.connect(feedsdb)
|
2022-03-26 20:07:35 +00:00
|
|
|
quite_sql.row_factory = sqlite3.Row
|
|
|
|
feed_id_map = {}
|
|
|
|
query = '''
|
|
|
|
SELECT
|
|
|
|
id,
|
|
|
|
text,
|
|
|
|
description,
|
|
|
|
xmlUrl,
|
|
|
|
htmlUrl,
|
|
|
|
image,
|
|
|
|
parentId,
|
|
|
|
rowToParent,
|
|
|
|
updateIntervalEnable,
|
|
|
|
updateInterval,
|
|
|
|
updateIntervalType,
|
|
|
|
disableUpdate
|
|
|
|
FROM feeds;
|
|
|
|
'''
|
|
|
|
feeds = list(quite_sql.execute(query))
|
|
|
|
while feeds:
|
|
|
|
feed = feeds.pop(0)
|
|
|
|
quite_id = feed['id']
|
|
|
|
if feed['parentId'] == 0:
|
|
|
|
parent = None
|
|
|
|
elif feed['parentId'] in feed_id_map:
|
|
|
|
parent = feed_id_map[feed['parentId']]
|
|
|
|
else:
|
|
|
|
# The parent is probably somewhere else in the list, let's come
|
|
|
|
# back to it later.
|
|
|
|
feeds.append(feed)
|
|
|
|
continue
|
|
|
|
|
|
|
|
title = feed['text']
|
|
|
|
description = feed['description']
|
|
|
|
rss_url = feed['xmlUrl']
|
|
|
|
web_url = feed['htmlUrl']
|
|
|
|
# rowToParent is zero-indexed, we use 1-index.
|
|
|
|
if parent:
|
|
|
|
# If the parent has ui_order_rank of 8, then a child with rowToParent
|
|
|
|
# of 4 will be 8.0004 and everything will get reassigned later.
|
|
|
|
ui_order_rank = parent.ui_order_rank + ((feed['rowToParent'] + 1) / 10000)
|
|
|
|
else:
|
|
|
|
ui_order_rank = feed['rowToParent'] + 1
|
|
|
|
|
|
|
|
if feed['updateIntervalEnable'] == 1 and feed['updateInterval'] > 0:
|
|
|
|
if feed['updateIntervalType'] in {1, "1"}:
|
|
|
|
# hours
|
|
|
|
autorefresh_interval = feed['updateInterval'] * 3600
|
|
|
|
elif feed['updateIntervalType'] in {0, "0"}:
|
|
|
|
# minutes
|
|
|
|
autorefresh_interval = feed['updateInterval'] * 60
|
|
|
|
elif feed['updateIntervalType'] in {-1, "-1"}:
|
|
|
|
# seconds
|
|
|
|
autorefresh_interval = feed['updateInterval']
|
|
|
|
else:
|
|
|
|
autorefresh_interval = 0
|
|
|
|
|
|
|
|
if feed['disableUpdate'] == 1:
|
|
|
|
refresh_with_others = False
|
|
|
|
autorefresh_interval = min(autorefresh_interval, -1 * autorefresh_interval)
|
|
|
|
else:
|
|
|
|
refresh_with_others = True
|
|
|
|
|
|
|
|
isolate_guids = False
|
|
|
|
|
|
|
|
if feed['image']:
|
|
|
|
icon = base64.b64decode(feed['image'])
|
|
|
|
else:
|
|
|
|
icon = None
|
|
|
|
|
|
|
|
feed = bringdb.add_feed(
|
|
|
|
autorefresh_interval=autorefresh_interval,
|
|
|
|
description=description,
|
|
|
|
icon=icon,
|
|
|
|
isolate_guids=isolate_guids,
|
|
|
|
parent=parent,
|
|
|
|
refresh_with_others=refresh_with_others,
|
|
|
|
rss_url=rss_url,
|
|
|
|
title=title,
|
|
|
|
ui_order_rank=ui_order_rank,
|
|
|
|
web_url=web_url,
|
|
|
|
)
|
|
|
|
feed_id_map[quite_id] = feed
|
|
|
|
|
|
|
|
bringdb.reassign_ui_order_ranks()
|
|
|
|
|
|
|
|
query = '''
|
|
|
|
SELECT
|
|
|
|
feedId,
|
|
|
|
guid,
|
|
|
|
description,
|
|
|
|
title,
|
|
|
|
published,
|
|
|
|
modified,
|
|
|
|
author_name,
|
|
|
|
author_uri,
|
|
|
|
author_email,
|
|
|
|
read,
|
|
|
|
comments,
|
|
|
|
enclosure_length,
|
|
|
|
enclosure_type,
|
|
|
|
enclosure_url,
|
|
|
|
link_href
|
|
|
|
FROM news
|
|
|
|
WHERE deleted == 0;
|
|
|
|
'''
|
|
|
|
newss = list(quite_sql.execute(query))
|
|
|
|
for news in newss:
|
|
|
|
quite_read = news['read']
|
|
|
|
|
|
|
|
authors = [{
|
|
|
|
'name': news['author_name'],
|
|
|
|
'email': news['author_email'],
|
|
|
|
'uri': news['author_uri'],
|
|
|
|
}]
|
|
|
|
enclosures = [{
|
|
|
|
'url': news['enclosure_url'],
|
|
|
|
'type': news['enclosure_type'],
|
|
|
|
'size': int(news['enclosure_length']) if news.get('enclosure_length') else None
|
|
|
|
}]
|
|
|
|
|
|
|
|
news = bringdb.add_news(
|
|
|
|
authors=authors,
|
|
|
|
comments_url=news['comments'],
|
|
|
|
enclosures=enclosures,
|
|
|
|
feed=feed_id_map[news['feedId']],
|
|
|
|
published=news['published'],
|
|
|
|
rss_guid=news['guid'],
|
|
|
|
text=news['description'],
|
|
|
|
title=news['title'],
|
|
|
|
updated=news['modified'] or news['published'],
|
|
|
|
web_url=news['link_href'],
|
|
|
|
)
|
|
|
|
if quite_read > 0:
|
|
|
|
news.set_read(True)
|
|
|
|
|
|
|
|
@vlogging.main_decorator
|
|
|
|
def main(argv):
|
|
|
|
parser = argparse.ArgumentParser(
|
|
|
|
description='''
|
|
|
|
Import feeds and news from QuiteRSS to BringRSS.
|
|
|
|
''',
|
|
|
|
)
|
|
|
|
parser.add_argument(
|
|
|
|
'feedsdb',
|
|
|
|
help='''
|
|
|
|
Filepath to the feeds.db in your QuiteRSS folder.
|
|
|
|
''',
|
|
|
|
)
|
|
|
|
parser.set_defaults(func=import_quiterss_argparse)
|
|
|
|
|
|
|
|
return betterhelp.go(parser, argv)
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
raise SystemExit(main(sys.argv[1:]))
|