Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Screens #56

Merged
merged 60 commits into from
Jan 4, 2024
Merged
Show file tree
Hide file tree
Changes from 52 commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
0b9dfa5
Add aaron
KenwoodFox Aug 17, 2023
f44830d
Move admin_bot structure
KenwoodFox Aug 17, 2023
d503109
Boilerplate admin_interface
KenwoodFox Aug 17, 2023
11b8e88
Fix build name
KenwoodFox Aug 17, 2023
dd322ad
Try registry cleaner
KenwoodFox Aug 17, 2023
38dde0f
order cleaner
KenwoodFox Aug 17, 2023
96cea1a
Add more stuff
KenwoodFox Aug 17, 2023
ae2ae16
Try cleaner
KenwoodFox Aug 17, 2023
3eefe00
add js stuff
KenwoodFox Aug 20, 2023
5aa017a
enable recurse
KenwoodFox Aug 20, 2023
2cad87b
Change teams
KenwoodFox Aug 20, 2023
da600d7
bumpp
KenwoodFox Aug 20, 2023
efa1f8e
bump
KenwoodFox Aug 20, 2023
85ba1fc
bump
KenwoodFox Aug 20, 2023
0055d93
Also clean interface
KenwoodFox Aug 20, 2023
625c7e6
fix interface
KenwoodFox Aug 20, 2023
c73d81b
Bump makefile
KenwoodFox Aug 21, 2023
2289308
Add more pictures of aaron
KenwoodFox Aug 21, 2023
c5e6c6e
Make everything more approchable
KenwoodFox Aug 21, 2023
23a7e59
MARGIN 0!!!! PADDING 0!!!
dublUayaychtee Aug 21, 2023
7bf05c6
Auto reload on server changes
KenwoodFox Aug 22, 2023
415fce9
rehaul styles: remove table on countdown, make table for discord, cha…
dublUayaychtee Aug 22, 2023
4551033
Add live discord updates, add live aaron updates
KenwoodFox Aug 23, 2023
4887fb8
add next meeting
KenwoodFox Aug 23, 2023
93a5d17
add bg pattern
dublUayaychtee Aug 23, 2023
b7f54d9
replace with jQuery
dublUayaychtee Aug 23, 2023
4508582
fix my jQuery
dublUayaychtee Aug 23, 2023
9641e02
update compose format
KenwoodFox Aug 23, 2023
24cc4a1
Add reqs for websockets
KenwoodFox Aug 23, 2023
5a62607
working alchemy demo
KenwoodFox Aug 23, 2023
ca7dd11
Modify compose
KenwoodFox Aug 23, 2023
c88d224
Add shared link for discord messages
KenwoodFox Aug 23, 2023
736f62b
Use webhooks!
KenwoodFox Aug 24, 2023
6e992a7
autoscroll discord + more jquery
dublUayaychtee Aug 24, 2023
121b93e
Add in versioning and time formatting
KenwoodFox Aug 24, 2023
737ec22
Allow discord bot to submit promo images
KenwoodFox Aug 24, 2023
0ae3715
add better expiry handling
KenwoodFox Aug 24, 2023
ebcbf08
Add in automatic grabbing of promo image
KenwoodFox Aug 24, 2023
e5d94ed
Require interface commands have Leads or mentor roles
KenwoodFox Aug 24, 2023
3e8dfea
Bump
KenwoodFox Sep 12, 2023
d4224df
Build new
KenwoodFox Sep 12, 2023
26fa142
misc fixups
KenwoodFox Sep 12, 2023
fbef420
Fix text
dublUayaychtee Sep 12, 2023
8021625
Patch glitch
KenwoodFox Sep 12, 2023
5100251
Truncate name limit to 15
KenwoodFox Sep 13, 2023
7b66784
Add more verbose
KenwoodFox Sep 13, 2023
19486d2
Fix next meeting
KenwoodFox Sep 14, 2023
0b4804d
Fix a bug where bot could suggest a negative meeting schedule
KenwoodFox Sep 14, 2023
fb150a1
Clean up compose
KenwoodFox Sep 16, 2023
1e8399e
Captions
KenwoodFox Sep 16, 2023
45e9160
fix caption's positioning, hide captions when empty
dublUayaychtee Sep 16, 2023
d8351e6
making the channels more restrictive
Sep 28, 2023
abaa525
Update admin_bot/admin_bot/cogs/interface.py
KenwoodFox Sep 28, 2023
409a73b
Add profanity filter
KenwoodFox Sep 29, 2023
d1fc25e
Misc fixups
KenwoodFox Oct 24, 2023
73abcb5
Fix bug with items not expiring on time
KenwoodFox Oct 26, 2023
4f35454
Catch exceptions when updating cal
KenwoodFox Oct 31, 2023
a522bcc
Limit ONLY to announcements
KenwoodFox Oct 31, 2023
048a25e
Add more aaron
KenwoodFox Nov 6, 2023
6059e2f
add picture of aaron
KenwoodFox Nov 15, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 34 additions & 6 deletions .github/workflows/admin_bot-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,19 @@ jobs:
# args: "AdminBot Pytest failed!"

