Add support for updating articles

master
Felix Stupp 2 years ago
parent 89e06303d9
commit c9a33d0bc3
Signed by: zocker
GPG Key ID: 93E1BD26F6B02FB7

@ -8,14 +8,31 @@ import json
import os import os
import re import re
import sys import sys
from typing import Sequence
import xdg.BaseDirectory import xdg.BaseDirectory
from tinytinypy import Connection from tinytinypy import Connection, UpdateMode, UpdateField
APP_NAME = "tinytinypy" # For default config directories APP_NAME = "tinytinypy" # For default config directories
UPDATE_MODES = {
"false": UpdateMode.SET_TO_FALSE,
"true": UpdateMode.SET_TO_TRUE,
"toggle": UpdateMode.TOGGLE,
}
UPDATE_FIELDS = {
"published": UpdateField.PUBLISHED,
"starred": UpdateField.STARRED,
"unread": UpdateField.UNREAD,
}
def comma_int_list(text: str) -> Sequence[int]:
return [int(i) for i in text.split(",")]
class OutputMode(Enum): class OutputMode(Enum):
# enum values # enum values
JSON = ('json', False) JSON = ('json', False)
@ -37,6 +54,39 @@ class OutputMode(Enum):
def __str__(self): def __str__(self):
return self.mode_name return self.mode_name
class ContentTTSParser(HTMLParser):
END_SENTENCE_CHARS = [".", ";", ":", "!", "?"]
ONLY_SEPARATION_CHARS = [","]
PUNCTATION_CHARS = END_SENTENCE_CHARS + ONLY_SEPARATION_CHARS
SENTENCE_TAG = ["p", "div"]
def __init__(self):
super().__init__()
self.extracted = ""
def append(self, text):
if self.extracted:
self.extracted += " "
self.extracted += ' '.join(text.split())
def close_sentence(self):
if self.extracted:
last_char = self.extracted[-1]
if last_char not in self.END_SENTENCE_CHARS:
if last_char in self.ONLY_SEPARATION_CHARS:
self.extracted = self.extracted[:-1] + self.END_SENTENCE_CHARS[0]
else:
self.extracted += self.END_SENTENCE_CHARS[0]
def append_sentence(self, text):
self.close_sentence()
self.append(text)
self.close_sentence()
def handle_starttag(self, tag, attrs):
if tag in self.SENTENCE_TAG:
self.close_sentence()
def handle_endtag(self, tag):
if tag in self.SENTENCE_TAG:
self.close_sentence()
def handle_data(self, data):
self.append(data)
def func_articles(server: Connection, args: argparse.Namespace): def func_articles(server: Connection, args: argparse.Namespace):
filtered = {key: value for key, value in args.__dict__.items() if key in ["feed_id", "cat_id", "limit", "skip", "view_mode", "since_id", "include_nested", "order_by"]} filtered = {key: value for key, value in args.__dict__.items() if key in ["feed_id", "cat_id", "limit", "skip", "view_mode", "since_id", "include_nested", "order_by"]}
headlines = server.getHeadlines(show_content=args.output_mode.requires_content, **filtered) headlines = server.getHeadlines(show_content=args.output_mode.requires_content, **filtered)
@ -60,6 +110,15 @@ def func_articles(server: Connection, args: argparse.Namespace):
else: else:
raise Exception(f'Not implemented output mode "{args.output_mode}"') raise Exception(f'Not implemented output mode "{args.output_mode}"')
def func_update(server: Connection, args: argparse.Namespace):
# argpase should check that mode and field are valid
updated = server.updateArticle(
article_ids=args.article_ids,
mode=UPDATE_MODES[args.mode],
field=UPDATE_FIELDS[args.field],
)
print(f"Updated {updated} article(s)")
def configure_parser(): def configure_parser():
parser = argparse.ArgumentParser(description="Allows access to feeds and articles of a Tiny Tiny RSS instance using the API.") parser = argparse.ArgumentParser(description="Allows access to feeds and articles of a Tiny Tiny RSS instance using the API.")
#parser.add_argument('--proto', '--protocol', dest='proto', default='https', choices=['http', 'https'], help="The protocol used to access the api, defaults to https") #parser.add_argument('--proto', '--protocol', dest='proto', default='https', choices=['http', 'https'], help="The protocol used to access the api, defaults to https")
@ -78,6 +137,12 @@ def configure_parser():
p.add_argument('--view-mode', '--filter', dest='view_mode', choices=['all_articles', 'unread', 'adaptive', 'marked', 'updated'], default='all_articles', help='Only show articles of certain type') p.add_argument('--view-mode', '--filter', dest='view_mode', choices=['all_articles', 'unread', 'adaptive', 'marked', 'updated'], default='all_articles', help='Only show articles of certain type')
p.add_argument('--order', '--order-by', dest='order_by', choices=['feed_dates', 'date_reverse'], default='date_reverse') p.add_argument('--order', '--order-by', dest='order_by', choices=['feed_dates', 'date_reverse'], default='date_reverse')
p.add_argument('--output-mode', dest='output_mode', choices=OutputMode, type=OutputMode.parse_mode, default='json', help='Define how the received articles should be outputed, in most modes except json and *-full modes, one line equals a single article') p.add_argument('--output-mode', dest='output_mode', choices=OutputMode, type=OutputMode.parse_mode, default='json', help='Define how the received articles should be outputed, in most modes except json and *-full modes, one line equals a single article')
#= Update Articles
p = sub.add_parser("update", help="Update articles")
p.set_defaults(func=func_update)
p.add_argument("-i", "--ids", "--article-ids", dest="article_ids", type=comma_int_list, help="Comma separated list of article ids to update")
p.add_argument("-m", "--mode", dest="mode", choices=UPDATE_MODES.keys())
p.add_argument("-f", "--field", dest="field", choices=UPDATE_FIELDS.keys())
return parser return parser
def parse(args): def parse(args):

@ -1 +1 @@
from .main import Connection from .main import Connection, UpdateField, UpdateMode

@ -1,12 +1,26 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import atexit import atexit
from enum import IntEnum
import http.client import http.client
import json import json
from typing import Dict from typing import Dict, Optional, Sequence
from .JsonClass import JsonClass from .JsonClass import JsonClass
class UpdateMode(IntEnum):
SET_TO_FALSE = 0
SET_TO_TRUE = 1
TOGGLE = 2
class UpdateField(IntEnum):
STARRED = 0
PUBLISHED = 1
UNREAD = 2
ARTICLE_NOTE = 3
# Class Invalid # Class Invalid
class TtRssCounters: class TtRssCounters:
def __init__(feeds=None, labels=None, categories=None, tags=None): def __init__(feeds=None, labels=None, categories=None, tags=None):
@ -259,3 +273,13 @@ class Connection:
def getArticle(self, article_id): def getArticle(self, article_id):
r = self._getSafe('getArticle', article_id=article_id) r = self._getSafe('getArticle', article_id=article_id)
return Article.fromJson(r) return Article.fromJson(r)
def updateArticle(self, article_ids: Sequence[int], mode: UpdateMode, field: UpdateField, data: Optional[str] = None) -> int:
r = self._getSafe(
op='updateArticle',
article_ids=",".join(str(i) for i in article_ids),
mode=mode.value,
field=field.value,
data=data,
)
return r["updated"]

Loading…
Cancel
Save