#!/usr/bin/env python3 import argparse import atexit from getpass import getpass import os import re import sys APP_NAME = "tinytinypy" # For default config directories def func_articles(server, args): 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(**filtered) if args.only_url: for h in headlines: print(h.url) else: print(json.dumps([h.toJson() for h in headlines])) def parser_articles(sub): p = sub.add_parser('articles', help="Get articles") p.set_defaults(func=func_articles) p.add_argument('--feed-id', dest='feed_id', help="Only output articles for this feed, cannot be used with --cat-id") p.add_argument('--cat-id', dest='cat_id', help="Only output articles for feeds of this category, cannot be used with --feed-id") p.add_argument('--limit', dest='limit', type=int, help="Maximum count of articles") p.add_argument('--skip', '--offset', dest='skip', type=int, help="Skip this amount of feeds first") 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('--only-url', dest='only_url', action='store_true', help="Only output urls of articles instead of full article info") def configure_parser(): 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('-H', '--host', '--url', dest='url', required=True, help="URL of the TT-RSS instace to access, examples: rss.example.com, example.com/tt-rss") parser.add_argument('-u', '--user', '--username', dest='user', required=True, help="Name of the user used to access the instance") parser.add_argument('-p', '--pass', '--password', dest='passwd', help="Password of the user used to access the instance") parser.add_argument('-P', '--pass-stdin', '--password-stdin', action='store_true', dest='passStdin', help="Read the password for the user used to access the instance from stdin") sub = parser.add_subparsers(help="Operations", dest='op', description="Operations available to send to server") parser_articles(sub) return parser def parse(args): return configure_parser().parse_args(args=args) def main(): URL_REGEX = re.compile(r'^(?P(https?://)?)(?P[^:/ ]+)(:(?P\d+))?(?P.*)$') # Retrieve args from config and shell storedArgs = sys.argv.copy() storedArgs.pop(0) for d in xdg.BaseDirectory.load_config_paths(APP_NAME): with open(os.path.join(d, "config.txt")) as f: storedArgs = [line.strip() for line in f if line.strip()[0] != '#'] + storedArgs # Parse args args = parse(storedArgs) # Read Pass if stdin passwd = args.passwd if args.passStdin: passwd = getpass() # Check for pass if passwd is None: raise ValueError("Password is missing!") # TODO make more beautiful for user # Parse url urlM = URL_REGEX.match(args.url).groupdict() host = urlM['host'] # Call api # TODO Support scheme (http / https) # TODO Support port server = TtRssInstance(host) server.login(args.user, passwd) args.func(server, args) if __name__ == "__main__": main()