Event calendar plugin app for Alliance Auth
Project description
Operation Calendar
An operation calendar app for Alliance Auth to display fleet operations and other events.
Includes
- Calendar type view of different events
- Manual events
- User created
- Detailed view
- Ical feed for exporting events
- Public NPSI events
- Automatic syncing with supported NPSI community events over APIs
- Ingame events
- Automatic syncing with ingame events
- Personal, Corporation and Alliance calendars
- Supports structure timers
- Supports aa-moonmining
- Self-hosted Discord bot to fetch events and sign up over Discord
- Event visibility options
- Custom names and colors
- Restrict to groups
- Restrict to states
- Webhook for sending event notifications
- Filter to include in ical feed
- Event categories
- Custom names
- Custom tickers
- Custom colors
- Optional FontAwesome icons and fallback color dots on the calendar
- Pre-fill text to add on events with the category
- Multihost support
- Discord notifications
- Webhook
- For: new, edited and deleted events
- Configurable ping timing (now / 1h / 1d / 1w before / custom)
- "Important" events with a blinking indicator on the calendar (and a 🔴 marker in Discord)
- Discord event channel bot
- Posts and keeps a pinned summary embed of upcoming events (including ingame events) in sync in a Discord channel
/signup <number> [attending|maybe|declined]slash command to sign up for events directly from Discord
- Counter on menu for events that the user has not signed or rejected from
|
Dark theme |
Light theme |
|
Details for manual events |
Event list command |
|
Event treacker in discord channel |
Requirements
- Alliance Auth 4.x or 5.x
- Python >= 3.10
- django-esi >= 8.0.0
py-cord>=2.0,<3.0(only needed if you use the Discord event channel bot)
Installation
Standard (venv / supervisor)
- Install the package:
pip install aa-opcalendar
- Add
'opcalendar'to yourINSTALLED_APPSin your project'slocal.py - Run migrations:
python manage.py migrate
- Collect static files:
python manage.py collectstatic
- Restart supervisor:
supervisorctl restart myauth:
- Set up permissions
Optional: Importing NPSI fleets
Opcalendar can automatically import predetermined NPSI fleets directly into your calendar from public NPSI community APIs. This is entirely optional — skip this if you don't need it.
- Go to the admin panel and select NPSI Event Imports.
- Create a host for each import and fill in the needed details for it.
- Add a new import by pressing the add event import button, then select the source, operation type and operation visibility for each fetched fleet.
- Add the following to your
local.py(or set up a periodic task foropcalendar.tasks.import_all_npsi_fleetsin the admin menu) to run imports hourly:CELERYBEAT_SCHEDULE['import_all_npsi_fleets'] = { 'task': 'opcalendar.tasks.import_all_npsi_fleets', 'schedule': crontab(minute=0, hour='*'), }
- Restart supervisor for the schedule change to take effect:
supervisorctl restart myauth:
See Importing NPSI fleets for the list of supported NPSI communities.
Optional: Importing fleets from ingame calendar
Opcalendar can pull fleets directly from in-game (ESI) personal, corporation and alliance calendars. This is entirely optional — skip this if you don't need it.
- Give the
add_ingame_calendar_ownerpermission to the wanted groups (see Permissions). - Navigate to the opcalendar page and press the
Add Ingame Calendar Feedbutton, then log in with the character that holds the calendar you want to import. - Add the following to your
local.py(or set up a periodic task foropcalendar.tasks.update_all_ingame_eventsin the admin menu) to pull fleets from ingame every 5 minutes:CELERYBEAT_SCHEDULE['update_all_ingame_events'] = { 'task': 'opcalendar.tasks.update_all_ingame_events', 'schedule': crontab(minute='*/5'), }
- Restart supervisor for the schedule change to take effect:
supervisorctl restart myauth:
See Importing fleets from ingame calendar for how imported events are displayed and how to assign a visibility filter and category to them.
Optional: Ical feed
Opcalendar can generate a standard ical-formatted feed of events for export into personal calendar apps. This is entirely optional — skip this if you don't need it.
- Open the relevant event visibility filter/category in the admin and check the box to include it in the ical feed. Only categories tagged with this box will show up on the feed.
- Add
'opcalendar'toAPPS_WITH_PUBLIC_VIEWSin yourlocal.py(create the setting if it doesn't exist):APPS_WITH_PUBLIC_VIEWS = [ 'opcalendar', ]
- Restart supervisor:
supervisorctl restart myauth:
- The feed is now available at
auth.example.com/opcalendar/feed.ics
Optional: Discord event channel bot
Opcalendar can run a self-hosted Discord bot that posts and keeps a single
pinned summary embed of upcoming events in sync inside a Discord channel,
and lets members sign up via a /signup slash command. This is entirely
optional — skip this if you don't need it.
- Create a Discord application and bot user in the Discord Developer Portal and invite it to your server with permission to read/send messages, manage messages (for pinning) and use slash commands.
- Add the bot token to your
local.py:OPCALENDAR_DISCORD_BOT_TOKEN = "your-bot-token-here"
- The bot needs to run as its own long-running process. Add a program
block for it to your supervisor config (e.g.
/etc/supervisor/conf.d/myauth.conf), adjusting the paths to match your install:[program:opcalendar_event_channel_bot] command=/home/allianceserver/venv/auth/bin/python /home/allianceserver/myauth/manage.py run_event_channel_bot directory=/home/allianceserver/myauth user=allianceserver numprocs=1 autostart=true autorestart=true stopasgroup=true killasgroup=true stderr_logfile=/home/allianceserver/myauth/log/opcalendar_event_channel_bot.err.log stdout_logfile=/home/allianceserver/myauth/log/opcalendar_event_channel_bot.out.log
The Discord ping timing feature (1 hour/1 day/1 week before fleet, or a custom date and time) requires a periodic task to actually send those reminders. The "Now" ping does not need this, since it's sent immediately when the event is created.
Add the following to your local.py (or set up a periodic task for opcalendar.tasks.send_scheduled_event_notifications in the admin menu) so due reminders are checked and sent every 5 minutes:
CELERYBEAT_SCHEDULE['send_scheduled_event_notifications'] = {
'task': 'opcalendar.tasks.send_scheduled_event_notifications',
'schedule': crontab(minute='*/5'),
}
[!IMPORTANT] Without this task scheduled, only the "Now" ping will be sent — the 1 hour/1 day/1 week and custom-time reminders will silently never fire.
supervisorctl reread
supervisorctl update
supervisorctl restart opcalendar_event_channel_bot
- Go to the admin panel and create an Event Channel, selecting the Discord channel ID and the visibility filter whose events should be listed in the summary.
Docker
- Add the package to your
conf/requirements.txt:aa-opcalendar==<latest stable version> - Add
'opcalendar'toINSTALLED_APPSin yourconf/local.py - Rebuild and restart the AllianceAuth containers:
docker compose build --no-cache docker compose up -d
- Run migrations and collect static files:
docker compose exec allianceauth_gunicorn python3 manage.py migrate docker compose exec allianceauth_gunicorn python3 manage.py collectstatic --noinput
- Set up permissions
Optional: Importing NPSI fleets
Opcalendar can automatically import predetermined NPSI fleets directly into your calendar from public NPSI community APIs. This is entirely optional — skip this if you don't need it.
- Go to the admin panel and select NPSI Event Imports.
- Create a host for each import and fill in the needed details for it.
- Add a new import by pressing the add event import button, then select the source, operation type and operation visibility for each fetched fleet.
- Add the following to your
conf/local.py(or set up a periodic task foropcalendar.tasks.import_all_npsi_fleetsin the admin menu) to run imports hourly:CELERYBEAT_SCHEDULE['import_all_npsi_fleets'] = { 'task': 'opcalendar.tasks.import_all_npsi_fleets', 'schedule': crontab(minute=0, hour='*'), }
- Restart the containers for the schedule change to take effect:
docker compose restart allianceauth_gunicorn allianceauth_worker allianceauth_beat
See Importing NPSI fleets for the list of supported NPSI communities.
Optional: Importing fleets from ingame calendar
Opcalendar can pull fleets directly from in-game (ESI) personal, corporation and alliance calendars. This is entirely optional — skip this if you don't need it.
- Give the
add_ingame_calendar_ownerpermission to the wanted groups (see Permissions). - Navigate to the opcalendar page and press the
Add Ingame Calendar Feedbutton, then log in with the character that holds the calendar you want to import. - Add the following to your
conf/local.py(or set up a periodic task foropcalendar.tasks.update_all_ingame_eventsin the admin menu) to pull fleets from ingame every 5 minutes:CELERYBEAT_SCHEDULE['update_all_ingame_events'] = { 'task': 'opcalendar.tasks.update_all_ingame_events', 'schedule': crontab(minute='*/5'), }
- Restart the containers for the schedule change to take effect:
docker compose restart allianceauth_gunicorn allianceauth_worker allianceauth_beat
See Importing fleets from ingame calendar for how imported events are displayed and how to assign a visibility filter and category to them.
Optional: Ical feed
Opcalendar can generate a standard ical-formatted feed of events for export into personal calendar apps. This is entirely optional — skip this if you don't need it.
- Open the relevant event visibility filter/category in the admin and check the box to include it in the ical feed. Only categories tagged with this box will show up on the feed.
- Add
'opcalendar'toAPPS_WITH_PUBLIC_VIEWSin yourconf/local.py(create the setting if it doesn't exist):APPS_WITH_PUBLIC_VIEWS = [ 'opcalendar', ]
- Restart the containers:
docker compose restart allianceauth_gunicorn allianceauth_worker allianceauth_beat
- The feed is now available at
auth.example.com/opcalendar/feed.ics
Optional: Discord event channel bot
Opcalendar can run a self-hosted Discord bot that posts and keeps a single
pinned summary embed of upcoming events in sync inside a Discord channel,
and lets members sign up via a /signup slash command. This is entirely
optional — skip this if you don't need it.
- Create a Discord application and bot user in the Discord Developer Portal and invite it to your server with permission to read/send messages, manage messages (for pinning) and use slash commands.
- Add the bot token to your
conf/local.py:OPCALENDAR_DISCORD_BOT_TOKEN=your-bot-token-here - Add a new service to your
docker-compose.yml, reusing thex-allianceauth-baseanchor shared byallianceauth_gunicorn/allianceauth_beat/allianceauth_workerso it inherits the same image,env_file, volumes,depends_on, working directory and logging:allianceauth_opcalendar_bot: container_name: allianceauth_opcalendar_bot <<: [*allianceauth-base] entrypoint: ["python3", "manage.py", "run_event_channel_bot"]
The Discord ping timing feature (1 hour/1 day/1 week before fleet, or a custom date and time) requires a periodic task to actually send those reminders. The "Now" ping does not need this, since it's sent immediately when the event is created.
Add the following to your local.py (or set up a periodic task for opcalendar.tasks.send_scheduled_event_notifications in the admin menu) so due reminders are checked and sent every 5 minutes:
CELERYBEAT_SCHEDULE['send_scheduled_event_notifications'] = {
'task': 'opcalendar.tasks.send_scheduled_event_notifications',
'schedule': crontab(minute='*/5'),
}
[!IMPORTANT] Without this task scheduled, only the "Now" ping will be sent — the 1 hour/1 day/1 week and custom-time reminders will silently never fire.
docker compose up -d allianceauth_opcalendar_bot
docker compose logs -f allianceauth_opcalendar_bot
[!NOTE] If
OPCALENDAR_DISCORD_BOT_TOKENis unset/blank, this container will start and immediately exit — the bot management command no-ops when the feature is disabled. Set the token first, or don't add this service until you're ready to use the Discord sign-up feature.
- Go to the admin panel and create an Event Channel, selecting the Discord channel ID and the visibility filter whose events should be listed in the summary.
Permissions
| Perm | Auth Site | Example Target Group |
|---|---|---|
| opcalendar basic_access | Can access this app and see operations based on visibility rules | Everyone |
| opcalendar create_event | Can create new events and edit/delete their own events | Members, FCs |
| opcalendar manage_event | Can edit and delete their own events | Members, FCs |
| opcalendar manage_all_events | Can edit and delete all events, including events created by other users | Leadership, FCs |
| opcalendar see_signups | Can see all signups for event | Leadership, FCs, Members |
| opcalendar add_ingame_calendar_owner | Can add ingame calendar feeds for their corporation | Leadership, FCs |
Settings
| Name | Description | Default |
|---|---|---|
| OPCALENDAR_NOTIFY_IMPORTS | Whether to send out discord notifications for ingame and public NPSI events | True |
| OPCALENDAR_DISPLAY_STRUCTURETIMERS | Whether we should include timers from the structuretimers plugin in the calendar. Inherits view permissions from aa-structuretimers | True |
| OPCALENDAR_DISPLAY_MOONMINING | Whether we should include extractions from the aa-moonmining plugin in the calendar. Inherits view permissions from aa-moonmining | True |
| OPCALENDAR_DISCORD_OPS_DISPLAY_EXTERNAL | Whether we display external hosts such as ingame hosts in the discord ops command filters | False |
| OPCALENDAR_DISPLAY_MOONMINING_TAGS | Display the rarity tag of aa-moonmining moons if the moonmining plugin is installed | True |
| OPCALENDAR_DISPLAY_MOONMINING_ARRIVAL_TIME | Displays aa-moonmining extraction time based on arrival time. Set to False to display as auto fracture time | True |
| OPCALENDAR_NOTIFY_REPEAT_EVENTS | If repeated events should also be created as webhook pings on discord. Can create spam if the event repeat is set to high | True |
| OPCALENDAR_SHOW_EVENT_COUNTER | Shows a counter next to the opcalendar menu for events that the user has not responded to | True |
| OPCALENDAR_TASKS_TIME_LIMIT | Hard timeout for opcalendar's periodic tasks in seconds, to reduce task accumulation during outages | 7200 |
| OPCALENDAR_DISCORD_BOT_TOKEN | Bot token for the self-hosted Discord event channel bot. Leave blank to disable the feature entirely | "" (empty) |
Setup
Before you are able to create new events on the front end you will need to set up the needed hosts, categories and visibility filters for your events. All of the following are configured from the Django admin site.
1. Host
Hosts are for identifying reasons. If you run a single corporation or alliance entity you most likely only want one host. If you want to extend the calendar with other hosts such as NPSI communities you can create a host for each different entity.
- Host name is shown on the event and on discord notifications
- You can customize host logos
- Go to the admin site
2. Visibility filter
These filters will determine who is able to see the events that are labeled with each different visibility filter.
- Can be restricted to groups and states
- If no groups or states are selected the events will be visible for everyone
- You can determine a custom color tag that will be shown on the top right corner of the event
- Each visibility filter will be displayed on the calendar and can be used for filtering events on the calendar
- Discord notification webhooks can be assigned for each visibility filter. Events created, deleted or edited under this filter will then be sent over to discord.
3. Categories
Categories are displayed as a ticker in front of manually created events. Most common categories are: PvP, Stratop, Mining, CTA etc.
- Ticker displayed on event
- Custom colors
- Optional FontAwesome icon (e.g.
fas fa-rocket), tinted with the category's color, shown in the calendar's left gutter. If no icon is set but a color is, a small colored dot is shown instead. Both blink for events marked "Important".
4. Discord webhook
If you want to receive notifications about your events (created/modified/deleted) on your discord you can add a webhook for the channel in discord you want to receive the notifications to. The webhooks you create will be used in the visibility filters.
Adding manual events
To add a manual event simply go to the calendar page and press on the new event button. Fill in and select the needed information.
You can mark an event as Important to show a blinking red indicator on the calendar (and on its category icon/dot, if any) so members notice it at a glance. Ingame (ESI) calendar events that EVE itself flags as important get this automatically.
Discord ping timing
When creating or editing an event you can choose when the Discord ping for it should be sent out. This is a multi select field, so you can pick multiple timings for the same event:
- Now - sends the ping as soon as the event is created
- 1 hour before fleet - sends a reminder ping 1 hour before the event start time
- 1 day before fleet - sends a reminder ping 1 day before the event start time
- 1 week before fleet - sends a reminder ping 1 week before the event start time
- Custom date and time - sends a reminder ping at a specific date and time you set yourself
The "Now" ping is sent out instantly when the event is created. All other timings ("1 hour/day/week before fleet" and "Custom date and time") are picked up by a periodic task that checks for due notifications and sends them out.
Sending a "starting now" ping
On the event details page, the owner of an event (the user who created it) will see a Send starting now ping button. This lets you instantly notify your Discord channel that the fleet is starting, regardless of which scheduled ping timings were selected when the event was created. Next to the button you can choose who the ping should mention:
- @here - notifies only the members who are currently online in the Discord server
- @everyone - notifies all members of the Discord server
The notification is sent through the same webhook configured on the event's visibility filter, so it respects that filter's enabled/ignore-past-fleets settings.
Importing NPSI fleets
Opcalendar has the ability to import predetermined NPSI fleets directly into your calendar from public NPSI community APIs.
This feature is optional and set up as part of the installation steps (see "Optional: Importing NPSI fleets" under either the Standard or Docker installation method).
[!NOTE] Don't forget to also set up the
send_scheduled_event_notificationsperiodic task described in Setup — Periodic task for scheduled Discord pings — it's required for the Discord ping timing feature and is unrelated to NPSI imports.
Supported NPSI communities
Opcalendar is currently supporting imports for the following NPSI fleets:
- EVE LinkNet
- Spectre Fleet
- EVE University (classes)
- Fun Inc.
- FRIDAY YARRRR
- Redemption Road
- CAS
- Fwaming Dwagons
- FREE RANGE CHIKUNS
Importing fleets from ingame calendar
You can import events that have been created in the ingame calendar. As the fields on the ingame calendar are limited the events will not be as detailed as when created directly from the calendar.
This feature is optional and set up as part of the installation steps (see "Optional: Importing fleets from ingame calendar" under either the Standard or Docker installation method).
Ingame event visibility and categories
By default, the ingame events you import have no visibility filter and no category. This means they will be visible for everyone.
If you wish to add a visibility filter or a category similar to the manual events, go to admin panel → Ingame event owners and select a filter and a category for the owner.
After selecting a visibility filter and a category, the ingame events will behave similarly to manual events and respect the group and state restrictions set for the visibility filters. Ingame events EVE itself flags as important will also show the "Important" blinking indicator automatically.
Discord event channel bot
Opcalendar can run a self-hosted Discord bot that posts and keeps a single pinned summary embed of upcoming events (both manually created events and ingame ESI events) in sync inside a Discord channel, and lets members sign up for events directly from Discord using a slash command.
This feature is optional and set up as part of the installation steps (see "Optional: Discord event channel bot" under either the Standard or Docker installation method).
Signing up from Discord
Members can sign up for an event listed in the pinned summary using the /signup <number> [attending|maybe|declined] slash command from within the event channel, where <number> is the position of the event as listed in the pinned summary.
Contributing
Make sure you have signed the License Agreement by logging in at https://developers.eveonline.com before submitting any pull requests. All bug fixes or features must not include extra superfluous formatting changes.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file aa_opcalendar-4.0.0b1.tar.gz.
File metadata
- Download URL: aa_opcalendar-4.0.0b1.tar.gz
- Upload date:
- Size: 166.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5b546f020f2f37d14210e5ffdf824a8b2f71f56f1ddfc6a3b16b28a4028d36c2
|
|
| MD5 |
f67cc2ce5c9cd7d266a86a583e8931f2
|
|
| BLAKE2b-256 |
8dd9586628db7f3734d223e42b2f22c8e92cd1a60ffff1c7136f1ed44f8b9e88
|
File details
Details for the file aa_opcalendar-4.0.0b1-py3-none-any.whl.
File metadata
- Download URL: aa_opcalendar-4.0.0b1-py3-none-any.whl
- Upload date:
- Size: 206.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
42703a03bf2ea843937353a4ad6ef734d700ba5082d2d0d539263ad43379c44b
|
|
| MD5 |
1fc08bd15be8477da9277b8812e47ac9
|
|
| BLAKE2b-256 |
74815135272ba4efd4fc80b66f099550e66daf62dceaf62f56a7af26f7ea30a4
|