Compare commits

...

10 commits

Author SHA1 Message Date
89bbecbf7a
Remove bad data from cherry-pick conflict 2024-05-20 22:50:02 -05:00
59753ae05a
Bitbot Python3.11 Inital Commit - Port to develop 2024-05-20 22:47:33 -05:00
David Schultz
af2ff08c3c rss: tweak migration regex
This pattern best reflects the custom formats currently in use
2023-06-16 21:57:32 -05:00
David Schultz
59ed31f5d9 rss: make format migration actually work 2023-06-16 21:47:00 -05:00
Val Lorentz
ababe8428a
rss: Replace crashy double-formatting with standard format_token_replace (#370)
* rss: Simplify entry formatting

* Use format_token_replace

* Apply suggestions

* add `rss-format` config migration

---------

Co-authored-by: David Schultz <me@zpld.me>
2023-06-13 21:12:18 -05:00
dependabot[bot]
0addf135ce
Bump tornado from 6.0.3 to 6.3.2 (#366)
* Bump requests from 2.22.0 to 2.31.0 (#365)

Bumps [requests](https://github.com/psf/requests) from 2.22.0 to 2.31.0.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.22.0...v2.31.0)

---
updated-dependencies:
- dependency-name: requests
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump tornado from 6.0.3 to 6.3.2

Bumps [tornado](https://github.com/tornadoweb/tornado) from 6.0.3 to 6.3.2.
- [Changelog](https://github.com/tornadoweb/tornado/blob/master/docs/releases.rst)
- [Commits](https://github.com/tornadoweb/tornado/compare/v6.0.3...v6.3.2)

---
updated-dependencies:
- dependency-name: tornado
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: David Schultz <me@zpld.me>
2023-05-30 10:53:27 -05:00
e68b773f95
wolfram|alpha: squash newlines put in returned input (#361)
oddly, wolfram|alpha's returned input string can sometimes contain
newlines, especially when asking for distances between locations.
previously this caused bitbot's output to get cut off, sending the
remaining section to ,more
2023-04-18 19:57:32 -05:00
David Schultz
a357866480
ignore.py: allow ignoring commands in channel (#356) 2023-03-19 19:33:36 -05:00
musk
25fde5b7c1
Update nginx (#359)
Fix proxy_set_header Host $port to $server_port
2023-03-19 19:31:38 -05:00
David Schultz
c4a30430d4
requirement no longer necessary per #360 2023-03-19 19:20:47 -05:00
8 changed files with 92 additions and 29 deletions

View file

@ -8,7 +8,7 @@ server {
location / {
proxy_pass http://[::1]:5001;
proxy_set_header Host $host:$port;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Forwarded-For $remote_addr;
}
}

View file

@ -15,8 +15,8 @@ class Module(ModuleManager.BaseModule):
today = datetime.datetime.utcnow().date()
week = datetime.timedelta(days=7)
not_valid_until = (today-certificate.not_valid_before.date()).days
not_valid_after = (certificate.not_valid_after.date()-today).days
not_valid_until = (today-certificate.not_valid_before_utc.date()).days
not_valid_after = (certificate.not_valid_after_utc.date()-today).days
if not_valid_until < 0:
self.log.warn(

View file

@ -1,7 +1,7 @@
#--depends-on config
#--depends-on shorturl
import difflib, hashlib, time
import difflib, hashlib, time, re
from src import ModuleManager, utils
import feedparser
@ -13,22 +13,39 @@ SETTING_BIND = utils.Setting("rss-bindhost",
"Interval (in seconds) between RSS polls", example="120"))
@utils.export("channelset", utils.BoolSetting("rss-shorten",
"Whether or not to shorten RSS urls"))
@utils.export("channelset", utils.Setting("rss-format", "Format of RSS announcements", example="$longtitle: $title - $link [$author]"))
@utils.export("channelset", utils.Setting("rss-format", "Format of RSS announcements", example="${longtitle}: ${title} - ${link} [${author}]"))
@utils.export("serverset", SETTING_BIND)
@utils.export("channelset", SETTING_BIND)
class Module(ModuleManager.BaseModule):
_name = "RSS"
def _migrate_formats(self):
count = 0
migration_re = re.compile(r"(?:\$|{)+(?P<variable>[^}:\s]+)(?:})?")
old_formats = self.bot.database.execute_fetchall("""
SELECT channel_id, value FROM channel_settings
WHERE setting = 'rss-format'
""")
for channel_id, format in old_formats:
new_format = migration_re.sub(r"${\1}", format)
self.bot.database.execute("""
UPDATE channel_settings SET value = ?
WHERE setting = 'rss-format'
AND channel_id = ?
""", [new_format, channel_id])
count += 1
self.log.info("Successfully migrated %d rss-format settings" % count)
def on_load(self):
if not self.bot.get_setting("rss-fmt-migration", False):
self.log.info("Attempting to migrate old rss-format settings")
self._migrate_formats()
self.bot.set_setting("rss-fmt-migration", True)
self.timers.add("rss-feeds", self._timer,
self.bot.get_setting("rss-interval", RSS_INTERVAL))
def _format_entry(self, server, channel, feed_title, entry, shorten):
title = utils.parse.line_normalise(utils.http.strip_html(
entry["title"]))
author = entry.get("author", "unknown author")
author = "%s" % author if author else ""
link = entry.get("link", None)
if shorten:
try:
@ -37,16 +54,21 @@ class Module(ModuleManager.BaseModule):
pass
link = "%s" % link if link else ""
feed_title_str = "%s" % feed_title if feed_title else ""
variables = dict(
longtitle=feed_title or "",
title=utils.parse.line_normalise(utils.http.strip_html(
entry["title"])),
link=link or "",
author=entry.get("author", "unknown author") or "",
)
variables.update(entry)
# just in case the format starts keyerroring and you're not sure why
self.log.trace("RSS Entry: " + str(entry))
try:
format = channel.get_setting("rss-format", "$longtitle: $title by $author - $link").replace("$longtitle", feed_title_str).replace("$title", title).replace("$link", link).replace("$author", author).format(**entry)
except KeyError:
self.log.warn(f"Failed to format RSS entry for {channel}. Falling back to default format.")
format = f"{feed_title_str}: {title} by {author} - {link}"
template = channel.get_setting("rss-format", "${longtitle}: ${title} by ${author} - ${link}")
_, formatted = utils.parse.format_token_replace(template, variables)
return formatted
return format
def _timer(self, timer):
start_time = time.monotonic()

View file

@ -32,7 +32,7 @@ class Module(ModuleManager.BaseModule):
for pod in page["queryresult"]["pods"]:
text = pod["subpods"][0]["plaintext"]
if pod["id"] == "Input" and text:
input = text
input = text.replace("\n", " | ")
elif pod.get("primary", False):
primaries.append(text)

View file

@ -10,8 +10,7 @@ netifaces ==0.10.9
PySocks ==1.7.1
python-dateutil ==2.8.1
pytz ==2019.2
requests ==2.22.0
suds ==1.0.0
tornado ==6.0.3
requests ==2.31.0
tornado ==6.3.2
tweepy ==3.8.0
requests-toolbelt ==0.9.1

View file

@ -235,7 +235,7 @@ class ModuleManager(object):
definition.filename)
module = importlib.util.module_from_spec(import_spec)
sys.modules[import_name] = module
loader = typing.cast(importlib.abc.Loader, import_spec.loader)
loader = typing.cast(importlib._abc.Loader, import_spec.loader)
loader.exec_module(module)
module_object_pointer = getattr(module, "Module", None)

View file

@ -12,12 +12,23 @@ class Module(ModuleManager.BaseModule):
return channel.get_user_setting(user.get_id(), "ignore", False)
def _server_command_ignored(self, server, command):
return server.get_setting("ignore-%s" % command, False)
def _channel_command_ignored(self, channel, command):
return channel.get_setting("ignore-command-%s" % command, False)
def _is_command_ignored(self, server, user, command):
if self._user_command_ignored(user, command):
def _is_command_ignored(self, event):
if self._user_command_ignored(event["user"], event["command"]):
return True
elif self._server_command_ignored(server, command):
elif self._server_command_ignored(event["server"], event["command"]):
return True
elif event["is_channel"] and self._channel_command_ignored(event["target"], event["command"]):
return True
def _is_valid_command(self, command):
hooks = self.events.on("received.command").on(command).get_hooks()
if hooks:
return True
else:
return False
@utils.hook("received.message.private")
@utils.hook("received.message.channel")
@ -38,8 +49,7 @@ class Module(ModuleManager.BaseModule):
elif event["is_channel"] and self._user_channel_ignored(event["target"],
event["user"]):
return utils.consts.PERMISSION_HARD_FAIL, None
elif self._is_command_ignored(event["server"], event["user"],
event["command"]):
elif self._is_command_ignored(event):
return utils.consts.PERMISSION_HARD_FAIL, None
@utils.hook("received.command.ignore", min_args=1)
@ -123,6 +133,38 @@ class Module(ModuleManager.BaseModule):
True)
event["stdout"].write("Ignoring %s" % target_user.nickname)
@utils.hook("received.command.ignorecommand",
help="Ignore a command in this channel")
@utils.hook("received.command.unignorecommand",
help="Unignore a command in this channel")
@utils.kwarg("channel_only", True)
@utils.kwarg("min_args", 1)
@utils.kwarg("usage", "<command>")
@utils.kwarg("permission", "cignore")
@utils.kwarg("require_mode", "o")
@utils.kwarg("require_access", "high,cignore")
def cignore_command(self, event):
remove = event["command"] == "unignorecommand"
command = event["args_split"][0]
if not self._is_valid_command(command):
raise utils.EventError("Unknown command '%s'" % command)
is_ignored = self._channel_command_ignored(event["target"], command)
if remove:
if not is_ignored:
raise utils.EventError("I'm not ignoring '%s' in this channel" %
target_user.nickname)
event["target"].del_setting("ignore-command-%s" % command)
event["stdout"].write("Unignored '%s' command" % command)
else:
if is_ignored:
raise utils.EventError("I'm already ignoring '%s' in this channel"
% command)
event["target"].set_setting("ignore-command-%s" % command, True)
event["stdout"].write("Ignoring '%s' command" % command)
@utils.hook("received.command.serverignore")
@utils.kwarg("help", "Ignore a command on the current server")
@utils.kwarg("permission", "serverignore")

View file

@ -304,7 +304,7 @@ def request_many(requests: typing.List[Request]) -> typing.Dict[str, Response]:
loop = asyncio.new_event_loop()
awaits = []
for request in requests:
awaits.append(_request(request))
awaits.append(loop.create_task(_request(request)))
task = asyncio.wait(awaits, timeout=5)
loop.run_until_complete(task)
loop.close()