add feature: react to launchpad bugs
This commit is contained in:
parent
f7c75c5a33
commit
9972f4d53a
4 changed files with 69 additions and 35 deletions
|
@ -15,15 +15,6 @@ jobs:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- run: cp ubottu/config.yaml.deploy ubottu/config.yaml
|
|
||||||
- run: rm -f ubottu/config.yaml.deploy
|
|
||||||
- run: rm -f ubottu/config.yaml.default
|
|
||||||
- run: sed -i "s/%%UNSHARED_SECRET%%/${UNSHARED_SECRET}/g" ubottu/config.yaml
|
|
||||||
- run: sed -i "s/%%HOMESERVER_URL%%/${HOMESERVER_URL}/g" ubottu/config.yaml
|
|
||||||
- run: sed -i "s/%%HOMESERVER_SECRET%%/${HOMESERVER_SECRET}/g" ubottu/config.yaml
|
|
||||||
- run: sed -i "s/%%HOMESERVER_DOMAIN%%/${HOMESERVER_DOMAIN}/g" ubottu/config.yaml
|
|
||||||
- run: sed -i "s/%%ADMIN_PW%%/${ADMIN_PW}/g" ubottu/config.yaml
|
|
||||||
- run: sed -i "s/%%PUBLIC_URL%%/${PUBLIC_URL}/g" ubottu/config.yaml
|
|
||||||
- run: pip install maubot
|
- run: pip install maubot
|
||||||
- run: mbc build # Build the project
|
- run: mbc build # Build the project
|
||||||
- run: mkdir -p output # Ensure output directory exists, `-p` to prevent error if already exists
|
- run: mkdir -p output # Ensure output directory exists, `-p` to prevent error if already exists
|
||||||
|
|
9
USAGE.md
9
USAGE.md
|
@ -14,6 +14,15 @@ The available facts are available at [here](https://maubot.haxxors.com/factoids/
|
||||||
**Example 2**: `!noble | Bob`
|
**Example 2**: `!noble | Bob`
|
||||||
**Response**: Bob: Ubuntu 24.04 (Noble Numbat) will be the 40th...
|
**Response**: Bob: Ubuntu 24.04 (Noble Numbat) will be the 40th...
|
||||||
|
|
||||||
|
## Launchpad Bugs
|
||||||
|
|
||||||
|
The bot reacts to URLs from bugs.launchpad.net and to "bug [#]bugnumber" in messages.
|
||||||
|
|
||||||
|
**Example 1**: got this issue right now https://bugs.launchpad.net/snapd/+bug/2052688 on my computer
|
||||||
|
**Example 2**: i am affected by bug 2052688 on my computer
|
||||||
|
**Example 3**: i am affected by bug #2052688 on my computer
|
||||||
|
**Response**: Launchpad Bug #2052688 in snapd "run-snapd-ns-snapd\x2ddesktop [...] long time when system enter in shutdown" [Undecided, New]
|
||||||
|
|
||||||
## Time Commands
|
## Time Commands
|
||||||
|
|
||||||
### `!time <city>`
|
### `!time <city>`
|
||||||
|
|
|
@ -28,35 +28,12 @@ class Ubottu(Plugin):
|
||||||
return safe_string
|
return safe_string
|
||||||
|
|
||||||
async def pre_start(self) -> None:
|
async def pre_start(self) -> None:
|
||||||
#if await self.get_ubottu_db('https://ubottu.com/ubuntu3.db'):
|
|
||||||
# self.db = sqlite3.connect("/home/maubot/.ubottu/ubuntu3.db")
|
|
||||||
#else:
|
|
||||||
# return False
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
async def start(self) -> None:
|
async def start(self) -> None:
|
||||||
self.config.load_and_update()
|
self.config.load_and_update()
|
||||||
self.flood_protection = FloodProtection()
|
self.flood_protection = FloodProtection()
|
||||||
|
|
||||||
async def get_ubottu_db(self, url):
|
|
||||||
"""Load a file from a URL into an in-memory filesystem."""
|
|
||||||
# Create a filename if required
|
|
||||||
u = urlparse(url)
|
|
||||||
fn = "/home/maubot/.ubottu/" + os.path.basename(u.path)
|
|
||||||
#if os.path.isfile(fn):
|
|
||||||
# return fn
|
|
||||||
requests.packages.urllib3.util.connection.HAS_IPV6 = False
|
|
||||||
with requests.get(url, stream=True) as r:
|
|
||||||
r.raise_for_status() # Checks if the request was successful
|
|
||||||
# Open the local file in binary write mode
|
|
||||||
with open(fn, 'wb+') as f:
|
|
||||||
for chunk in r.iter_content(chunk_size=8192):
|
|
||||||
# If you have a chunk of data, write it to the file
|
|
||||||
if chunk:
|
|
||||||
f.write(chunk)
|
|
||||||
f.close()
|
|
||||||
return fn
|
|
||||||
|
|
||||||
def check_access(self, sender, room_id):
|
def check_access(self, sender, room_id):
|
||||||
if sender in self.config["whitelist"] and room_id in self.config["rooms"]:
|
if sender in self.config["whitelist"] and room_id in self.config["rooms"]:
|
||||||
return True
|
return True
|
||||||
|
@ -77,6 +54,14 @@ class Ubottu(Plugin):
|
||||||
#print(data)
|
#print(data)
|
||||||
await evt.reply(data['employees'][0]['email'])
|
await evt.reply(data['employees'][0]['email'])
|
||||||
|
|
||||||
|
async def lookup_launchpad_bug(self, bug_id):
|
||||||
|
url = 'http://127.0.0.1:8000/bugtracker/api/bugtracker/launchpad/' + str(bug_id) + '/'
|
||||||
|
resp = await self.http.get(url)
|
||||||
|
if resp.status == 200:
|
||||||
|
data = await resp.json()
|
||||||
|
return data
|
||||||
|
return False
|
||||||
|
|
||||||
async def lookup_factoid(self, command_name, to_user, evt):
|
async def lookup_factoid(self, command_name, to_user, evt):
|
||||||
api_url = 'http://127.0.0.1:8000/factoids/api/facts/'
|
api_url = 'http://127.0.0.1:8000/factoids/api/facts/'
|
||||||
url = api_url + command_name + '/?format=json'
|
url = api_url + command_name + '/?format=json'
|
||||||
|
@ -102,8 +87,26 @@ class Ubottu(Plugin):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@command.passive("bug #?(\d+)|https?:\/\/bugs\.launchpad\.net\/.+/(\d+)")
|
||||||
|
async def command_bug(self, evt: MessageEvent, match: Tuple[str]) -> None:
|
||||||
|
if match:
|
||||||
|
if match[1]:
|
||||||
|
bug_id = match[1]
|
||||||
|
if match[2]:
|
||||||
|
bug_id = match[2]
|
||||||
|
if self.flood_protection.flood_check_bug(bug_id) and self.flood_protection.flood_check(evt.sender):
|
||||||
|
data = await self.lookup_launchpad_bug(bug_id)
|
||||||
|
if data:
|
||||||
|
if data['package'] != '':
|
||||||
|
package = ' in ' + '[' + data['package'] + '](' + data['target_link'] + ')'
|
||||||
|
msg = f"Launchpad Bug [#{data['id']}]({data['link']}){package} \"{data['title']}\" [{data['importance']}, {data['status']}]"
|
||||||
|
await evt.respond(msg)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
@command.passive("^!(.+)$")
|
@command.passive("^!(.+)$")
|
||||||
async def command(self, evt: MessageEvent, match: Tuple[str]) -> None:
|
async def command_e(self, evt: MessageEvent, match: Tuple[str]) -> None:
|
||||||
# allow all rooms and users, only enable flood protection
|
# allow all rooms and users, only enable flood protection
|
||||||
#if self.check_access(evt.sender, evt.room_id):
|
#if self.check_access(evt.sender, evt.room_id):
|
||||||
if self.flood_protection.flood_check(evt.sender):
|
if self.flood_protection.flood_check(evt.sender):
|
||||||
|
@ -121,7 +124,6 @@ class Ubottu(Plugin):
|
||||||
if command_name == 'tr':
|
if command_name == 'tr':
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
#reload stuff
|
#reload stuff
|
||||||
if command_name == 'reload' and self.check_access_sender(evt.sender):
|
if command_name == 'reload' and self.check_access_sender(evt.sender):
|
||||||
if self.pre_start():
|
if self.pre_start():
|
||||||
|
@ -142,6 +144,19 @@ class Ubottu(Plugin):
|
||||||
if data:
|
if data:
|
||||||
await evt.respond('The current time in ' + data['location'] + ' is ' + data['local_time'])
|
await evt.respond('The current time in ' + data['location'] + ' is ' + data['local_time'])
|
||||||
|
|
||||||
|
if command_name == 'bug':
|
||||||
|
if len(args) == 1:
|
||||||
|
package = ''
|
||||||
|
bug_id = int(args[0])
|
||||||
|
data = await self.lookup_launchpad_bug(bug_id)
|
||||||
|
if data:
|
||||||
|
if data['package'] != '':
|
||||||
|
package = ' in ' + '[' + data['package'] + '](' + data['target_link'] + ')'
|
||||||
|
msg = f"Launchpad Bug [#{data['id']}]({data['link']}){package} \"{data['title']}\" [{data['importance']}, {data['status']}]"
|
||||||
|
await evt.respond(msg)
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
#!package lookup command
|
#!package lookup command
|
||||||
if command_name == 'package' or command_name == 'depends':
|
if command_name == 'package' or command_name == 'depends':
|
||||||
apt = Apt()
|
apt = Apt()
|
||||||
|
|
|
@ -4,8 +4,11 @@ from time import time
|
||||||
class FloodProtection:
|
class FloodProtection:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.user_commands = defaultdict(list) # Stores timestamps of commands for each user
|
self.user_commands = defaultdict(list) # Stores timestamps of commands for each user
|
||||||
|
self.bug_ids = defaultdict(list) # Stores timestamps of commands for each user
|
||||||
self.max_commands = 3
|
self.max_commands = 3
|
||||||
self.time_window = 60 # 60 seconds
|
self.time_window = 60 # 60 seconds
|
||||||
|
self.time_window_bug = 180 # 3 minutes
|
||||||
|
self.max_commands_bugs = 1
|
||||||
|
|
||||||
def flood_check(self, user_id):
|
def flood_check(self, user_id):
|
||||||
"""Check if a user can send a command based on flood protection limits."""
|
"""Check if a user can send a command based on flood protection limits."""
|
||||||
|
@ -23,3 +26,19 @@ class FloodProtection:
|
||||||
|
|
||||||
# Otherwise, do not allow the command
|
# Otherwise, do not allow the command
|
||||||
return False
|
return False
|
||||||
|
def flood_check_bug(self, bug_id):
|
||||||
|
"""Check if a user can send a command based on flood protection limits."""
|
||||||
|
current_time = time()
|
||||||
|
if bug_id not in self.bug_ids:
|
||||||
|
self.bug_ids[bug_id] = [current_time]
|
||||||
|
return True
|
||||||
|
|
||||||
|
# Remove bugs outside the time window
|
||||||
|
self.bug_ids[bug_id] = [timestamp for timestamp in self.bug_ids[bug_id] if current_time - timestamp < self.time_window_bug]
|
||||||
|
|
||||||
|
if len(self.bug_ids[bug_id]) < self.max_commands_bugs:
|
||||||
|
self.bug_ids[bug_id].append(current_time)
|
||||||
|
return True # Allow the bug if under the limit
|
||||||
|
|
||||||
|
# Otherwise, do not allow the bug
|
||||||
|
return False
|
Loading…
Reference in a new issue