Slixfeed/slixfeed/__main__.py

285 lines
11 KiB
Python
Raw Normal View History

"""
FIXME
1) Check feed duplication on runtime.
When feed is valid and is not yet in the database it is
posible to send a batch which would result in duplication.
Consequently, it might result in database lock error upon
feed removal attempt
2) Communicate to messages of new contacts (not subscribed and not in roster)
TODO
2) Machine Learning for scrapping Title, Link, Summary and Timstamp;
2023-12-24 19:37:05 +01:00
Scrape element </article> (example: Liferea)
http://intertwingly.net/blog/
https://www.brandenburg.de/
3) Set MUC subject
Feeds which entries are to be set as groupchat subject.
Perhaps not, as it would require to check every feed for this setting.
2023-12-24 19:37:05 +01:00
Maybe a separate bot;
5) OMEMO;
6) Logging;
2023-12-24 19:37:05 +01:00
https://docs.python.org/3/howto/logging.html
9.1) IDEA: Bot to display Title and Excerpt
(including sending a PDF version of it) of posted link
2024-01-09 16:53:19 +01:00
10) Fetch summary from URL, instead of storing summary, or
Store 5 upcoming summaries.
This would help making the database files smaller.
2023-11-15 15:02:39 +01:00
2024-01-09 16:53:19 +01:00
13) Tip Of The Day.
Did you know that you can follow you favorite Mastodon feeds by just
sending the URL address?
Supported fediverse websites are:
Akkoma, Firefish (Calckey), Friendica, HubZilla,
Mastodon, Misskey, Pixelfed, Pleroma, Socialhome, Soapbox.
2024-01-09 16:53:19 +01:00
14) Brand: News Broker, Newsman, Newsdealer, Laura Harbinger
2023-12-24 19:37:05 +01:00
2024-01-09 16:53:19 +01:00
16) Search messages of government regulated publishers, and promote other sources.
2023-12-24 19:37:05 +01:00
Dear reader, we couldn't get news from XYZ as they don't provide RSS feeds.
However, you might want to get news from (1) (2) and (3) instead!
17) The operator account will be given reports from the bot about its
2024-01-14 19:05:12 +01:00
activities every X minutes.
When a suspicious activity is detected, it will be reported immediately.
"""
2023-07-16 17:23:10 +02:00
# vars and their meanings:
# jid = Jabber ID (XMPP)
# res = response (HTTP)
from argparse import ArgumentParser
2024-01-18 21:57:49 +01:00
from getpass import getpass
import sys
import configparser
# import filehandler
# from slixfeed.file import get_default_confdir
2023-07-16 17:23:10 +02:00
from getpass import getpass
import logging
import os
2023-07-16 17:23:10 +02:00
# from datetime import date
# import time
2023-07-16 17:23:10 +02:00
# from eliot import start_action, to_file
2024-02-04 19:19:56 +01:00
# # to_file(open('slixfeed.log', 'w'))
# # with start_action(action_type='set_date()', jid=jid):
# # with start_action(action_type='message()', msg=msg):
2023-07-16 17:23:10 +02:00
#import slixfeed.smtp
#import slixfeed.irc
#import slixfeed.matrix
import slixfeed.config as config
2024-02-04 19:19:56 +01:00
from slixfeed.version import __version__
2023-07-16 17:23:10 +02:00
# import socks
# import socket
account = config.get_values('accounts.toml', 'xmpp')
if not 'mode' in account['settings']:
account_mode = 'client'
print('Key "mode" was not found.\nSetting value to "client".')
# raise Exception('Key type is missing from accounts.toml.')
else:
account_mode = 'component'
match account_mode:
2024-02-04 19:19:56 +01:00
case 'client':
from slixfeed.xmpp.client import Slixfeed
# from slixfeed.config import ConfigClient as ConfigAccount
2024-02-04 19:19:56 +01:00
case 'component':
2024-01-24 21:28:14 +01:00
from slixfeed.xmpp.component import SlixfeedComponent
# from slixfeed.config import ConfigComponent as ConfigAccount
# account = ConfigAccount() # TODO Delete as soon as posible after is no longer needed
class JabberComponent:
2024-01-24 21:28:14 +01:00
def __init__(self, jid, secret, hostname, port, alias=None):
xmpp = SlixfeedComponent(jid, secret, hostname, port, alias)
xmpp.register_plugin('xep_0004') # Data Forms
xmpp.register_plugin('xep_0030') # Service Discovery
xmpp.register_plugin('xep_0045') # Multi-User Chat
# xmpp.register_plugin('xep_0048') # Bookmarks
xmpp.register_plugin('xep_0050') # Ad-Hoc Commands
xmpp.register_plugin('xep_0054') # vcard-temp
xmpp.register_plugin('xep_0060') # Publish-Subscribe
# xmpp.register_plugin('xep_0065') # SOCKS5 Bytestreams
xmpp.register_plugin('xep_0066') # Out of Band Data
xmpp.register_plugin('xep_0071') # XHTML-IM
xmpp.register_plugin('xep_0084') # User Avatar
xmpp.register_plugin('xep_0085') # Chat State Notifications
xmpp.register_plugin('xep_0115') # Entity Capabilities
xmpp.register_plugin('xep_0122') # Data Forms Validation
xmpp.register_plugin('xep_0153') # vCard-Based Avatars
xmpp.register_plugin('xep_0199') # XMPP Ping
2024-02-23 10:00:39 +01:00
xmpp.register_plugin('xep_0203') # Delayed Delivery
xmpp.register_plugin('xep_0249') # Direct MUC Invitations
2024-02-23 10:00:39 +01:00
xmpp.register_plugin('xep_0297') # Stanza Forwarding
xmpp.register_plugin('xep_0356') # Privileged Entity
xmpp.register_plugin('xep_0363') # HTTP File Upload
xmpp.register_plugin('xep_0402') # PEP Native Bookmarks
xmpp.register_plugin('xep_0444') # Message Reactions
xmpp.connect()
xmpp.process()
2023-07-16 17:23:10 +02:00
class JabberClient:
2024-01-24 21:28:14 +01:00
def __init__(self, jid, password, hostname=None, port=None, alias=None):
xmpp = Slixfeed(jid, password, hostname, port, alias)
xmpp.register_plugin('xep_0004') # Data Forms
xmpp.register_plugin('xep_0030') # Service Discovery
xmpp.register_plugin('xep_0045') # Multi-User Chat
xmpp.register_plugin('xep_0048') # Bookmarks
xmpp.register_plugin('xep_0050') # Ad-Hoc Commands
2024-01-17 15:36:28 +01:00
xmpp.register_plugin('xep_0054') # vcard-temp
xmpp.register_plugin('xep_0060') # Publish-Subscribe
# xmpp.register_plugin('xep_0065') # SOCKS5 Bytestreams
xmpp.register_plugin('xep_0066') # Out of Band Data
xmpp.register_plugin('xep_0071') # XHTML-IM
2024-01-17 15:36:28 +01:00
xmpp.register_plugin('xep_0084') # User Avatar
xmpp.register_plugin('xep_0085') # Chat State Notifications
xmpp.register_plugin('xep_0115') # Entity Capabilities
xmpp.register_plugin('xep_0122') # Data Forms Validation
2024-01-17 15:36:28 +01:00
xmpp.register_plugin('xep_0153') # vCard-Based Avatars
xmpp.register_plugin('xep_0199', {'keepalive': True}) # XMPP Ping
xmpp.register_plugin('xep_0249') # Direct MUC Invitations
xmpp.register_plugin('xep_0363') # HTTP File Upload
xmpp.register_plugin('xep_0402') # PEP Native Bookmarks
xmpp.register_plugin('xep_0444') # Message Reactions
2024-02-04 19:19:56 +01:00
# proxy_enabled = config.get_value('accounts', 'XMPP', 'proxy_enabled')
# if proxy_enabled == '1':
2024-02-04 19:19:56 +01:00
# values = config.get_value('accounts', 'XMPP', [
# 'proxy_host',
# 'proxy_port',
# 'proxy_username',
# 'proxy_password'
# ])
2024-02-04 19:19:56 +01:00
# print('Proxy is enabled: {}:{}'.format(values[0], values[1]))
# xmpp.use_proxy = True
# xmpp.proxy_config = {
# 'host': values[0],
# 'port': values[1],
# 'username': values[2],
# 'password': values[3]
# }
# proxy = {'socks5': (values[0], values[1])}
# xmpp.proxy = {'socks5': ('localhost', 9050)}
# Connect to the XMPP server and start processing XMPP stanzas.
if hostname and port:
xmpp.connect((hostname, port))
else:
xmpp.connect()
xmpp.process()
2024-01-18 21:57:49 +01:00
def main():
config_dir = config.get_default_config_directory()
2024-02-04 19:19:56 +01:00
logging.info('Reading configuration from {}'.format(config_dir))
print('Reading configuration from {}'.format(config_dir))
2024-03-13 17:17:43 +01:00
network_settings = config.get_values('settings.toml', 'network')
print('User agent:', network_settings['user_agent'] or 'Slixfeed/0.1')
if network_settings['http_proxy']: print('HTTP Proxy:', network_settings['http_proxy'])
# values = config.get_value('accounts', 'XMPP Proxy',
# ['socks5_host', 'socks5_port'])
# if values[0] and values[1]:
# host = values[0]
# port = values[1]
# s = socks.socksocket()
# s.set_proxy(socks.SOCKS5, host, port)
# # socks.set_default_proxy(socks.SOCKS5, host, port)
# # socket.socket = socks.socksocket
2024-01-18 21:57:49 +01:00
# Setup the command line arguments.
match account_mode:
2024-02-23 14:51:19 +01:00
case 'client':
parser = ArgumentParser(description=Slixfeed.__doc__)
case 'component':
parser = ArgumentParser(description=SlixfeedComponent.__doc__)
2024-01-18 21:57:49 +01:00
2024-02-04 19:19:56 +01:00
parser.add_argument('-v', '--version', help='Print version',
action='version', version=__version__)
2024-01-18 21:57:49 +01:00
# Output verbosity options.
2024-02-04 19:19:56 +01:00
parser.add_argument('-q', '--quiet', help='set logging to ERROR',
action='store_const', dest='loglevel',
const=logging.ERROR, default=logging.INFO)
2024-02-04 19:19:56 +01:00
parser.add_argument('-d', '--debug', help='set logging to DEBUG',
action='store_const', dest='loglevel',
const=logging.DEBUG, default=logging.INFO)
2024-01-18 21:57:49 +01:00
# JID and password options.
2024-02-04 19:19:56 +01:00
parser.add_argument('-j', '--jid', help='Jabber ID', dest='jid')
parser.add_argument('-p', '--password', help='Password of JID',
dest='password')
parser.add_argument('-a', '--alias', help='Display name', dest='alias')
parser.add_argument('-n', '--hostname', help='Hostname', dest='hostname')
parser.add_argument('-o', '--port', help='Port number', dest='port')
2024-01-18 21:57:49 +01:00
args = parser.parse_args()
# Setup logging.
logging.basicConfig(level=args.loglevel,
format='%(levelname)-8s %(message)s')
2024-01-18 21:57:49 +01:00
2024-03-03 15:13:01 +01:00
# # Setup logging.
# logging.basicConfig(level=args.loglevel,
# format='%(levelname)-8s %(message)s')
# # logging.basicConfig(format='[%(levelname)s] %(message)s')
# logger = logging.getLogger()
# logdbg = logger.debug
# logerr = logger.error
# lognfo = logger.info
# logwrn = logger.warning
2024-01-18 21:57:49 +01:00
# Try configuration file
jid = account[account_mode]['jid']
password = account[account_mode]['password']
alias = account[account_mode]['alias'] if 'alias' in account[account_mode] else None
hostname = account[account_mode]['hostname'] if 'hostname' in account[account_mode] else None
port = account[account_mode]['port'] if 'port' in account[account_mode] else None
2024-01-18 21:57:49 +01:00
# Use arguments if were given
if args.jid:
2024-01-24 19:59:10 +01:00
jid = args.jid
2024-01-18 21:57:49 +01:00
if args.password:
password = args.password
if args.alias:
alias = args.alias
if args.hostname:
hostname = args.hostname
if args.port:
port = args.port
2024-01-18 21:57:49 +01:00
# Prompt for credentials if none were given
2024-01-24 19:59:10 +01:00
if not jid:
2024-02-04 19:19:56 +01:00
jid = input('JID: ')
2024-01-18 21:57:49 +01:00
if not password:
2024-02-04 19:19:56 +01:00
password = getpass('Password: ')
if not alias:
2024-02-04 19:19:56 +01:00
alias = (input('Alias: ')) or 'Slixfeed'
match account_mode:
2024-02-04 19:19:56 +01:00
case 'client':
2024-01-24 21:28:14 +01:00
JabberClient(jid, password, hostname=hostname, port=port, alias=alias)
2024-02-04 19:19:56 +01:00
case 'component':
2024-01-24 21:28:14 +01:00
JabberComponent(jid, password, hostname, port, alias=alias)
2024-01-18 21:57:49 +01:00
sys.exit(0)
2024-02-04 19:19:56 +01:00
if __name__ == '__main__':
2024-01-18 21:57:49 +01:00
main()