build-and-publish-image:
name: Build and Publish Registry Image
name: Build Registry
runs-on: ubuntu-latest
needs: [formatblack] # Keeps the bot from updating the image if its not tested/formatted

permissions:
contents: read
packages: write

strategy:
matrix:
package:
- admin_bot
- admin_interface

steps:
- name: Checkout repository
uses: actions/checkout@v2
Expand All @@ -88,7 +93,7 @@ jobs:
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

- name: Extract Version information for admin_bot
- name: Extract Version information for ${{ matrix.package }}
id: extract_hash
run: |
echo BUILD_HASH=$(git describe --abbrev=8 --always --tags --dirty) >> $GITHUB_ENV
Expand All @@ -101,12 +106,12 @@ jobs:
run: |
echo "${{ steps.branch-name.outputs.current_branch }}"
echo "${{ steps.meta.outputs.tags }}"
echo "CUSTOM_TAG=ghcr.io/frc-1721/adminbot:$(echo "${{ steps.branch-name.outputs.current_branch }}" | sed 's/[^a-zA-Z0-9]/-/g; s/[A-Z]/\L&/g')" >> $GITHUB_ENV
echo "CUSTOM_TAG=ghcr.io/frc-1721/$(echo ${{ matrix.package }} | sed 's/[A-Z_]\|L&//'):$(echo "${{ steps.branch-name.outputs.current_branch }}" | sed 's/[^a-zA-Z0-9]/-/g; s/[A-Z]/\L&/g')" >> $GITHUB_ENV

- name: Build and push Docker image
uses: docker/build-push-action@v2
with:
context: .
context: ${{ matrix.package }}/
push: true
build-args: |
GIT_COMMIT=${{ env.BUILD_HASH }}
Expand All @@ -119,4 +124,27 @@ jobs:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
uses: Ilshidur/action-discord@master
with:
args: "Built and published a new Adman Bot docker image to `${{ env.CUSTOM_TAG }}`!"
args: "Built and published a new `${{ matrix.package }}` docker image to `${{ env.CUSTOM_TAG }}`!"

gcr-cleaner:
runs-on: "ubuntu-latest"
needs: [build-and-publish-image]

steps:
- name: Clean adminbot
id: clean_adminbot
uses: actions/delete-package-versions@v4
with:
package-name: "adminbot"
package-type: "container"
min-versions-to-keep: 2
delete-only-untagged-versions: "true"

- name: Clean admininterface
id: clean_admininterface
uses: actions/delete-package-versions@v4
with:
package-name: "admininterface"
package-type: "container"
min-versions-to-keep: 2
delete-only-untagged-versions: "true"
97 changes: 32 additions & 65 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,75 +1,42 @@
.PHONY: help clean clean-pyc clean-build list test coverage release

