Compare commits
No commits in common. "master" and "master" have entirely different histories.
|
@ -20,15 +20,14 @@ Slixfeed is primarily designed for XMPP (aka Jabber), yet it is built to be exte
|
|||
|
||||
## Features
|
||||
|
||||
- **Visual interface** - Interactive interface for XMPP using Ad-Hoc Commands,
|
||||
- **Ease** - Slixfeed automatically scans (i.e. crawls) for syndication feeds of given URL.
|
||||
- **Encryption** - Messages are encrypted with the OMEMO standard.
|
||||
- **Export** - Download articles as ePUB, HTML, Markdown and PDF.
|
||||
- **Filtering** - Filter news items using lists of allow and deny.
|
||||
- **Multimedia** - Display audios pictures and videos inline.
|
||||
- **Privacy** - Redirect to alternative back-ends, such as Invidious, Librarian, Nitter, for increased privacy, productivity and security.
|
||||
- **Portable** - Export and import feeds with a standard OPML file.
|
||||
- **Simultaneous** - Slixfeed is designed to handle multiple contacts, including groupchats, Simultaneously.
|
||||
- **Visual interface** - Interactive interface for XMPP using Ad-Hoc Commands,
|
||||
|
||||
## Preview
|
||||
|
||||
|
@ -57,7 +56,7 @@ It is possible to install Slixfeed using pip and pipx.
|
|||
```
|
||||
$ python3 -m venv .venv
|
||||
$ source .venv/bin/activate
|
||||
$ pip install git+https://git.xmpp-it.net/sch/Slixfeed
|
||||
$ pip install git+https://gitgud.io/sjehuda/slixfeed
|
||||
```
|
||||
|
||||
#### pipx
|
||||
|
@ -65,14 +64,14 @@ $ pip install git+https://git.xmpp-it.net/sch/Slixfeed
|
|||
##### Install
|
||||
|
||||
```
|
||||
$ pipx install git+https://git.xmpp-it.net/sch/Slixfeed
|
||||
$ pipx install git+https://gitgud.io/sjehuda/slixfeed
|
||||
```
|
||||
|
||||
##### Update
|
||||
|
||||
```
|
||||
$ pipx uninstall slixfeed
|
||||
$ pipx install git+https://git.xmpp-it.net/sch/Slixfeed
|
||||
$ pipx install git+https://gitgud.io/sjehuda/slixfeed
|
||||
```
|
||||
|
||||
### Start
|
||||
|
|
|
@ -39,22 +39,16 @@ keywords = [
|
|||
]
|
||||
# urls = {Homepage = "https://gitgud.io/sjehuda/slixfeed"}
|
||||
dependencies = [
|
||||
"aiofiles",
|
||||
"aiohttp",
|
||||
# "daemonize",
|
||||
"feedparser",
|
||||
"lxml",
|
||||
"omemo", # OMEMO
|
||||
# "pysocks",
|
||||
"protobuf==3.20.3", # OMEMO
|
||||
"python-dateutil",
|
||||
"requests",
|
||||
"slixmpp",
|
||||
"slixmpp-omemo", # OMEMO
|
||||
"tomli", # Python 3.10
|
||||
"tomli_w",
|
||||
"X3DH", # OMEMO
|
||||
"XEdDSA", # OMEMO
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
|
|
|
@ -11,7 +11,6 @@ interval = 300 # Update interval (Minimum value 10)
|
|||
length = 300 # Maximum length of summary (Value 0 to disable)
|
||||
media = 0 # Display media (audio, image, video) when available
|
||||
old = 0 # Mark entries of newly added entries as unread
|
||||
omemo = 1 # Encrypt messages with OMEMO
|
||||
quantum = 3 # Amount of entries per update
|
||||
random = 0 # Pick random item from database
|
||||
|
||||
|
|
|
@ -51,31 +51,27 @@ logger = Logger(__name__)
|
|||
# setting_jid.setting_key has value, otherwise resort to setting_default.setting_key.
|
||||
class Config:
|
||||
|
||||
def add_settings_default(self):
|
||||
def add_settings_default(settings):
|
||||
settings_default = get_values('settings.toml', 'settings')
|
||||
self.defaults = settings_default
|
||||
settings['default'] = settings_default
|
||||
|
||||
# TODO Open SQLite file once
|
||||
def add_settings_jid(self, jid_bare, db_file):
|
||||
self.settings[jid_bare] = {}
|
||||
for key in self.defaults['default']:
|
||||
def add_settings_jid(settings, jid_bare, db_file):
|
||||
settings[jid_bare] = {}
|
||||
for key in ('archive', 'enabled', 'filter', 'formatting', 'interval',
|
||||
'length', 'media', 'old', 'quantum'):
|
||||
value = sqlite.get_setting_value(db_file, key)
|
||||
if value:
|
||||
self.settings[jid_bare][key] = value[0]
|
||||
elif key not in ('check', 'formatting'):
|
||||
# NOTE This might neglects the need for
|
||||
# self.defaults of get_setting_value
|
||||
self.settings[jid_bare][key] = self.defaults['default'][key]
|
||||
if value: settings[jid_bare][key] = value[0]
|
||||
|
||||
def get_settings_xmpp(key=None):
|
||||
result = get_values('accounts.toml', 'xmpp')
|
||||
result = result[key] if key else result
|
||||
return result
|
||||
|
||||
async def set_setting_value(self, jid_bare, db_file, key, val):
|
||||
async def set_setting_value(settings, jid_bare, db_file, key, val):
|
||||
key = key.lower()
|
||||
key_val = [key, val]
|
||||
self.settings[jid_bare][key] = val
|
||||
settings[jid_bare][key] = val
|
||||
if sqlite.is_setting_key(db_file, key):
|
||||
await sqlite.update_setting_value(db_file, key_val)
|
||||
else:
|
||||
|
@ -83,11 +79,11 @@ class Config:
|
|||
|
||||
# TODO Segregate Jabber ID settings from Slixfeed wide settings.
|
||||
# self.settings, self.settings_xmpp, self.settings_irc etc.
|
||||
def get_setting_value(self, jid_bare, key):
|
||||
if jid_bare in self.settings and key in self.settings[jid_bare]:
|
||||
value = self.settings[jid_bare][key]
|
||||
def get_setting_value(settings, jid_bare, key):
|
||||
if jid_bare in settings and key in settings[jid_bare]:
|
||||
value = settings[jid_bare][key]
|
||||
else:
|
||||
value = self.defaults['default'][key]
|
||||
value = settings['default'][key]
|
||||
return value
|
||||
|
||||
class ConfigNetwork:
|
||||
|
@ -109,71 +105,6 @@ class ConfigJabberID:
|
|||
settings[jid_bare][key] = value
|
||||
|
||||
|
||||
class Data:
|
||||
|
||||
|
||||
def get_default_data_directory():
|
||||
"""
|
||||
Determine the directory path where dbfile will be stored.
|
||||
|
||||
* If $XDG_DATA_HOME is defined, use it;
|
||||
* else if $HOME exists, use it;
|
||||
* else if the platform is Windows, use %APPDATA%;
|
||||
* else use the current directory.
|
||||
|
||||
Returns
|
||||
-------
|
||||
str
|
||||
Path to database file.
|
||||
|
||||
Note
|
||||
----
|
||||
This function was taken from project buku.
|
||||
|
||||
See https://github.com/jarun/buku
|
||||
|
||||
* Arun Prakash Jana (jarun)
|
||||
* Dmitry Marakasov (AMDmi3)
|
||||
"""
|
||||
# data_home = xdg.BaseDirectory.xdg_data_home
|
||||
data_home = os.environ.get('XDG_DATA_HOME')
|
||||
if data_home is None:
|
||||
if os.environ.get('HOME') is None:
|
||||
if sys.platform == 'win32':
|
||||
data_home = os.environ.get('APPDATA')
|
||||
if data_home is None:
|
||||
return os.path.abspath('.slixfeed/data')
|
||||
else:
|
||||
return os.path.abspath('.slixfeed/data')
|
||||
else:
|
||||
data_home = os.path.join(
|
||||
os.environ.get('HOME'), '.local', 'share'
|
||||
)
|
||||
return os.path.join(data_home, 'slixfeed')
|
||||
|
||||
|
||||
def get_pathname_to_omemo_directory():
|
||||
"""
|
||||
Get OMEMO directory.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
None
|
||||
|
||||
Returns
|
||||
-------
|
||||
object
|
||||
Coroutine object.
|
||||
"""
|
||||
db_dir = get_default_data_directory()
|
||||
if not os.path.isdir(db_dir):
|
||||
os.mkdir(db_dir)
|
||||
if not os.path.isdir(db_dir + "/omemo"):
|
||||
os.mkdir(db_dir + "/omemo")
|
||||
omemo_dir = os.path.join(db_dir, "omemo")
|
||||
return omemo_dir
|
||||
|
||||
|
||||
def get_values(filename, key=None):
|
||||
config_dir = get_default_config_directory()
|
||||
if not os.path.isdir(config_dir):
|
||||
|
|
|
@ -36,7 +36,6 @@ NOTE
|
|||
|
||||
"""
|
||||
|
||||
import aiofiles
|
||||
from aiohttp import ClientError, ClientSession, ClientTimeout
|
||||
from asyncio import TimeoutError
|
||||
# from asyncio.exceptions import IncompleteReadError
|
||||
|
@ -46,8 +45,6 @@ from asyncio import TimeoutError
|
|||
import requests
|
||||
import slixfeed.config as config
|
||||
from slixfeed.log import Logger
|
||||
# import urllib.request
|
||||
# from urllib.error import HTTPError
|
||||
|
||||
logger = Logger(__name__)
|
||||
|
||||
|
@ -58,6 +55,7 @@ except:
|
|||
"Package magnet2torrent was not found.\n"
|
||||
"BitTorrent is disabled.")
|
||||
|
||||
|
||||
# class Dat:
|
||||
# async def dat():
|
||||
|
||||
|
@ -70,116 +68,14 @@ except:
|
|||
# class Gopher:
|
||||
# async def gopher():
|
||||
|
||||
# class Http:
|
||||
# async def http():
|
||||
|
||||
# class Ipfs:
|
||||
# async def ipfs():
|
||||
|
||||
|
||||
class Http:
|
||||
|
||||
|
||||
# def fetch_media(url, pathname):
|
||||
# try:
|
||||
# urllib.request.urlretrieve(url, pathname)
|
||||
# status = 1
|
||||
# except HTTPError as e:
|
||||
# logger.error(e)
|
||||
# status = 0
|
||||
# return status
|
||||
|
||||
|
||||
async def fetch_headers(url):
|
||||
network_settings = config.get_values('settings.toml', 'network')
|
||||
user_agent = (network_settings['user_agent'] or 'Slixfeed/0.1')
|
||||
headers = {'User-Agent': user_agent}
|
||||
proxy = (network_settings['http_proxy'] or None)
|
||||
timeout = ClientTimeout(total=10)
|
||||
async with ClientSession(headers=headers) as session:
|
||||
async with session.get(url, proxy=proxy,
|
||||
# proxy_auth=(proxy_username, proxy_password),
|
||||
timeout=timeout
|
||||
) as response:
|
||||
headers = response.headers
|
||||
return headers
|
||||
# print("Headers for URL:", url)
|
||||
# for header_name, header_value in headers.items():
|
||||
# print(f"{header_name}: {header_value}")
|
||||
|
||||
|
||||
# TODO Write file to disk. Consider aiofiles
|
||||
async def fetch_media(url, pathname):
|
||||
"""
|
||||
Download media content of given URL.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
url : str
|
||||
URL.
|
||||
pathname : list
|
||||
Pathname (including filename) to save content to.
|
||||
|
||||
Returns
|
||||
-------
|
||||
msg: list or str
|
||||
Document or error message.
|
||||
"""
|
||||
network_settings = config.get_values('settings.toml', 'network')
|
||||
user_agent = (network_settings['user_agent'] or 'Slixfeed/0.1')
|
||||
headers = {'User-Agent': user_agent}
|
||||
proxy = (network_settings['http_proxy'] or None)
|
||||
timeout = ClientTimeout(total=10)
|
||||
async with ClientSession(headers=headers) as session:
|
||||
# async with ClientSession(trust_env=True) as session:
|
||||
try:
|
||||
async with session.get(url, proxy=proxy,
|
||||
# proxy_auth=(proxy_username, proxy_password),
|
||||
timeout=timeout
|
||||
) as response:
|
||||
status = response.status
|
||||
if status in (200, 201):
|
||||
f = await aiofiles.open(pathname, mode='wb')
|
||||
await f.write(await response.read())
|
||||
await f.close()
|
||||
try:
|
||||
result = {'charset': response.charset,
|
||||
'content_length': response.content_length,
|
||||
'content_type': response.content_type,
|
||||
'error': False,
|
||||
'message': None,
|
||||
'original_url': url,
|
||||
'status_code': status,
|
||||
'response_url': response.url}
|
||||
except:
|
||||
result = {'error': True,
|
||||
'message': 'Could not get document.',
|
||||
'original_url': url,
|
||||
'status_code': status,
|
||||
'response_url': response.url}
|
||||
else:
|
||||
result = {'error': True,
|
||||
'message': 'HTTP Error:' + str(status),
|
||||
'original_url': url,
|
||||
'status_code': status,
|
||||
'response_url': response.url}
|
||||
except ClientError as e:
|
||||
result = {'error': True,
|
||||
'message': 'Error:' + str(e) if e else 'ClientError',
|
||||
'original_url': url,
|
||||
'status_code': None}
|
||||
except TimeoutError as e:
|
||||
result = {'error': True,
|
||||
'message': 'Timeout:' + str(e) if e else 'TimeoutError',
|
||||
'original_url': url,
|
||||
'status_code': None}
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
result = {'error': True,
|
||||
'message': 'Error:' + str(e) if e else 'Error',
|
||||
'original_url': url,
|
||||
'status_code': None}
|
||||
return result
|
||||
|
||||
|
||||
def http_response(url):
|
||||
def http_response(url):
|
||||
"""
|
||||
Download response headers.
|
||||
|
||||
|
|
|
@ -2762,39 +2762,6 @@ def get_active_feeds_url(db_file):
|
|||
return result
|
||||
|
||||
|
||||
def get_active_feeds_url_sorted_by_last_scanned(db_file):
|
||||
"""
|
||||
Query table feeds for active URLs and sort them by last scanned time.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
db_file : str
|
||||
Path to database file.
|
||||
|
||||
Returns
|
||||
-------
|
||||
result : tuple
|
||||
URLs of active feeds.
|
||||
"""
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: db_file: {}'
|
||||
.format(function_name, db_file))
|
||||
with create_connection(db_file) as conn:
|
||||
cur = conn.cursor()
|
||||
sql = (
|
||||
"""
|
||||
SELECT feeds_properties.url
|
||||
FROM feeds_properties
|
||||
INNER JOIN feeds_preferences ON feeds_properties.id = feeds_preferences.feed_id
|
||||
INNER JOIN feeds_state ON feeds_properties.id = feeds_state.feed_id
|
||||
WHERE feeds_preferences.enabled = 1
|
||||
ORDER BY feeds_state.scanned
|
||||
"""
|
||||
)
|
||||
result = cur.execute(sql).fetchall()
|
||||
return result
|
||||
|
||||
|
||||
def get_tags(db_file):
|
||||
"""
|
||||
Query table tags and list items.
|
||||
|
|
|
@ -348,7 +348,7 @@ class Feed:
|
|||
if new_entries:
|
||||
await sqlite.add_entries_and_update_feed_state(
|
||||
db_file, feed_id, new_entries)
|
||||
old = Config.get_setting_value(self, jid_bare, 'old')
|
||||
old = Config.get_setting_value(self.settings, jid_bare, 'old')
|
||||
if not old: await sqlite.mark_feed_as_read(db_file, feed_id)
|
||||
result_final = {'link' : url,
|
||||
'index' : feed_id,
|
||||
|
@ -1276,7 +1276,7 @@ class FeedTask:
|
|||
logger.info('Scanning for updates for JID {}'.format(jid_bare))
|
||||
while True:
|
||||
db_file = config.get_pathname_to_database(jid_bare)
|
||||
urls = sqlite.get_active_feeds_url_sorted_by_last_scanned(db_file)
|
||||
urls = sqlite.get_active_feeds_url(db_file)
|
||||
for url in urls:
|
||||
Message.printer('Scanning updates for URL {} ...'.format(url))
|
||||
url = url[0]
|
||||
|
@ -1335,7 +1335,7 @@ class FeedTask:
|
|||
new_entries.extend([new_entry])
|
||||
if new_entries:
|
||||
await sqlite.add_entries_and_update_feed_state(db_file, feed_id, new_entries)
|
||||
limit = Config.get_setting_value(self, jid_bare, 'archive')
|
||||
limit = Config.get_setting_value(self.settings, jid_bare, 'archive')
|
||||
ixs = sqlite.get_entries_id_of_feed(db_file, feed_id)
|
||||
ixs_invalid = {}
|
||||
for ix in ixs:
|
||||
|
@ -1360,8 +1360,8 @@ class FeedTask:
|
|||
# TODO return number of archived entries and add if statement to run archive maintainence function
|
||||
await sqlite.maintain_archive(db_file, limit)
|
||||
# await sqlite.process_invalid_entries(db_file, ixs)
|
||||
await asyncio.sleep(60 * 2)
|
||||
val = Config.get_setting_value(self, jid_bare, 'check')
|
||||
await asyncio.sleep(50)
|
||||
val = Config.get_setting_value(self.settings, jid_bare, 'check')
|
||||
await asyncio.sleep(60 * float(val))
|
||||
# Schedule to call this function again in 90 minutes
|
||||
# loop.call_at(
|
||||
|
|
|
@ -67,107 +67,6 @@ except:
|
|||
logger = Logger(__name__)
|
||||
|
||||
|
||||
class Config:
|
||||
|
||||
|
||||
def get_default_data_directory():
|
||||
if os.environ.get('HOME'):
|
||||
data_home = os.path.join(os.environ.get('HOME'), '.local', 'share')
|
||||
return os.path.join(data_home, 'kaikout')
|
||||
elif sys.platform == 'win32':
|
||||
data_home = os.environ.get('APPDATA')
|
||||
if data_home is None:
|
||||
return os.path.join(
|
||||
os.path.dirname(__file__) + '/kaikout_data')
|
||||
else:
|
||||
return os.path.join(os.path.dirname(__file__) + '/kaikout_data')
|
||||
|
||||
|
||||
def get_default_config_directory():
|
||||
"""
|
||||
Determine the directory path where configuration will be stored.
|
||||
|
||||
* If $XDG_CONFIG_HOME is defined, use it;
|
||||
* else if $HOME exists, use it;
|
||||
* else if the platform is Windows, use %APPDATA%;
|
||||
* else use the current directory.
|
||||
|
||||
Returns
|
||||
-------
|
||||
str
|
||||
Path to configuration directory.
|
||||
"""
|
||||
# config_home = xdg.BaseDirectory.xdg_config_home
|
||||
config_home = os.environ.get('XDG_CONFIG_HOME')
|
||||
if config_home is None:
|
||||
if os.environ.get('HOME') is None:
|
||||
if sys.platform == 'win32':
|
||||
config_home = os.environ.get('APPDATA')
|
||||
if config_home is None:
|
||||
return os.path.abspath('.')
|
||||
else:
|
||||
return os.path.abspath('.')
|
||||
else:
|
||||
config_home = os.path.join(
|
||||
os.environ.get('HOME'), '.config'
|
||||
)
|
||||
return os.path.join(config_home, 'kaikout')
|
||||
|
||||
|
||||
def get_setting_value(db_file, key):
|
||||
value = sqlite.get_setting_value(db_file, key)
|
||||
if value:
|
||||
value = value[0]
|
||||
else:
|
||||
value = Config.get_value('settings', 'Settings', key)
|
||||
return value
|
||||
|
||||
|
||||
def get_values(filename, key=None):
|
||||
config_dir = Config.get_default_config_directory()
|
||||
if not os.path.isdir(config_dir):
|
||||
config_dir = '/usr/share/slixfeed/'
|
||||
if not os.path.isdir(config_dir):
|
||||
config_dir = os.path.dirname(__file__) + "/assets"
|
||||
config_file = os.path.join(config_dir, filename)
|
||||
with open(config_file, mode="rb") as defaults:
|
||||
result = tomllib.load(defaults)
|
||||
values = result[key] if key else result
|
||||
return values
|
||||
|
||||
|
||||
class Database:
|
||||
|
||||
|
||||
def instantiate(jid_bare):
|
||||
"""
|
||||
Callback function to instantiate action on database.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
jid_file : str
|
||||
Filename.
|
||||
callback : ?
|
||||
Function name.
|
||||
message : str, optional
|
||||
Optional kwarg when a message is a part or
|
||||
required argument. The default is None.
|
||||
|
||||
Returns
|
||||
-------
|
||||
object
|
||||
Coroutine object.
|
||||
"""
|
||||
db_dir = Config.get_default_data_directory()
|
||||
if not os.path.isdir(db_dir):
|
||||
os.mkdir(db_dir)
|
||||
if not os.path.isdir(db_dir + "/sqlite"):
|
||||
os.mkdir(db_dir + "/sqlite")
|
||||
db_file = os.path.join(db_dir, "sqlite", r"{}.db".format(jid_bare))
|
||||
sqlite.create_tables(db_file)
|
||||
return db_file
|
||||
|
||||
|
||||
class DateAndTime:
|
||||
|
||||
#https://feedparser.readthedocs.io/en/latest/date-parsing.html
|
||||
|
@ -327,7 +226,6 @@ class Html:
|
|||
'//img[not('
|
||||
'contains(@src, "avatar") or '
|
||||
'contains(@src, "cc-by-sa") or '
|
||||
'contains(@src, "data:image/") or '
|
||||
'contains(@src, "emoji") or '
|
||||
'contains(@src, "icon") or '
|
||||
'contains(@src, "logo") or '
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
__version__ = '0.1.92'
|
||||
__version_info__ = (0, 1, 92)
|
||||
__version__ = '0.1.85'
|
||||
__version_info__ = (0, 1, 85)
|
||||
|
|
|
@ -24,29 +24,21 @@ TODO
|
|||
"""
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
from pathlib import Path
|
||||
from random import randrange # pending_tasks: Use a list and read the first index (i.e. index 0).
|
||||
import slixfeed.config as config
|
||||
from slixfeed.config import Config
|
||||
import slixfeed.fetch as fetch
|
||||
from slixfeed.fetch import Http
|
||||
from slixfeed.log import Logger
|
||||
import slixfeed.sqlite as sqlite
|
||||
from slixfeed.syndication import FeedTask
|
||||
from slixfeed.utilities import Documentation, Html, MD, Task, Url
|
||||
from slixfeed.xmpp.commands import XmppCommands
|
||||
from slixfeed.xmpp.encryption import XmppOmemo
|
||||
from slixfeed.xmpp.message import XmppMessage
|
||||
from slixfeed.xmpp.presence import XmppPresence
|
||||
from slixfeed.xmpp.status import XmppStatusTask
|
||||
from slixfeed.xmpp.upload import XmppUpload
|
||||
from slixfeed.xmpp.utilities import XmppUtilities
|
||||
from slixmpp import JID
|
||||
from slixmpp.stanza import Message
|
||||
import sys
|
||||
import time
|
||||
from typing import Optional
|
||||
|
||||
|
||||
logger = Logger(__name__)
|
||||
|
@ -63,7 +55,7 @@ logger = Logger(__name__)
|
|||
class XmppChat:
|
||||
|
||||
|
||||
async def process_message(self, message: Message, allow_untrusted: bool = False) -> None:
|
||||
async def process_message(self, message):
|
||||
"""
|
||||
Process incoming message stanzas. Be aware that this also
|
||||
includes MUC messages and error messages. It is usually
|
||||
|
@ -77,27 +69,25 @@ class XmppChat:
|
|||
for stanza objects and the Message stanza to see
|
||||
how it may be used.
|
||||
"""
|
||||
message_from = message['from']
|
||||
message_type = message['type']
|
||||
if message_type in ('chat', 'groupchat', 'normal'):
|
||||
jid_bare = message_from.bare
|
||||
if message['type'] in ('chat', 'groupchat', 'normal'):
|
||||
jid_bare = message['from'].bare
|
||||
command = ' '.join(message['body'].split())
|
||||
command_time_start = time.time()
|
||||
|
||||
# if (message_type == 'groupchat' and
|
||||
# if (message['type'] == 'groupchat' and
|
||||
# message['muc']['nick'] == self.alias):
|
||||
# return
|
||||
|
||||
# FIXME Code repetition. See below.
|
||||
# TODO Check alias by nickname associated with conference
|
||||
if message_type == 'groupchat':
|
||||
if message['type'] == 'groupchat':
|
||||
if (message['muc']['nick'] == self.alias):
|
||||
return
|
||||
jid_full = message_from.full
|
||||
jid_full = str(message['from'])
|
||||
if not XmppUtilities.is_moderator(self, jid_bare, jid_full):
|
||||
return
|
||||
|
||||
if message_type == 'groupchat':
|
||||
if message['type'] == 'groupchat':
|
||||
# nick = message['from'][message['from'].index('/')+1:]
|
||||
# nick = str(message['from'])
|
||||
# nick = nick[nick.index('/')+1:]
|
||||
|
@ -119,7 +109,7 @@ class XmppChat:
|
|||
# if nick not in operator:
|
||||
# return
|
||||
# approved = False
|
||||
jid_full = message_from.full
|
||||
jid_full = str(message['from'])
|
||||
if not XmppUtilities.is_moderator(self, jid_bare, jid_full):
|
||||
return
|
||||
# if role == 'moderator':
|
||||
|
@ -150,27 +140,17 @@ class XmppChat:
|
|||
|
||||
# await compose.message(self, jid_bare, message)
|
||||
|
||||
if self['xep_0384'].is_encrypted(message):
|
||||
allow_untrusted=True # Temporary fix. This should be handled by "retry""
|
||||
command, omemo_decrypted, retry = await XmppOmemo.decrypt(
|
||||
self, message, allow_untrusted)
|
||||
if retry:
|
||||
command, omemo_decrypted, retry = await XmppOmemo.decrypt(
|
||||
self, message, allow_untrusted=True)
|
||||
else:
|
||||
omemo_decrypted = None
|
||||
|
||||
if message_type == 'groupchat':
|
||||
if message['type'] == 'groupchat':
|
||||
command = command[1:]
|
||||
command_lowercase = command.lower()
|
||||
|
||||
logger.debug([message_from.full, ':', command])
|
||||
logger.debug([str(message['from']), ':', command])
|
||||
|
||||
# Support private message via groupchat
|
||||
# See https://codeberg.org/poezio/slixmpp/issues/3506
|
||||
if message_type == 'chat' and message.get_plugin('muc', check=True):
|
||||
# jid_bare = message_from.bare
|
||||
jid_full = message_from.full
|
||||
if message['type'] == 'chat' and message.get_plugin('muc', check=True):
|
||||
# jid_bare = message['from'].bare
|
||||
jid_full = str(message['from'])
|
||||
if (jid_bare == jid_full[:jid_full.index('/')]):
|
||||
# TODO Count and alert of MUC-PM attempts
|
||||
return
|
||||
|
@ -237,7 +217,7 @@ class XmppChat:
|
|||
command = command[4:]
|
||||
url = command.split(' ')[0]
|
||||
title = ' '.join(command.split(' ')[1:])
|
||||
response = await XmppCommands.feed_add(
|
||||
response = XmppCommands.feed_add(
|
||||
url, db_file, jid_bare, title)
|
||||
case _ if command_lowercase.startswith('allow +'):
|
||||
val = command[7:]
|
||||
|
@ -347,25 +327,15 @@ class XmppChat:
|
|||
# self.pending_tasks[jid_bare][self.pending_tasks_counter] = status_message
|
||||
XmppPresence.send(self, jid_bare, status_message,
|
||||
status_type=status_type)
|
||||
pathname, response = XmppCommands.export_feeds(
|
||||
filename, response = XmppCommands.export_feeds(
|
||||
jid_bare, ext)
|
||||
encrypt_omemo = Config.get_setting_value(self, jid_bare, 'omemo')
|
||||
encrypted = True if encrypt_omemo else False
|
||||
url = await XmppUpload.start(self, jid_bare, Path(pathname), encrypted=encrypted)
|
||||
url = await XmppUpload.start(self, jid_bare, filename)
|
||||
# response = (
|
||||
# 'Feeds exported successfully to {}.\n{}'
|
||||
# ).format(ex, url)
|
||||
# XmppMessage.send_oob_reply_message(message, url, response)
|
||||
if url:
|
||||
chat_type = await XmppUtilities.get_chat_type(self, jid_bare)
|
||||
if encrypted:
|
||||
url_encrypted, omemo_encrypted = await XmppOmemo.encrypt(
|
||||
self, message_from, url)
|
||||
XmppMessage.send_omemo_oob(self, message_from, url_encrypted, chat_type)
|
||||
else:
|
||||
XmppMessage.send_oob(self, jid_bare, url, chat_type)
|
||||
else:
|
||||
response = 'OPML file export has been failed.'
|
||||
del self.pending_tasks[jid_bare][pending_tasks_num]
|
||||
# del self.pending_tasks[jid_bare][self.pending_tasks_counter]
|
||||
XmppStatusTask.restart_task(self, jid_bare)
|
||||
|
@ -383,7 +353,7 @@ class XmppChat:
|
|||
response = (first_line + result +
|
||||
'\n```\nTotal of {} feeds'.format(number))
|
||||
case 'goodbye':
|
||||
if message_type == 'groupchat':
|
||||
if message['type'] == 'groupchat':
|
||||
await XmppCommands.muc_leave(self, jid_bare)
|
||||
else:
|
||||
response = 'This command is valid in groupchat only.'
|
||||
|
@ -408,18 +378,18 @@ class XmppChat:
|
|||
# del self.pending_tasks[jid_bare][self.pending_tasks_counter]
|
||||
XmppStatusTask.restart_task(self, jid_bare)
|
||||
case _ if command_lowercase.startswith('pubsub list'):
|
||||
jid_full_pubsub = command[12:]
|
||||
response = 'List of nodes for {}:\n```\n'.format(jid_full_pubsub)
|
||||
response = await XmppCommands.pubsub_list(self, jid_full_pubsub)
|
||||
jid = command[12:]
|
||||
response = 'List of nodes for {}:\n```\n'.format(jid)
|
||||
response = await XmppCommands.pubsub_list(self, jid)
|
||||
response += '```'
|
||||
case _ if command_lowercase.startswith('pubsub send'):
|
||||
if XmppUtilities.is_operator(self, jid_bare):
|
||||
info = command[12:]
|
||||
info = info.split(' ')
|
||||
jid_full_pubsub = info[0]
|
||||
jid = info[0]
|
||||
# num = int(info[1])
|
||||
if jid_full_pubsub:
|
||||
response = XmppCommands.pubsub_send(self, info, jid_full_pubsub)
|
||||
if jid:
|
||||
response = XmppCommands.pubsub_send(self, info, jid)
|
||||
else:
|
||||
response = ('This action is restricted. '
|
||||
'Type: sending news to PubSub.')
|
||||
|
@ -483,13 +453,6 @@ class XmppChat:
|
|||
self, jid_bare, db_file)
|
||||
case _ if command_lowercase.startswith('next'):
|
||||
num = command[5:]
|
||||
if num:
|
||||
try:
|
||||
int(num)
|
||||
except:
|
||||
# NOTE Show this text as a status message
|
||||
# response = 'Argument for command "next" must be an integer.'
|
||||
num = None
|
||||
await XmppChatAction.send_unread_items(self, jid_bare, num)
|
||||
XmppStatusTask.restart_task(self, jid_bare)
|
||||
case _ if command_lowercase.startswith('node delete'):
|
||||
|
@ -511,12 +474,6 @@ class XmppChat:
|
|||
case 'old':
|
||||
response = await XmppCommands.set_old_on(
|
||||
self, jid_bare, db_file)
|
||||
case 'omemo off':
|
||||
response = await XmppCommands.set_omemo_off(
|
||||
self, jid_bare, db_file)
|
||||
case 'omemo on':
|
||||
response = await XmppCommands.set_omemo_on(
|
||||
self, jid_bare, db_file)
|
||||
case 'options':
|
||||
response = 'Options:\n```'
|
||||
response += XmppCommands.print_options(self, jid_bare)
|
||||
|
@ -595,9 +552,9 @@ class XmppChat:
|
|||
XmppPresence.send(self, jid_bare, status_message,
|
||||
status_type=status_type)
|
||||
await asyncio.sleep(5)
|
||||
callbacks = (FeedTask, XmppChatTask, XmppStatusTask)
|
||||
tasks = (FeedTask, XmppChatTask, XmppStatusTask)
|
||||
response = await XmppCommands.scheduler_start(
|
||||
self, db_file, jid_bare, callbacks)
|
||||
self, db_file, jid_bare, tasks)
|
||||
case 'stats':
|
||||
response = XmppCommands.print_statistics(db_file)
|
||||
case 'stop':
|
||||
|
@ -624,20 +581,8 @@ class XmppChat:
|
|||
command_time_finish = time.time()
|
||||
command_time_total = command_time_finish - command_time_start
|
||||
command_time_total = round(command_time_total, 3)
|
||||
if response:
|
||||
encrypt_omemo = Config.get_setting_value(self, jid_bare, 'omemo')
|
||||
encrypted = True if encrypt_omemo else False
|
||||
if encrypted and self['xep_0384'].is_encrypted(message):
|
||||
response_encrypted, omemo_encrypted = await XmppOmemo.encrypt(
|
||||
self, message_from, response)
|
||||
if omemo_decrypted and omemo_encrypted:
|
||||
# message_from = message['from']
|
||||
# message_type = message['type']
|
||||
XmppMessage.send_omemo(self, message_from, message_type, response_encrypted)
|
||||
# XmppMessage.send_omemo_reply(self, message, response_encrypted)
|
||||
else:
|
||||
XmppMessage.send_reply(self, message, response)
|
||||
if Config.get_setting_value(self, jid_bare, 'finished'):
|
||||
if response: XmppMessage.send_reply(self, message, response)
|
||||
if Config.get_setting_value(self.settings, jid_bare, 'finished'):
|
||||
response_finished = 'Finished. Total time: {}s'.format(command_time_total)
|
||||
XmppMessage.send_reply(self, message, response_finished)
|
||||
|
||||
|
@ -665,13 +610,13 @@ class XmppChat:
|
|||
class XmppChatAction:
|
||||
|
||||
|
||||
async def send_unread_items(self, jid_bare, num: Optional[int] = None):
|
||||
async def send_unread_items(self, jid_bare, num=None):
|
||||
"""
|
||||
Send news items as messages.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
jid_bare : str
|
||||
jid : str
|
||||
Jabber ID.
|
||||
num : str, optional
|
||||
Number. The default is None.
|
||||
|
@ -679,17 +624,14 @@ class XmppChatAction:
|
|||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid: {} num: {}'.format(function_name, jid_bare, num))
|
||||
db_file = config.get_pathname_to_database(jid_bare)
|
||||
encrypt_omemo = Config.get_setting_value(self, jid_bare, 'omemo')
|
||||
encrypted = True if encrypt_omemo else False
|
||||
jid = JID(jid_bare)
|
||||
show_media = Config.get_setting_value(self, jid_bare, 'media')
|
||||
show_media = Config.get_setting_value(self.settings, jid_bare, 'media')
|
||||
if not num:
|
||||
num = Config.get_setting_value(self, jid_bare, 'quantum')
|
||||
num = Config.get_setting_value(self.settings, jid_bare, 'quantum')
|
||||
else:
|
||||
num = int(num)
|
||||
results = sqlite.get_unread_entries(db_file, num)
|
||||
news_digest = ''
|
||||
media_url = None
|
||||
media = None
|
||||
chat_type = await XmppUtilities.get_chat_type(self, jid_bare)
|
||||
for result in results:
|
||||
ix = result[0]
|
||||
|
@ -716,91 +658,19 @@ class XmppChatAction:
|
|||
# elif enclosure:
|
||||
if show_media:
|
||||
if enclosure:
|
||||
media_url = enclosure
|
||||
media = enclosure
|
||||
else:
|
||||
media_url = await Html.extract_image_from_html(url)
|
||||
try:
|
||||
http_headers = await Http.fetch_headers(media_url)
|
||||
if ('Content-Length' in http_headers):
|
||||
if int(http_headers['Content-Length']) < 100000:
|
||||
media_url = None
|
||||
else:
|
||||
media_url = None
|
||||
except Exception as e:
|
||||
print(media_url)
|
||||
logger.error(e)
|
||||
media_url = None
|
||||
media = await Html.extract_image_from_html(url)
|
||||
|
||||
if media_url and news_digest:
|
||||
if encrypt_omemo:
|
||||
news_digest_encrypted, omemo_encrypted = await XmppOmemo.encrypt(
|
||||
self, jid, news_digest)
|
||||
if encrypt_omemo and omemo_encrypted:
|
||||
XmppMessage.send_omemo(self, jid, chat_type, news_digest_encrypted)
|
||||
else:
|
||||
if media and news_digest:
|
||||
# Send textual message
|
||||
XmppMessage.send(self, jid_bare, news_digest, chat_type)
|
||||
news_digest = ''
|
||||
# Send media
|
||||
if encrypt_omemo:
|
||||
cache_dir = config.get_default_cache_directory()
|
||||
# if not media_url.startswith('data:'):
|
||||
filename = media_url.split('/').pop().split('?')[0]
|
||||
if not filename: breakpoint()
|
||||
pathname = os.path.join(cache_dir, filename)
|
||||
# http_response = await Http.response(media_url)
|
||||
http_headers = await Http.fetch_headers(media_url)
|
||||
if ('Content-Length' in http_headers and
|
||||
int(http_headers['Content-Length']) < 3000000):
|
||||
status = await Http.fetch_media(media_url, pathname)
|
||||
if status:
|
||||
filesize = os.path.getsize(pathname)
|
||||
media_url_new = await XmppUpload.start(
|
||||
self, jid_bare, Path(pathname), filesize, encrypted=encrypted)
|
||||
else:
|
||||
media_url_new = media_url
|
||||
else:
|
||||
media_url_new = media_url
|
||||
# else:
|
||||
# import io, base64
|
||||
# from PIL import Image
|
||||
# file_content = media_url.split(',').pop()
|
||||
# file_extension = media_url.split(';')[0].split(':').pop().split('/').pop()
|
||||
# img = Image.open(io.BytesIO(base64.decodebytes(bytes(file_content, "utf-8"))))
|
||||
# filename = 'image.' + file_extension
|
||||
# pathname = os.path.join(cache_dir, filename)
|
||||
# img.save(pathname)
|
||||
# filesize = os.path.getsize(pathname)
|
||||
# media_url_new = await XmppUpload.start(
|
||||
# self, jid_bare, Path(pathname), filesize, encrypted=encrypted)
|
||||
media_url_new_encrypted, omemo_encrypted = await XmppOmemo.encrypt(
|
||||
self, jid, media_url_new)
|
||||
if media_url_new_encrypted and omemo_encrypted:
|
||||
# NOTE Tested against Gajim.
|
||||
# FIXME This only works with aesgcm URLs, and it does
|
||||
# not work with http URLs.
|
||||
# url = saxutils.escape(url)
|
||||
# AttributeError: 'Encrypted' object has no attribute 'replace'
|
||||
XmppMessage.send_omemo_oob(self, jid, media_url_new_encrypted, chat_type)
|
||||
else:
|
||||
# NOTE Tested against Gajim.
|
||||
# FIXME Jandle data: URIs.
|
||||
if not media_url.startswith('data:'):
|
||||
http_headers = await Http.fetch_headers(media_url)
|
||||
if ('Content-Length' in http_headers and
|
||||
int(http_headers['Content-Length']) > 100000):
|
||||
print(http_headers['Content-Length'])
|
||||
XmppMessage.send_oob(self, jid_bare, media_url, chat_type)
|
||||
else:
|
||||
XmppMessage.send_oob(self, jid_bare, media_url, chat_type)
|
||||
media_url = None
|
||||
XmppMessage.send_oob(self, jid_bare, media, chat_type)
|
||||
media = None
|
||||
|
||||
if news_digest:
|
||||
if encrypt_omemo: news_digest_encrypted, omemo_encrypted = await XmppOmemo.encrypt(
|
||||
self, jid, news_digest)
|
||||
if encrypt_omemo and omemo_encrypted:
|
||||
XmppMessage.send_omemo(self, jid, chat_type, news_digest_encrypted)
|
||||
else:
|
||||
XmppMessage.send(self, jid_bare, news_digest, chat_type)
|
||||
# TODO Add while loop to assure delivery.
|
||||
# print(await current_time(), ">>> ACT send_message",jid)
|
||||
|
@ -886,7 +756,7 @@ class XmppChatAction:
|
|||
summary = summary.replace(' ', ' ')
|
||||
# summary = summary.replace(' ', ' ')
|
||||
summary = ' '.join(summary.split())
|
||||
length = Config.get_setting_value(self, jid, 'length')
|
||||
length = Config.get_setting_value(self.settings, jid, 'length')
|
||||
length = int(length)
|
||||
summary = summary[:length] + " […]"
|
||||
# summary = summary.strip().split('\n')
|
||||
|
@ -900,7 +770,7 @@ class XmppChatAction:
|
|||
feed_id = result[4]
|
||||
# news_item = ("\n{}\n{}\n{} [{}]\n").format(str(title), str(link),
|
||||
# str(feed_title), str(ix))
|
||||
formatting = Config.get_setting_value(self, jid, 'formatting')
|
||||
formatting = Config.get_setting_value(self.settings, jid, 'formatting')
|
||||
news_item = formatting.format(feed_title=feed_title,
|
||||
title=title,
|
||||
summary=summary,
|
||||
|
@ -917,9 +787,9 @@ class XmppChatTask:
|
|||
async def task_message(self, jid_bare):
|
||||
db_file = config.get_pathname_to_database(jid_bare)
|
||||
if jid_bare not in self.settings:
|
||||
Config.add_settings_jid(self, jid_bare, db_file)
|
||||
Config.add_settings_jid(self.settings, jid_bare, db_file)
|
||||
while True:
|
||||
update_interval = Config.get_setting_value(self, jid_bare, 'interval')
|
||||
update_interval = Config.get_setting_value(self.settings, jid_bare, 'interval')
|
||||
update_interval = 60 * int(update_interval)
|
||||
last_update_time = sqlite.get_last_update_time(db_file)
|
||||
if last_update_time:
|
||||
|
|
|
@ -31,9 +31,8 @@ NOTE
|
|||
|
||||
import asyncio
|
||||
from datetime import datetime
|
||||
from feedparser import parse
|
||||
import os
|
||||
from pathlib import Path
|
||||
from feedparser import parse
|
||||
import slixmpp
|
||||
# from slixmpp.plugins.xep_0363.http_upload import FileTooBig, HTTPError, UploadServiceNotFound
|
||||
# from slixmpp.plugins.xep_0402 import BookmarkStorage, Conference
|
||||
|
@ -44,7 +43,7 @@ import slixmpp
|
|||
# from lxml import etree
|
||||
|
||||
import slixfeed.config as config
|
||||
from slixfeed.config import Config, Data
|
||||
from slixfeed.config import Config
|
||||
import slixfeed.fetch as fetch
|
||||
from slixfeed.log import Logger
|
||||
import slixfeed.sqlite as sqlite
|
||||
|
@ -54,12 +53,11 @@ from slixfeed.version import __version__
|
|||
from slixfeed.xmpp.bookmark import XmppBookmark
|
||||
from slixfeed.xmpp.chat import XmppChat, XmppChatTask
|
||||
from slixfeed.xmpp.connect import XmppConnect, XmppConnectTask
|
||||
from slixfeed.xmpp.encryption import XmppOmemo
|
||||
from slixfeed.xmpp.groupchat import XmppGroupchat
|
||||
from slixfeed.xmpp.ipc import XmppIpcServer
|
||||
from slixfeed.xmpp.iq import XmppIQ
|
||||
from slixfeed.xmpp.message import XmppMessage
|
||||
from slixfeed.xmpp.muc import XmppMuc
|
||||
from slixfeed.xmpp.groupchat import XmppGroupchat
|
||||
from slixfeed.xmpp.presence import XmppPresence
|
||||
import slixfeed.xmpp.profile as profile
|
||||
from slixfeed.xmpp.publish import XmppPubsub, XmppPubsubAction, XmppPubsubTask
|
||||
|
@ -68,9 +66,6 @@ from slixfeed.xmpp.roster import XmppRoster
|
|||
from slixfeed.xmpp.status import XmppStatusTask
|
||||
from slixfeed.xmpp.upload import XmppUpload
|
||||
from slixfeed.xmpp.utilities import XmppUtilities
|
||||
from slixmpp import JID
|
||||
import slixmpp_omemo
|
||||
from slixmpp_omemo import PluginCouldNotLoad
|
||||
import sys
|
||||
import time
|
||||
|
||||
|
@ -117,16 +112,14 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
# Handler for ping
|
||||
self.task_ping_instance = {}
|
||||
|
||||
# Handler for default configuration
|
||||
self.defaults = config.get_values('settings.toml')
|
||||
# Handler for configuration
|
||||
self.settings = {}
|
||||
self.settings = config.get_values('settings.toml')
|
||||
# Handler for operators
|
||||
self.operators = config.get_values('accounts.toml', 'xmpp')['operators']
|
||||
|
||||
# self.settings = {}
|
||||
# # Populate dict handler
|
||||
# Config.add_settings_default(self)
|
||||
# Config.add_settings_default(self.settings)
|
||||
|
||||
# Handlers for connection events
|
||||
self.connection_attempts = 0
|
||||
|
@ -154,21 +147,6 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
self.register_plugin('xep_0363') # HTTP File Upload
|
||||
self.register_plugin('xep_0402') # PEP Native Bookmarks
|
||||
self.register_plugin('xep_0444') # Message Reactions
|
||||
try:
|
||||
self.register_plugin(
|
||||
'xep_0384',
|
||||
{
|
||||
'data_dir': Data.get_pathname_to_omemo_directory(),
|
||||
},
|
||||
module=slixmpp_omemo,) # OMEMO Encryption
|
||||
except (PluginCouldNotLoad,):
|
||||
logger.error('An error has occured when loading the OMEMO plugin.')
|
||||
sys.exit(1)
|
||||
try:
|
||||
self.register_plugin('xep_0454')
|
||||
except slixmpp.plugins.base.PluginNotFound:
|
||||
logger.error('Could not load xep_0454. Ensure you have '
|
||||
'\'cryptography\' from extras_require installed.')
|
||||
|
||||
# proxy_enabled = config.get_value('accounts', 'XMPP', 'proxy_enabled')
|
||||
# if proxy_enabled == '1':
|
||||
|
@ -252,7 +230,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
# TODO Test
|
||||
async def on_groupchat_invite(self, message):
|
||||
time_begin = time.time()
|
||||
jid_full = message['from'].full
|
||||
jid_full = str(message['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
message_log = '{}: jid_full: {}'
|
||||
logger.debug(message_log.format(function_name, jid_full))
|
||||
|
@ -290,7 +268,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
# NOTE Tested with Gajim and Psi
|
||||
async def on_groupchat_direct_invite(self, message):
|
||||
time_begin = time.time()
|
||||
jid_full = message['from'].full
|
||||
jid_full = str(message['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
message_log = '{}: jid_full: {}'
|
||||
logger.debug(message_log.format(function_name, jid_full))
|
||||
|
@ -355,12 +333,12 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
# jid_bare = result['jid']
|
||||
# if jid_bare not in self.settings:
|
||||
# db_file = config.get_pathname_to_database(jid_bare)
|
||||
# Config.add_settings_jid(self, jid_bare, db_file)
|
||||
# Config.add_settings_jid(self.settings, jid_bare, db_file)
|
||||
# await FeedTask.check_updates(self, jid_bare)
|
||||
# XmppPubsubTask.task_publish(self, jid_bare)
|
||||
bookmarks = await XmppBookmark.get_bookmarks(self)
|
||||
await XmppGroupchat.autojoin(self, bookmarks)
|
||||
if 'ipc' in self.defaults and self.defaults['ipc']['bsd']:
|
||||
if 'ipc' in self.settings and self.settings['ipc']['bsd']:
|
||||
# Start Inter-Process Communication
|
||||
print('POSIX sockets: Initiating IPC server...')
|
||||
self.ipc = asyncio.create_task(XmppIpcServer.ipc(self))
|
||||
|
@ -388,7 +366,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
async def on_disco_info(self, DiscoInfo):
|
||||
time_begin = time.time()
|
||||
jid_full = DiscoInfo['from'].full
|
||||
jid_full = str(DiscoInfo['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
message_log = '{}: jid_full: {}'
|
||||
logger.debug(message_log.format(function_name, jid_full))
|
||||
|
@ -403,14 +381,14 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
async def on_message(self, message):
|
||||
time_begin = time.time()
|
||||
jid_full = message['from'].full
|
||||
jid_full = str(message['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
message_log = '{}: jid_full: {}'
|
||||
logger.debug(message_log.format(function_name, jid_full))
|
||||
jid_bare = message['from'].bare
|
||||
db_file = config.get_pathname_to_database(jid_bare)
|
||||
if jid_bare not in self.settings:
|
||||
Config.add_settings_jid(self, jid_bare, db_file)
|
||||
Config.add_settings_jid(self.settings, jid_bare, db_file)
|
||||
if jid_bare == self.boundjid.bare:
|
||||
status_type = 'dnd'
|
||||
status_message = ('Slixfeed is not designed to receive messages '
|
||||
|
@ -449,7 +427,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
async def on_changed_status(self, presence):
|
||||
time_begin = time.time()
|
||||
jid_full = presence['from'].full
|
||||
jid_full = str(presence['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
message_log = '{}: jid_full: {}'
|
||||
logger.debug(message_log.format(function_name, jid_full))
|
||||
|
@ -474,7 +452,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
async def on_presence_subscribe(self, presence):
|
||||
time_begin = time.time()
|
||||
jid_full = presence['from'].full
|
||||
jid_full = str(presence['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
message_log = '{}: jid_full: {}'
|
||||
logger.debug(message_log.format(function_name, jid_full))
|
||||
|
@ -497,7 +475,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
def on_presence_subscribed(self, presence):
|
||||
time_begin = time.time()
|
||||
jid_full = presence['from'].full
|
||||
jid_full = str(presence['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
message_log = '{}: jid_full: {}'
|
||||
logger.debug(message_log.format(function_name, jid_full))
|
||||
|
@ -519,7 +497,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
async def on_presence_available(self, presence):
|
||||
time_begin = time.time()
|
||||
jid_full = presence['from'].full
|
||||
jid_full = str(presence['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
message_log = '{}: jid_full: {}'
|
||||
logger.debug(message_log.format(function_name, jid_full))
|
||||
|
@ -543,7 +521,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
def on_presence_unsubscribed(self, presence):
|
||||
time_begin = time.time()
|
||||
jid_full = presence['from'].full
|
||||
jid_full = str(presence['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
message_log = '{}: jid_full: {}'
|
||||
logger.debug(message_log.format(function_name, jid_full))
|
||||
|
@ -564,7 +542,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
def on_presence_unavailable(self, presence):
|
||||
time_begin = time.time()
|
||||
jid_full = presence['from'].full
|
||||
jid_full = str(presence['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
message_log = '{}: jid_full: {}'
|
||||
logger.debug(message_log.format(function_name, jid_full))
|
||||
|
@ -592,7 +570,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
# If bookmarks, remove groupchat JID into file
|
||||
def on_presence_error(self, presence):
|
||||
time_begin = time.time()
|
||||
jid_full = presence['from'].full
|
||||
jid_full = str(presence['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
message_log = '{}: jid_full: {}'
|
||||
logger.debug(message_log.format(function_name, jid_full))
|
||||
|
@ -612,7 +590,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
async def on_chatstate_active(self, message):
|
||||
time_begin = time.time()
|
||||
jid_full = message['from'].full
|
||||
jid_full = str(message['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
message_log = '{}: jid_full: {}'
|
||||
logger.debug(message_log.format(function_name, jid_full))
|
||||
|
@ -635,7 +613,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
async def on_chatstate_composing(self, message):
|
||||
# print('on_chatstate_composing START')
|
||||
time_begin = time.time()
|
||||
jid_full = message['from'].full
|
||||
jid_full = str(message['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
message_log = '{}: jid_full: {}'
|
||||
logger.debug(message_log.format(function_name, jid_full))
|
||||
|
@ -658,7 +636,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
def on_chatstate_gone(self, message):
|
||||
time_begin = time.time()
|
||||
jid_full = message['from'].full
|
||||
jid_full = str(message['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
message_log = '{}: jid_full: {}'
|
||||
logger.debug(message_log.format(function_name, jid_full))
|
||||
|
@ -675,7 +653,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
def on_chatstate_inactive(self, message):
|
||||
time_begin = time.time()
|
||||
jid_full = message['from'].full
|
||||
jid_full = str(message['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
message_log = '{}: jid_full: {}'
|
||||
logger.debug(message_log.format(function_name, jid_full))
|
||||
|
@ -692,7 +670,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
def on_chatstate_paused(self, message):
|
||||
time_begin = time.time()
|
||||
jid_full = message['from'].full
|
||||
jid_full = str(message['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
message_log = '{}: jid_full: {}'
|
||||
logger.debug(message_log.format(function_name, jid_full))
|
||||
|
@ -854,7 +832,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
# http://jabber.org/protocol/commands#actions
|
||||
|
||||
async def _handle_publish(self, iq, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -895,7 +873,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
return session
|
||||
|
||||
async def _handle_publish_action(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -1003,7 +981,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
return session
|
||||
|
||||
async def _handle_publish_db_preview(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -1111,7 +1089,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_publish_url_preview(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -1303,14 +1281,14 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
return session
|
||||
|
||||
async def _handle_profile(self, iq, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
jid_bare = session['from'].bare
|
||||
db_file = config.get_pathname_to_database(jid_bare)
|
||||
if jid_bare not in self.settings:
|
||||
Config.add_settings_jid(self, jid_bare, db_file)
|
||||
Config.add_settings_jid(self.settings, jid_bare, db_file)
|
||||
form = self['xep_0004'].make_form('form', 'Profile')
|
||||
form['instructions'] = ('Displaying information\nJabber ID {}'
|
||||
.format(jid_bare))
|
||||
|
@ -1334,42 +1312,42 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
value=unread)
|
||||
form.add_field(ftype='fixed',
|
||||
label='Options')
|
||||
key_archive = Config.get_setting_value(self, jid_bare, 'archive')
|
||||
key_archive = Config.get_setting_value(self.settings, jid_bare, 'archive')
|
||||
key_archive = str(key_archive)
|
||||
form.add_field(label='Archive',
|
||||
ftype='text-single',
|
||||
value=key_archive)
|
||||
key_enabled = Config.get_setting_value(self, jid_bare, 'enabled')
|
||||
key_enabled = Config.get_setting_value(self.settings, jid_bare, 'enabled')
|
||||
key_enabled = str(key_enabled)
|
||||
form.add_field(label='Enabled',
|
||||
ftype='text-single',
|
||||
value=key_enabled)
|
||||
key_interval = Config.get_setting_value(self, jid_bare, 'interval')
|
||||
key_interval = Config.get_setting_value(self.settings, jid_bare, 'interval')
|
||||
key_interval = str(key_interval)
|
||||
form.add_field(label='Interval',
|
||||
ftype='text-single',
|
||||
value=key_interval)
|
||||
key_length = Config.get_setting_value(self, jid_bare, 'length')
|
||||
key_length = Config.get_setting_value(self.settings, jid_bare, 'length')
|
||||
key_length = str(key_length)
|
||||
form.add_field(label='Length',
|
||||
ftype='text-single',
|
||||
value=key_length)
|
||||
key_media = Config.get_setting_value(self, jid_bare, 'media')
|
||||
key_media = Config.get_setting_value(self.settings, jid_bare, 'media')
|
||||
key_media = str(key_media)
|
||||
form.add_field(label='Media',
|
||||
ftype='text-single',
|
||||
value=key_media)
|
||||
key_old = Config.get_setting_value(self, jid_bare, 'old')
|
||||
key_old = Config.get_setting_value(self.settings, jid_bare, 'old')
|
||||
key_old = str(key_old)
|
||||
form.add_field(label='Old',
|
||||
ftype='text-single',
|
||||
value=key_old)
|
||||
key_quantum = Config.get_setting_value(self, jid_bare, 'quantum')
|
||||
key_quantum = Config.get_setting_value(self.settings, jid_bare, 'quantum')
|
||||
key_quantum = str(key_quantum)
|
||||
form.add_field(label='Quantum',
|
||||
ftype='text-single',
|
||||
value=key_quantum)
|
||||
update_interval = Config.get_setting_value(self, jid_bare, 'interval')
|
||||
update_interval = Config.get_setting_value(self.settings, jid_bare, 'interval')
|
||||
update_interval = str(update_interval)
|
||||
update_interval = 60 * int(update_interval)
|
||||
last_update_time = sqlite.get_last_update_time(db_file)
|
||||
|
@ -1405,7 +1383,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
return session
|
||||
|
||||
async def _handle_filters(self, iq, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -1478,7 +1456,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
session. Additional, custom data may be saved
|
||||
here to persist across handler callbacks.
|
||||
"""
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -1514,7 +1492,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_subscription_add(self, iq, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -1577,7 +1555,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_recent(self, iq, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -1628,7 +1606,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_recent_result(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -1685,7 +1663,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
# FIXME
|
||||
async def _handle_recent_select(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -1758,7 +1736,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_subscription_new(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -1962,7 +1940,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_subscription_toggle(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -1987,7 +1965,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_subscription_del_complete(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -2015,7 +1993,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
def _handle_cancel(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -2028,7 +2006,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_discover(self, iq, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -2066,7 +2044,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
def _handle_discover_type(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -2122,7 +2100,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_discover_category(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -2152,7 +2130,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_subscriptions(self, iq, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -2217,7 +2195,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_subscriptions_result(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -2311,7 +2289,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_subscription_tag(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -2349,7 +2327,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_subscription_edit(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -2446,7 +2424,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
# TODO Create a new form. Do not "recycle" the last form.
|
||||
async def _handle_subscription_complete(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -2512,7 +2490,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_advanced(self, iq, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -2554,7 +2532,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_advanced_result(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -2701,7 +2679,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_about(self, iq, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -2726,7 +2704,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_about_result(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -2790,7 +2768,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_motd(self, iq, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -2803,7 +2781,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_help(self, iq, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -2844,7 +2822,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_import_complete(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -2885,11 +2863,12 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_export_complete(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
form = self['xep_0004'].make_form('result', 'Done')
|
||||
form['instructions'] = 'Export has been completed successfully!'
|
||||
# form['type'] = 'result'
|
||||
values = payload['values']
|
||||
jid_bare = session['from'].bare
|
||||
|
@ -2901,18 +2880,8 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
exts = values['filetype']
|
||||
for ext in exts:
|
||||
filename = Feed.export_feeds(jid_bare, ext)
|
||||
encrypt_omemo = Config.get_setting_value(self, jid_bare, 'omemo')
|
||||
encrypted = True if encrypt_omemo else False
|
||||
url = await XmppUpload.start(
|
||||
self, jid_bare, Path(filename), encrypted=encrypted)
|
||||
if url:
|
||||
form['instructions'] = 'Export has been completed successfully!'
|
||||
url = await XmppUpload.start(self, jid_bare, filename)
|
||||
chat_type = await XmppUtilities.get_chat_type(self, jid_bare)
|
||||
if encrypted:
|
||||
url_encrypted, omemo_encrypted = await XmppOmemo.encrypt(
|
||||
self, JID(jid_bare), url)
|
||||
XmppMessage.send_omemo_oob(self, JID(jid_bare), url_encrypted, chat_type)
|
||||
else:
|
||||
XmppMessage.send_oob(self, jid_bare, url, chat_type)
|
||||
url_field = form.add_field(var=ext.upper(),
|
||||
ftype='text-single',
|
||||
|
@ -2922,9 +2891,6 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
session["has_next"] = False
|
||||
session['next'] = None
|
||||
session['payload'] = form
|
||||
else:
|
||||
text_warn = 'OPML file export has been failed.'
|
||||
session['notes'] = [['warn', text_warn]]
|
||||
return session
|
||||
|
||||
|
||||
|
@ -2932,12 +2898,12 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
# TODO Attempt to look up for feeds of hostname of JID (i.e. scan
|
||||
# jabber.de for feeds for juliet@jabber.de)
|
||||
async def _handle_promoted(self, iq, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
jid_bare = session['from'].bare
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
chat_type = await XmppUtilities.get_chat_type(self, jid_bare)
|
||||
if XmppUtilities.is_access(self, jid_bare, jid_full, chat_type):
|
||||
form = self['xep_0004'].make_form('form', 'Subscribe')
|
||||
|
@ -3005,7 +2971,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_admin_action(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -3081,7 +3047,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
form['instructions'] = ('Select a Publish-Subscribe service '
|
||||
'of which nodes you want to list.')
|
||||
# jid_bare = self.boundjid.bare
|
||||
# enabled_state = Config.get_setting_value(self, jid_bare, 'enabled')
|
||||
# enabled_state = Config.get_setting_value(self.settings, jid_bare, 'enabled')
|
||||
|
||||
results = await XmppPubsub.get_pubsub_services(self)
|
||||
options = form.add_field(desc='Select a PubSub service.',
|
||||
|
@ -3106,7 +3072,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
ftype='fixed',
|
||||
label='Jabber ID')
|
||||
# jid_bare = self.boundjid.bare
|
||||
# enabled_state = Config.get_setting_value(self, jid_bare, 'enabled')
|
||||
# enabled_state = Config.get_setting_value(self.settings, jid_bare, 'enabled')
|
||||
|
||||
results = await XmppPubsub.get_pubsub_services(self)
|
||||
for result in results + [{'jid' : self.boundjid.bare,
|
||||
|
@ -3114,7 +3080,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
jid_bare = result['jid']
|
||||
name = result['name']
|
||||
enabled_state = Config.get_setting_value(
|
||||
self, jid_bare, 'enabled')
|
||||
self.settings, jid_bare, 'enabled')
|
||||
form.add_field(desc=jid_bare,
|
||||
ftype='boolean',
|
||||
label=name,
|
||||
|
@ -3130,7 +3096,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
def _handle_nodes(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -3158,7 +3124,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_nodes_action(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -3217,7 +3183,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_node_browse(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -3248,7 +3214,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_item_view(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -3284,7 +3250,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
# FIXME Undefined name 'jid_bare'
|
||||
async def _handle_node_edit(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -3337,7 +3303,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_nodes_purge(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -3355,7 +3321,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_nodes_delete(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -3373,7 +3339,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_pubsub_complete(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -3385,9 +3351,9 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
value = values[key]
|
||||
db_file = config.get_pathname_to_database(jid_bare)
|
||||
if jid_bare not in self.settings:
|
||||
Config.add_settings_jid(self, jid_bare, db_file)
|
||||
await Config.set_setting_value(
|
||||
self, jid_bare, db_file, 'enabled', value)
|
||||
Config.add_settings_jid(self.settings, jid_bare, db_file)
|
||||
await Config.set_setting_value(self.settings, jid_bare,
|
||||
db_file, 'enabled', value)
|
||||
print(self.settings)
|
||||
text_note = 'Done.'
|
||||
session['has_next'] = False
|
||||
|
@ -3398,7 +3364,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_subscribers_complete(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -3446,7 +3412,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_contact_action(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -3514,7 +3480,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
def _handle_contacts_complete(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -3538,7 +3504,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_bookmarks_edit(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -3603,7 +3569,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_bookmarks_complete(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -3638,7 +3604,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
session. Additional, custom data may be saved
|
||||
here to persist across handler callbacks.
|
||||
"""
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
|
@ -3647,10 +3613,10 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
if XmppUtilities.is_access(self, jid_bare, jid_full, chat_type):
|
||||
db_file = config.get_pathname_to_database(jid_bare)
|
||||
if jid_bare not in self.settings:
|
||||
Config.add_settings_jid(self, jid_bare, db_file)
|
||||
Config.add_settings_jid(self.settings, jid_bare, db_file)
|
||||
form = self['xep_0004'].make_form('form', 'Settings')
|
||||
form['instructions'] = 'Editing settings of {}'.format(jid_bare)
|
||||
value = Config.get_setting_value(self, jid_bare, 'enabled')
|
||||
value = Config.get_setting_value(self.settings, jid_bare, 'enabled')
|
||||
value = str(value)
|
||||
value = int(value)
|
||||
if value:
|
||||
|
@ -3662,7 +3628,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
label='Enabled',
|
||||
value=value,
|
||||
var='enabled')
|
||||
value = Config.get_setting_value(self, jid_bare, 'media')
|
||||
value = Config.get_setting_value(self.settings, jid_bare, 'media')
|
||||
value = str(value)
|
||||
value = int(value)
|
||||
if value:
|
||||
|
@ -3674,7 +3640,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
label='Display media',
|
||||
value=value,
|
||||
var='media')
|
||||
value = Config.get_setting_value(self, jid_bare, 'old')
|
||||
value = Config.get_setting_value(self.settings, jid_bare, 'old')
|
||||
value = str(value)
|
||||
value = int(value)
|
||||
if value:
|
||||
|
@ -3688,7 +3654,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
label='Include old news',
|
||||
value=value,
|
||||
var='old')
|
||||
value = Config.get_setting_value(self, jid_bare, 'interval')
|
||||
value = Config.get_setting_value(self.settings, jid_bare, 'interval')
|
||||
value = str(value)
|
||||
value = int(value)
|
||||
value = value/60
|
||||
|
@ -3709,7 +3675,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
i += 6
|
||||
else:
|
||||
i += 1
|
||||
value = Config.get_setting_value(self, jid_bare, 'quantum')
|
||||
value = Config.get_setting_value(self.settings, jid_bare, 'quantum')
|
||||
value = str(value)
|
||||
options = form.add_field(desc='Amount of items per update.',
|
||||
ftype='list-single',
|
||||
|
@ -3723,7 +3689,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
x = str(i)
|
||||
options.addOption(x, x)
|
||||
i += 1
|
||||
value = Config.get_setting_value(self, jid_bare, 'archive')
|
||||
value = Config.get_setting_value(self.settings, jid_bare, 'archive')
|
||||
value = str(value)
|
||||
options = form.add_field(desc='Number of news items to archive.',
|
||||
ftype='list-single',
|
||||
|
@ -3757,14 +3723,14 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
|
||||
|
||||
async def _handle_settings_complete(self, payload, session):
|
||||
jid_full = session['from'].full
|
||||
jid_full = str(session['from'])
|
||||
function_name = sys._getframe().f_code.co_name
|
||||
logger.debug('{}: jid_full: {}'
|
||||
.format(function_name, jid_full))
|
||||
jid_bare = session['from'].bare
|
||||
db_file = config.get_pathname_to_database(jid_bare)
|
||||
if jid_bare not in self.settings:
|
||||
Config.add_settings_jid(self, jid_bare, db_file)
|
||||
Config.add_settings_jid(self.settings, jid_bare, db_file)
|
||||
# In this case (as is typical), the payload is a form
|
||||
values = payload['values']
|
||||
for key in values:
|
||||
|
@ -3783,7 +3749,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
if val < 1: val = 1
|
||||
val = val * 60
|
||||
|
||||
is_enabled = Config.get_setting_value(self, jid_bare, 'enabled')
|
||||
is_enabled = Config.get_setting_value(self.settings, jid_bare, 'enabled')
|
||||
|
||||
if (key == 'enabled' and
|
||||
val == 1 and
|
||||
|
@ -3809,7 +3775,7 @@ class XmppClient(slixmpp.ClientXMPP):
|
|||
XmppPresence.send(self, jid_bare, status_message,
|
||||
status_type=status_type)
|
||||
|
||||
await Config.set_setting_value(self, jid_bare, db_file, key, val)
|
||||
await Config.set_setting_value(self.settings, jid_bare, db_file, key, val)
|
||||
val = self.settings[jid_bare][key]
|
||||
|
||||
if key in ('enabled', 'media', 'old'):
|
||||
|
|
|
@ -174,8 +174,10 @@ class XmppCommands:
|
|||
# the look into function "check_updates" of module "task".
|
||||
# await action.scan(self, jid_bare, db_file, url)
|
||||
# if jid_bare not in self.settings:
|
||||
# Config.add_settings_jid(self, jid_bare, db_file)
|
||||
# old = Config.get_setting_value(self, jid_bare, 'old')
|
||||
# Config.add_settings_jid(self.settings, jid_bare,
|
||||
# db_file)
|
||||
# old = Config.get_setting_value(self.settings, jid_bare,
|
||||
# 'old')
|
||||
# if old:
|
||||
# # task.clean_tasks_xmpp_chat(self, jid_bare, ['status'])
|
||||
# # await send_status(jid)
|
||||
|
@ -232,7 +234,8 @@ class XmppCommands:
|
|||
|
||||
|
||||
def get_archive(self, jid_bare):
|
||||
result = Config.get_setting_value(self, jid_bare, 'archive')
|
||||
result = Config.get_setting_value(
|
||||
self.settings, jid_bare, 'archive')
|
||||
message = str(result)
|
||||
return message
|
||||
|
||||
|
@ -243,9 +246,10 @@ class XmppCommands:
|
|||
if val_new > 500:
|
||||
message = 'Value may not be greater than 500.'
|
||||
else:
|
||||
val_old = Config.get_setting_value(self, jid_bare, 'archive')
|
||||
val_old = Config.get_setting_value(
|
||||
self.settings, jid_bare, 'archive')
|
||||
await Config.set_setting_value(
|
||||
self, jid_bare, db_file, 'archive', val_new)
|
||||
self.settings, jid_bare, db_file, 'archive', val_new)
|
||||
message = ('Maximum archived items has been set to {} (was: {}).'
|
||||
.format(val_new, val_old))
|
||||
except:
|
||||
|
@ -330,9 +334,9 @@ class XmppCommands:
|
|||
|
||||
|
||||
def export_feeds(jid_bare, ext):
|
||||
pathname = Feed.export_feeds(jid_bare, ext)
|
||||
filename = Feed.export_feeds(jid_bare, ext)
|
||||
message = 'Feeds successfuly exported to {}.'.format(ext)
|
||||
return pathname, message
|
||||
return filename, message
|
||||
|
||||
|
||||
def fetch_gemini():
|
||||
|
@ -546,7 +550,8 @@ class XmppCommands:
|
|||
|
||||
|
||||
def get_interval(self, jid_bare):
|
||||
result = Config.get_setting_value(self, jid_bare, 'interval')
|
||||
result = Config.get_setting_value(
|
||||
self.settings, jid_bare, 'interval')
|
||||
message = str(result)
|
||||
return message
|
||||
|
||||
|
@ -554,9 +559,10 @@ class XmppCommands:
|
|||
async def set_interval(self, db_file, jid_bare, val):
|
||||
try:
|
||||
val_new = int(val)
|
||||
val_old = Config.get_setting_value(self, jid_bare, 'interval')
|
||||
val_old = Config.get_setting_value(
|
||||
self.settings, jid_bare, 'interval')
|
||||
await Config.set_setting_value(
|
||||
self, jid_bare, db_file, 'interval', val_new)
|
||||
self.settings, jid_bare, db_file, 'interval', val_new)
|
||||
message = ('Updates will be sent every {} minutes '
|
||||
'(was: {}).'.format(val_new, val_old))
|
||||
except Exception as e:
|
||||
|
@ -590,7 +596,8 @@ class XmppCommands:
|
|||
|
||||
|
||||
def get_length(self, jid_bare):
|
||||
result = Config.get_setting_value(self, jid_bare, 'length')
|
||||
result = Config.get_setting_value(
|
||||
self.settings, jid_bare, 'length')
|
||||
result = str(result)
|
||||
return result
|
||||
|
||||
|
@ -598,9 +605,10 @@ class XmppCommands:
|
|||
async def set_length(self, db_file, jid_bare, val):
|
||||
try:
|
||||
val_new = int(val)
|
||||
val_old = Config.get_setting_value(self, jid_bare, 'length')
|
||||
val_old = Config.get_setting_value(
|
||||
self.settings, jid_bare, 'length')
|
||||
await Config.set_setting_value(
|
||||
self, jid_bare, db_file, 'length', val_new)
|
||||
self.settings, jid_bare, db_file, 'length', val_new)
|
||||
if not val_new: # i.e. val_new == 0
|
||||
# TODO Add action to disable limit
|
||||
message = ('Summary length limit is disabled '
|
||||
|
@ -617,41 +625,29 @@ class XmppCommands:
|
|||
|
||||
|
||||
async def set_media_off(self, jid_bare, db_file):
|
||||
await Config.set_setting_value(self, jid_bare, db_file, 'media', 0)
|
||||
await Config.set_setting_value(self.settings, jid_bare, db_file, 'media', 0)
|
||||
message = 'Media is disabled.'
|
||||
return message
|
||||
|
||||
|
||||
async def set_media_on(self, jid_bare, db_file):
|
||||
await Config.set_setting_value(self, jid_bare, db_file, 'media', 1)
|
||||
await Config.set_setting_value(self.settings, jid_bare, db_file, 'media', 1)
|
||||
message = 'Media is enabled.'
|
||||
return message
|
||||
|
||||
|
||||
async def set_old_off(self, jid_bare, db_file):
|
||||
await Config.set_setting_value(self, jid_bare, db_file, 'old', 0)
|
||||
await Config.set_setting_value(self.settings, jid_bare, db_file, 'old', 0)
|
||||
message = 'Only new items of newly added feeds be delivered.'
|
||||
return message
|
||||
|
||||
|
||||
async def set_old_on(self, jid_bare, db_file):
|
||||
await Config.set_setting_value(self, jid_bare, db_file, 'old', 1)
|
||||
await Config.set_setting_value(self.settings, jid_bare, db_file, 'old', 1)
|
||||
message = 'All items of newly added feeds be delivered.'
|
||||
return message
|
||||
|
||||
|
||||
async def set_omemo_off(self, jid_bare, db_file):
|
||||
await Config.set_setting_value(self, jid_bare, db_file, 'omemo', 0)
|
||||
message = 'OMEMO is disabled.'
|
||||
return message
|
||||
|
||||
|
||||
async def set_omemo_on(self, jid_bare, db_file):
|
||||
await Config.set_setting_value(self, jid_bare, db_file, 'omemo', 1)
|
||||
message = 'OMEMO is enabled.'
|
||||
return message
|
||||
|
||||
|
||||
def node_delete(self, info):
|
||||
info = info.split(' ')
|
||||
if len(info) > 2:
|
||||
|
@ -691,8 +687,8 @@ class XmppCommands:
|
|||
def print_options(self, jid_bare):
|
||||
message = ''
|
||||
for key in self.settings[jid_bare]:
|
||||
val = Config.get_setting_value(self, jid_bare, key)
|
||||
# val = Config.get_setting_value(self, jid_bare, key)
|
||||
val = Config.get_setting_value(self.settings, jid_bare, key)
|
||||
# val = Config.get_setting_value(self.settings, jid_bare, key)
|
||||
steps = 11 - len(key)
|
||||
pulse = ''
|
||||
for step in range(steps):
|
||||
|
@ -702,7 +698,8 @@ class XmppCommands:
|
|||
|
||||
|
||||
def get_quantum(self, jid_bare):
|
||||
result = Config.get_setting_value(self, jid_bare, 'quantum')
|
||||
result = Config.get_setting_value(
|
||||
self.settings, jid_bare, 'quantum')
|
||||
message = str(result)
|
||||
return message
|
||||
|
||||
|
@ -710,13 +707,14 @@ class XmppCommands:
|
|||
async def set_quantum(self, db_file, jid_bare, val):
|
||||
try:
|
||||
val_new = int(val)
|
||||
val_old = Config.get_setting_value(self, jid_bare, 'quantum')
|
||||
val_old = Config.get_setting_value(
|
||||
self.settings, jid_bare, 'quantum')
|
||||
# response = (
|
||||
# 'Every update will contain {} news items.'
|
||||
# ).format(response)
|
||||
db_file = config.get_pathname_to_database(jid_bare)
|
||||
await Config.set_setting_value(
|
||||
self, jid_bare, db_file, 'quantum', val_new)
|
||||
await Config.set_setting_value(self.settings, jid_bare,
|
||||
db_file, 'quantum', val_new)
|
||||
message = ('Next update will contain {} news items (was: {}).'
|
||||
.format(val_new, val_old))
|
||||
except:
|
||||
|
@ -960,16 +958,17 @@ class XmppCommands:
|
|||
|
||||
# Tasks are classes which are passed to this function
|
||||
# On an occasion in which they would have returned, variable "tasks" might be called "callback"
|
||||
async def scheduler_start(self, db_file, jid_bare, callbacks):
|
||||
await Config.set_setting_value(self, jid_bare, db_file, 'enabled', 1)
|
||||
for callback in callbacks:
|
||||
callback.restart_task(self, jid_bare)
|
||||
async def scheduler_start(self, db_file, jid_bare, tasks):
|
||||
await Config.set_setting_value(self.settings, jid_bare, db_file, 'enabled', 1)
|
||||
for task in tasks:
|
||||
task.restart_task(self, jid_bare)
|
||||
message = 'Updates are enabled.'
|
||||
return message
|
||||
|
||||
|
||||
async def scheduler_stop(self, db_file, jid_bare):
|
||||
await Config.set_setting_value(self, jid_bare, db_file, 'enabled', 0)
|
||||
await Config.set_setting_value(
|
||||
self.settings, jid_bare, db_file, 'enabled', 0)
|
||||
for task in ('interval', 'status'):
|
||||
if (jid_bare in self.task_manager and
|
||||
task in self.task_manager[jid_bare]):
|
||||
|
|
|
@ -1,180 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
||||
TODO
|
||||
|
||||
1) Deprecate "add" (see above) and make it interactive.
|
||||
Slixfeed: Do you still want to add this URL to subscription list?
|
||||
See: case _ if command_lowercase.startswith("add"):
|
||||
|
||||
2) If subscription is inadequate (see XmppPresence.request), send a message that says so.
|
||||
|
||||
elif not self.client_roster[jid]["to"]:
|
||||
breakpoint()
|
||||
message.reply("Share online status to activate bot.").send()
|
||||
return
|
||||
|
||||
3) Set timeout for moderator interaction.
|
||||
If moderator interaction has been made, and moderator approves the bot, then
|
||||
the bot will add the given groupchat to bookmarks; otherwise, the bot will
|
||||
send a message that it was not approved and therefore leaves the groupchat.
|
||||
|
||||
"""
|
||||
|
||||
from omemo.exceptions import MissingBundleException
|
||||
from slixfeed.log import Logger
|
||||
from slixmpp import JID
|
||||
from slixmpp.exceptions import IqTimeout, IqError
|
||||
from slixmpp.stanza import Message
|
||||
from slixmpp_omemo import MissingOwnKey, EncryptionPrepareException
|
||||
from slixmpp_omemo import UndecidedException, UntrustedException, NoAvailableSession
|
||||
|
||||
|
||||
logger = Logger(__name__)
|
||||
|
||||
|
||||
# for task in main_task:
|
||||
# task.cancel()
|
||||
|
||||
# Deprecated in favour of event "presence_available"
|
||||
# if not main_task:
|
||||
# await select_file()
|
||||
|
||||
|
||||
class XmppOmemo:
|
||||
|
||||
|
||||
async def decrypt(self, message: Message, allow_untrusted: bool = False):
|
||||
jid = message['from']
|
||||
try:
|
||||
message_omemo_encrypted = message['omemo_encrypted']
|
||||
message_body = await self['xep_0384'].decrypt_message(
|
||||
message_omemo_encrypted, jid, allow_untrusted)
|
||||
# decrypt_message returns Optional[str]. It is possible to get
|
||||
# body-less OMEMO message (see KeyTransportMessages), currently
|
||||
# used for example to send heartbeats to other devices.
|
||||
if message_body is not None:
|
||||
response = message_body.decode('utf8')
|
||||
omemo_decrypted = True
|
||||
else:
|
||||
omemo_decrypted = response = None
|
||||
retry = None
|
||||
except (MissingOwnKey,) as exn:
|
||||
# The message is missing our own key, it was not encrypted for
|
||||
# us, and we can't decrypt it.
|
||||
response = ('Error: Your message has not been encrypted for '
|
||||
'Slixfeed (MissingOwnKey).')
|
||||
omemo_decrypted = False
|
||||
retry = False
|
||||
logger.error(exn)
|
||||
except (NoAvailableSession,) as exn:
|
||||
# We received a message from that contained a session that we
|
||||
# don't know about (deleted session storage, etc.). We can't
|
||||
# decrypt the message, and it's going to be lost.
|
||||
# Here, as we need to initiate a new encrypted session, it is
|
||||
# best if we send an encrypted message directly. XXX: Is it
|
||||
# where we talk about self-healing messages?
|
||||
response = ('Error: Your message has not been encrypted for '
|
||||
'Slixfeed (NoAvailableSession).')
|
||||
omemo_decrypted = False
|
||||
retry = False
|
||||
logger.error(exn)
|
||||
except (UndecidedException, UntrustedException) as exn:
|
||||
# We received a message from an untrusted device. We can
|
||||
# choose to decrypt the message nonetheless, with the
|
||||
# `allow_untrusted` flag on the `decrypt_message` call, which
|
||||
# we will do here. This is only possible for decryption,
|
||||
# encryption will require us to decide if we trust the device
|
||||
# or not. Clients _should_ indicate that the message was not
|
||||
# trusted, or in undecided state, if they decide to decrypt it
|
||||
# anyway.
|
||||
response = (f'Error: Device "{exn.device}" is not present in the '
|
||||
'trusted devices of Slixfeed.')
|
||||
omemo_decrypted = False
|
||||
retry = True
|
||||
logger.error(exn)
|
||||
# We resend, setting the `allow_untrusted` parameter to True.
|
||||
# await XmppChat.process_message(self, message, allow_untrusted=True)
|
||||
except (EncryptionPrepareException,) as exn:
|
||||
# Slixmpp tried its best, but there were errors it couldn't
|
||||
# resolve. At this point you should have seen other exceptions
|
||||
# and given a chance to resolve them already.
|
||||
response = ('Error: Your message has not been encrypted for '
|
||||
'Slixfeed (EncryptionPrepareException).')
|
||||
omemo_decrypted = False
|
||||
retry = False
|
||||
logger.error(exn)
|
||||
except (Exception,) as exn:
|
||||
response = ('Error: Your message has not been encrypted for '
|
||||
'Slixfeed (Unknown).')
|
||||
omemo_decrypted = False
|
||||
retry = False
|
||||
logger.error(exn)
|
||||
raise
|
||||
|
||||
return response, omemo_decrypted, retry
|
||||
|
||||
|
||||
async def encrypt(self, jid: JID, message_body):
|
||||
expect_problems = {} # type: Optional[Dict[JID, List[int]]]
|
||||
while True:
|
||||
try:
|
||||
# `encrypt_message` excepts the plaintext to be sent, a list of
|
||||
# bare JIDs to encrypt to, and optionally a dict of problems to
|
||||
# expect per bare JID.
|
||||
#
|
||||
# Note that this function returns an `<encrypted/>` object,
|
||||
# and not a full Message stanza. This combined with the
|
||||
# `recipients` parameter that requires for a list of JIDs,
|
||||
# allows you to encrypt for 1:1 as well as groupchats (MUC).
|
||||
#
|
||||
# `expect_problems`: See EncryptionPrepareException handling.
|
||||
recipients = [jid]
|
||||
message_body = await self['xep_0384'].encrypt_message(
|
||||
message_body, recipients, expect_problems)
|
||||
omemo_encrypted = True
|
||||
break
|
||||
except UndecidedException as exn:
|
||||
# The library prevents us from sending a message to an
|
||||
# untrusted/undecided barejid, so we need to make a decision here.
|
||||
# This is where you prompt your user to ask what to do. In
|
||||
# this bot we will automatically trust undecided recipients.
|
||||
await self['xep_0384'].trust(exn.bare_jid, exn.device, exn.ik)
|
||||
omemo_encrypted = False
|
||||
# TODO: catch NoEligibleDevicesException
|
||||
except EncryptionPrepareException as exn:
|
||||
# This exception is being raised when the library has tried
|
||||
# all it could and doesn't know what to do anymore. It
|
||||
# contains a list of exceptions that the user must resolve, or
|
||||
# explicitely ignore via `expect_problems`.
|
||||
# TODO: We might need to bail out here if errors are the same?
|
||||
for error in exn.errors:
|
||||
if isinstance(error, MissingBundleException):
|
||||
# We choose to ignore MissingBundleException. It seems
|
||||
# to be somewhat accepted that it's better not to
|
||||
# encrypt for a device if it has problems and encrypt
|
||||
# for the rest, rather than error out. The "faulty"
|
||||
# device won't be able to decrypt and should display a
|
||||
# generic message. The receiving end-user at this
|
||||
# point can bring up the issue if it happens.
|
||||
message_body = (f'Could not find keys for device '
|
||||
'"{error.device}"'
|
||||
f' of recipient "{error.bare_jid}". '
|
||||
'Skipping.')
|
||||
omemo_encrypted = False
|
||||
jid = JID(error.bare_jid)
|
||||
device_list = expect_problems.setdefault(jid, [])
|
||||
device_list.append(error.device)
|
||||
except (IqError, IqTimeout) as exn:
|
||||
message_body = ('An error occured while fetching information '
|
||||
'on a recipient.\n%r' % exn)
|
||||
omemo_encrypted = False
|
||||
except Exception as exn:
|
||||
message_body = ('An error occured while attempting to encrypt'
|
||||
'.\n%r' % exn)
|
||||
omemo_encrypted = False
|
||||
raise
|
||||
|
||||
return message_body, omemo_encrypted
|
|
@ -34,24 +34,14 @@ class XmppGroupchat:
|
|||
'bookmark {}'.format(bookmark['name']))
|
||||
alias = bookmark["nick"]
|
||||
muc_jid = bookmark["jid"]
|
||||
# Message.printer('Joining to MUC {} ...'.format(muc_jid))
|
||||
print('Joining to MUC {} ...'.format(muc_jid))
|
||||
Message.printer('Joining to MUC {} ...'.format(muc_jid))
|
||||
result = await XmppMuc.join(self, muc_jid, alias)
|
||||
match result:
|
||||
case 'ban':
|
||||
if result == 'ban':
|
||||
await XmppBookmark.remove(self, muc_jid)
|
||||
logger.warning('{} is banned from {}'.format(self.alias, muc_jid))
|
||||
logger.warning('Groupchat {} has been removed from bookmarks'
|
||||
.format(muc_jid))
|
||||
case 'error':
|
||||
logger.warning('An error has occured while attempting '
|
||||
'to join to groupchat {}'
|
||||
.format(muc_jid))
|
||||
case 'timeout':
|
||||
logger.warning('Timeout has reached while attempting '
|
||||
'to join to groupchat {}'
|
||||
.format(muc_jid))
|
||||
case _:
|
||||
else:
|
||||
logger.info('Autojoin groupchat\n'
|
||||
'Name : {}\n'
|
||||
'JID : {}\n'
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from slixfeed.log import Logger
|
||||
from slixmpp import JID
|
||||
import xml.sax.saxutils as saxutils
|
||||
|
||||
logger = Logger(__name__)
|
||||
|
@ -40,43 +39,6 @@ class XmppMessage:
|
|||
mnick=self.alias)
|
||||
|
||||
|
||||
def send_omemo(self, jid: JID, chat_type, response_encrypted):
|
||||
jid_from = str(self.boundjid) if self.is_component else None
|
||||
message = self.make_message(mto=jid, mfrom=jid_from, mtype=chat_type)
|
||||
eme_ns = 'eu.siacs.conversations.axolotl'
|
||||
# message['eme']['namespace'] = eme_ns
|
||||
# message['eme']['name'] = self['xep_0380'].mechanisms[eme_ns]
|
||||
message['eme'] = {'namespace': eme_ns}
|
||||
# message['eme'] = {'name': self['xep_0380'].mechanisms[eme_ns]}
|
||||
message.append(response_encrypted)
|
||||
message.send()
|
||||
|
||||
|
||||
def send_omemo_oob(self, jid: JID, url_encrypted, chat_type, aesgcm=False):
|
||||
jid_from = str(self.boundjid) if self.is_component else None
|
||||
# if not aesgcm: url_encrypted = saxutils.escape(url_encrypted)
|
||||
message = self.make_message(mto=jid, mfrom=jid_from, mtype=chat_type)
|
||||
eme_ns = 'eu.siacs.conversations.axolotl'
|
||||
# message['eme']['namespace'] = eme_ns
|
||||
# message['eme']['name'] = self['xep_0380'].mechanisms[eme_ns]
|
||||
message['eme'] = {'namespace': eme_ns}
|
||||
# message['eme'] = {'name': self['xep_0380'].mechanisms[eme_ns]}
|
||||
message['oob']['url'] = url_encrypted
|
||||
message.append(url_encrypted)
|
||||
message.send()
|
||||
|
||||
|
||||
# FIXME Solve this function
|
||||
def send_omemo_reply(self, message, response_encrypted):
|
||||
eme_ns = 'eu.siacs.conversations.axolotl'
|
||||
# message['eme']['namespace'] = eme_ns
|
||||
# message['eme']['name'] = self['xep_0380'].mechanisms[eme_ns]
|
||||
message['eme'] = {'namespace': eme_ns}
|
||||
# message['eme'] = {'name': self['xep_0380'].mechanisms[eme_ns]}
|
||||
message.append(response_encrypted)
|
||||
message.reply(message['body']).send()
|
||||
|
||||
|
||||
# NOTE We might want to add more characters
|
||||
# def escape_to_xml(raw_string):
|
||||
# escape_map = {
|
||||
|
|
|
@ -46,7 +46,7 @@ class XmppMuc:
|
|||
# )
|
||||
logger.info('Joining groupchat\nJID : {}\n'.format(jid))
|
||||
jid_from = str(self.boundjid) if self.is_component else None
|
||||
if not alias: alias = self.alias
|
||||
if alias == None: self.alias
|
||||
try:
|
||||
await self.plugin['xep_0045'].join_muc_wait(jid,
|
||||
alias,
|
||||
|
|
|
@ -379,7 +379,7 @@ class XmppPubsubTask:
|
|||
async def task_publish(self, jid_bare):
|
||||
db_file = config.get_pathname_to_database(jid_bare)
|
||||
if jid_bare not in self.settings:
|
||||
Config.add_settings_jid(self, jid_bare, db_file)
|
||||
Config.add_settings_jid(self.settings, jid_bare, db_file)
|
||||
while True:
|
||||
await XmppPubsubAction.send_unread_items(self, jid_bare)
|
||||
await asyncio.sleep(60 * 180)
|
||||
|
|
|
@ -28,7 +28,7 @@ class XmppStatus:
|
|||
logger.debug('{}: jid: {}'.format(function_name, jid_bare))
|
||||
status_text = '📜️ Slixfeed RSS News Bot'
|
||||
db_file = config.get_pathname_to_database(jid_bare)
|
||||
enabled = Config.get_setting_value(self, jid_bare, 'enabled')
|
||||
enabled = Config.get_setting_value(self.settings, jid_bare, 'enabled')
|
||||
if enabled:
|
||||
jid_task = self.pending_tasks[jid_bare] if jid_bare in self.pending_tasks else None
|
||||
if jid_task and len(jid_task):
|
||||
|
@ -50,7 +50,7 @@ class XmppStatus:
|
|||
status_text = '📬️ There are {} news items'.format(str(unread))
|
||||
else:
|
||||
# print('status no news for ' + jid_bare)
|
||||
status_mode = 'away'
|
||||
status_mode = 'available'
|
||||
status_text = '📭️ No news'
|
||||
else:
|
||||
# print('status disabled for ' + jid_bare)
|
||||
|
|
|
@ -6,51 +6,47 @@ Based on http_upload.py example from project slixmpp
|
|||
https://codeberg.org/poezio/slixmpp/src/branch/master/examples/http_upload.py
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
from slixfeed.log import Logger
|
||||
from slixmpp import JID
|
||||
from slixmpp.exceptions import IqTimeout, IqError
|
||||
from slixmpp.plugins.xep_0363.http_upload import HTTPError
|
||||
import sys
|
||||
from typing import Optional
|
||||
|
||||
logger = Logger(__name__)
|
||||
# import sys
|
||||
|
||||
class XmppUpload:
|
||||
|
||||
async def start(self, jid, filename: Path, size: Optional[int] = None,
|
||||
encrypted: bool = False, domain: Optional[JID] = None):
|
||||
async def start(self, jid, filename, domain=None):
|
||||
logger.info(['Uploading file %s...', filename])
|
||||
try:
|
||||
upload_file = self['xep_0363'].upload_file
|
||||
if encrypted and not self['xep_0454']:
|
||||
print(
|
||||
'The xep_0454 module isn\'t available. '
|
||||
'Ensure you have \'cryptography\' '
|
||||
'from extras_require installed.',
|
||||
file=sys.stderr,
|
||||
)
|
||||
url = None
|
||||
elif encrypted:
|
||||
upload_file = self['xep_0454'].upload_file
|
||||
# if self.encrypted and not self['xep_0454']:
|
||||
# print(
|
||||
# 'The xep_0454 module isn\'t available. '
|
||||
# 'Ensure you have \'cryptography\' '
|
||||
# 'from extras_require installed.',
|
||||
# file=sys.stderr,
|
||||
# )
|
||||
# return
|
||||
# elif self.encrypted:
|
||||
# upload_file = self['xep_0454'].upload_file
|
||||
try:
|
||||
url = await upload_file(filename, size, domain, timeout=10,)
|
||||
url = await upload_file(
|
||||
filename, domain, timeout=10,
|
||||
)
|
||||
logger.info('Upload successful!')
|
||||
logger.info(['Sending file to %s', jid])
|
||||
except HTTPError:
|
||||
url = None
|
||||
url = ('Error: It appears that this server does not support '
|
||||
'HTTP File Upload.')
|
||||
logger.error('It appears that this server does not support '
|
||||
'HTTP File Upload.')
|
||||
# raise HTTPError(
|
||||
# "This server doesn't appear to support HTTP File Upload"
|
||||
# )
|
||||
except IqError as e:
|
||||
url = None
|
||||
logger.error('Could not send message')
|
||||
logger.error(e)
|
||||
except IqTimeout as e:
|
||||
url = None
|
||||
# raise TimeoutError('Could not send message in time')
|
||||
logger.error('Could not send message in time')
|
||||
logger.error(e)
|
||||
|
|
Loading…
Reference in a new issue