Rough Campaign module skeleton.

This commit is contained in:
2026-07-22 18:42:08 +03:00
parent b8ffacd916
commit 67a04ef82f
10 changed files with 237 additions and 50 deletions
+124
View File
@@ -0,0 +1,124 @@
from typing import Optional, TypeAlias, TypedDict
import json
from collections import defaultdict
from datetime import datetime, timedelta
from dataclasses import dataclass
from data.queries import JOINTYPE, ORDER
from meta.sockets import Channel
from utils.lib import utc_now
from modules.profiles.profiles.profiles import ProfilesRegistry
from . import logger
from .data import (
Campaign,
CampaignData,
EarnedReward,
)
from .campaign import CampaignRegistry
# ISO formatted timestamp
ISOTimestamp: TypeAlias = str
async def prepare_campaign(
profiler: ProfilesRegistry, campaign: Campaign
):
return {}
class CampaignChannel(Channel):
name = "PlusCampaign"
def __init__(
self, profiler: ProfilesRegistry, campaigns: CampaignRegistry, **kwargs
):
super().__init__(**kwargs)
self.profiler: ProfilesRegistry = profiler
self.campaigns: CampaignRegistry = campaigns
# Map of communities to webhooks listening for this community
self.communities = defaultdict(
set
) # Map of communityid -> listening websockets
async def on_connection(self, websocket, event):
if not (cidstr := event.get("community")):
logger.warning("Campaign connection missing communityid")
await super().on_connection(websocket, event)
await self.send_sample(websocket=websocket)
return
elif not cidstr.isdigit():
raise ValueError("Community id provided is not an integer")
cid = int(cidstr)
community = await self.profiler.get_community(cid)
if community is None:
raise ValueError("Unknown community provided.")
await super().on_connection(websocket, event)
self.communities[cid].add(websocket)
# TODO: Prepare campaign for sending
if campaign:
payload = await prepare_campaign(self.profiler, campaign)
await self.send_campaign_update(cid, payload, websocket)
else:
await self.send_no_campaign(cid, websocket)
async def send_sample(self, websocket):
import json
import random
with open("sample-payload.json") as f:
payload = json.load(f)
ending = utc_now() + timedelta(seconds=10)
payload['args']['end_at'] = ending.isoformat()
await self.send_event(payload, websocket=websocket)
async def del_connection(self, websocket):
for wss in self.communities.values():
wss.discard(websocket)
await super().del_connection(websocket)
async def send_campaign_update(
self, communityid: int, payload, websocket=None
):
for ws in (websocket,) if websocket else self.communities[communityid]:
await self.send_event(
{
"type": "DO",
"method": "setTimer",
"args": payload,
},
websocket=ws,
)
async def send_campaign_ended(
self, communityid: int, payload, websocket=None
):
for ws in (websocket,) if websocket else self.communities[communityid]:
await self.send_event(
{
"type": "DO",
"method": "endTimer",
"args": payload,
},
websocket=ws,
)
async def send_no_campaign(self, communityid: int, websocket=None):
for ws in (websocket,) if websocket else self.communities[communityid]:
await self.send_event(
{
"type": "DO",
"method": "noTimer",
"args": {},
},
websocket=ws,
)
async def send_event(self, event, **kwargs):
logger.info(f"Sending websocket event: {json.dumps(event, indent=1)}")
await super().send_event(event, **kwargs)