# Help
help:
@echo " clean-build - Remove build artifacts"
@echo " clean-pyc - Remove Python file artifacts"
@echo " lint - Check style with flake8"
@echo " test - Run tests quickly with the default Python"
@echo " install-requirements - install the requirements for development"
@echo " build Builds the docker images for the docker-compose setup"
@echo " docker-rm Stops and removes all docker containers"
@echo " run Run a command. Can run scripts, e.g. make run COMMAND=\"./scripts/schema_generator.sh\""
@echo " shell Opens a Bash shell"
@echo " prod Is meant for running on the production env"

# Clean everything
clean: clean-build clean-pyc docker-rm

# Clean build data
clean-build:
rm -fr build/
rm -fr dist/
rm -fr *.egg-info

# Clean python cache
clean-pyc:
find . -name '*.pyc' -exec rm -f {} +
find . -name '*.pyo' -exec rm -f {} +
find . -name '*~' -exec rm -f {} +

# Delint the code
lint:
flake8 .

# Run the tests
test: build
docker-compose run admin_bot test

# Install requirements (locally)
install-requirements:
pip install -r requirements/requirements.txt
pip install -r requirements/test_requirements.txt

# Build container locally
build:
# Shortcut makefile list

help: ## Show this help.
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'


test: build ## Currently broken, requires build
docker compose run admin_bot test


configure-pipenv: ## sets up pipenv for you
pipenv install -r admin_bot/requirements/requirements.txt
pipenv install -r admin_interface/requirements/requirements.txt
pipenv shell


build: ## Build containers locally
# Generate tag
echo TAG=$(shell git rev-parse --abbrev-ref HEAD | sed 's/[^a-zA-Z0-9]/-/g') > .env

# Build
docker-compose build --build-arg GIT_COMMIT=$(shell git describe --abbrev=8 --always --tags --dirty) --build-arg DEBUG=True
docker compose build --build-arg GIT_COMMIT=$(shell git describe --abbrev=8 --always --tags --dirty) --build-arg DEBUG=True


docker-rm: stop ## Delete containers, requires stop
docker compose rm -f

# Delete container
docker-rm: stop
docker-compose rm -f

# Get container shell
shell:
docker-compose run --entrypoint "/bin/bash" admin_bot
shell: ## Get container shell
docker compose run --entrypoint "/bin/bash" admin_bot

# Run command in container
run: build
docker-compose run admin_bot $(COMMAND)

# Stop container
stop:
docker-compose down
docker-compose stop
run: build ## Run command in container, requires build
docker compose up

# "production"
prod:
docker-compose -f docker-compose-prod.yml up -d
stop: ## Stop containers
docker compose down
docker compose stop

# Development stuff
dev:
docker-compose -f docker-compose.yml build && docker-compose -f docker-compose.yml up
# Specific stuff
flask-local: ## Runs flask locally for you!
cd admin_interface/admin_interface && flask --app main.py run
File renamed without changes.
File renamed without changes.
10 changes: 10 additions & 0 deletions admin_bot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Adminbot

This is the discord bot component.

To get started developing here, you'll need a `BOT_TOKEN`, you can get this by
making your own discord bot here https://discord.com/developers/applications

It can be a bit tricky to setup a server and a bot for testing but its worth it.
Use `^sync` to manually sync any discord slash commands to your development server,
and submit a pr!
File renamed without changes.
File renamed without changes.
140 changes: 140 additions & 0 deletions admin_bot/admin_bot/cogs/interface.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
# Tidal Force robotics
# 2021, Admin Bot
# MIT License


import os
import time
import json
import pytz
import string
import random
import discord
import logging
import asyncio
import requests
import subprocess

from typing import Literal, Optional
from discord import app_commands
from discord.ext import commands, tasks
from ics import Calendar

from PIL import Image, ImageDraw, ImageFilter, UnidentifiedImageError

from utilities.common import seconds_until


# Minimal cog to provide an interface to the digital signage


class InterfaceCog(commands.Cog, name="Interface"):
def __init__(self, bot):
self.bot = bot

@app_commands.command(name="clear_promo")
@commands.has_any_role("Leads", "Adult Mentor", "Student Mentor")
async def clearPromo(self, ctx: discord.Interaction):
"""
Removes all promo materials in rotation
"""
msg = "Removing: "

dir = "/app/promo"
for f in os.listdir(dir):
msg += f"{f}, "
os.remove(os.path.join(dir, f))

await ctx.response.send_message(msg)

@app_commands.command(name="submit_promo")
@commands.has_any_role("Leads", "Adult Mentor", "Student Mentor")
async def submitPromo(
self, ctx: discord.Interaction, img: str, days: int, caption: str = None
):
"""
Submits a promotional image to be displayed in rotation.
"""

if days > 90:
await ctx.response.send_message(
"Sorry, thats too long for a submitted image to be in rotation. Contact <@&614313406345904148> to submit a permanent promo image."
)
else:
# This may take a moment
await ctx.response.defer()
try:
# Make a random string
_rand = "".join(
random.choices(string.ascii_lowercase + string.digits, k=7)
)
# Create a full filename
filename = f"/app/promo/{(ctx.user.nick).replace(' ', '_')}_{_rand}"

# Write metadata first
imgData = {
"expires": f"{int(time.time()) + (86400*days)}",
"author": f"Submitted by {ctx.user.nick}",
"caption": caption,
}

json_object = json.dumps(imgData, indent=4)
with open(f"{filename}.json", "w") as outfile:
outfile.write(json_object)

# Download the file
subprocess.run(["wget", img, "-O", f"{filename}.png"])

await ctx.followup.send(
f"Done! Added `{filename}`, expires in `{days}` days! Caption was `{caption}`.",
file=discord.File(f"{filename}.png"),
)
except Exception as e:
await ctx.followup.send(f"Sorry! There was an error! {e}")

@commands.Cog.listener()
async def on_message(self, ctx: discord.message.Message):
"""
Pushes messages into the postgresql database.
"""

# We dont want to publish EVERY channel, just some specific ones!
allowed_channels = [
590312336414212107, # mechanical-cad
1075174212723032064, # electrical
590312300695650305, # software
776835421976002570, # outreach-buisness
1024362276951703552, # media
KenwoodFox marked this conversation as resolved.
Show resolved Hide resolved
]

if (
not isinstance(ctx.channel, discord.channel.DMChannel)
and not ctx.author.bot
):
logging.info(
f"Sending message from {ctx.channel.id}, author was {ctx.author.name}, forwarding it!"
)

webhookUrl = "http://interface:8000/dashboard/hook"

dataToSend = {
"channel": ctx.channel.name,
"author": ctx.author.display_name,
"author_avatar": str(ctx.author.avatar.url),
"content": ctx.content,
"version": self.bot.version,
}

if ctx.channel.id in allowed_channels:
req = requests.post(
url=webhookUrl,
data=json.dumps(dataToSend),
headers={"Content-type": "application/json"},
)
logging.debug(f"Sent webhook to signage, req was {req}")
else:
logging.debug(f"Channel {ctx.channel.id} was not in allowed channels.")


async def setup(bot):
await bot.add_cog(InterfaceCog(bot))
File renamed without changes.
5 changes: 3 additions & 2 deletions admin_bot/cogs/tools.py → admin_bot/admin_bot/cogs/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,19 @@
# MIT License


import time
import json
import pytz
import discord
import logging
import asyncio
import psycopg
import requests
import random

from typing import Literal, Optional
from discord import app_commands
from discord.ext import commands, tasks
from datetime import datetime, timedelta, time
from datetime import datetime, timedelta
from ics import Calendar

from utilities.common import seconds_until
Expand Down
5 changes: 4 additions & 1 deletion admin_bot/main.py → admin_bot/admin_bot/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ def __init__(self):
format="%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s",
datefmt="%H:%M:%S",
level=os.environ.get("LOG_LEVEL", "INFO").upper(),
handlers=[logging.FileHandler("/tmp/adman.log"), logging.StreamHandler()],
handlers=[
logging.FileHandler("/tmp/admin_bot.log"),
logging.StreamHandler(),
],
)

# Append some extra information to our discord bot
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ requests
PyYAML
pillow
pytz==2022.7
ics==0.8.0.dev0
ics==0.8.0.dev0
File renamed without changes.
File renamed without changes.
Loading