generated from HoloTech/holotech-plugin-template
Rough Campaign module skeleton.
This commit is contained in:
@@ -1,15 +0,0 @@
|
||||
from typing import Optional
|
||||
from .data import (
|
||||
AwesomeData,
|
||||
AwesomeTable,
|
||||
)
|
||||
|
||||
|
||||
class AwesomeRegistry:
|
||||
VERSION = AwesomeData.VERSION
|
||||
|
||||
def __init__(self, data: AwesomeData):
|
||||
self.data = data
|
||||
|
||||
async def init(self):
|
||||
await self.data.init()
|
||||
@@ -0,0 +1,16 @@
|
||||
from typing import Optional
|
||||
from .data import (
|
||||
CampaignData,
|
||||
Campaign,
|
||||
EarnedReward,
|
||||
)
|
||||
|
||||
|
||||
class CampaignRegistry:
|
||||
VERSION = CampaignData.VERSION
|
||||
|
||||
def __init__(self, data: CampaignData):
|
||||
self.data = data
|
||||
|
||||
async def init(self):
|
||||
await self.data.init()
|
||||
@@ -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)
|
||||
+40
-8
@@ -2,16 +2,48 @@ from data import Registry, RowModel, Table
|
||||
from data.columns import String, Timestamp, Integer, Bool
|
||||
|
||||
|
||||
class AwesomeTable(RowModel):
|
||||
_tablename_ = "awesome_table"
|
||||
_cache_ = {}
|
||||
class Campaign(RowModel):
|
||||
_tablename_ = "campaigns"
|
||||
# _cache_ = {}
|
||||
|
||||
campaign_id = Integer(primary=True)
|
||||
communityid = Integer()
|
||||
target_rewards = Integer()
|
||||
campaign_name = String()
|
||||
started_at = Timestamp()
|
||||
completed_at = Timestamp()
|
||||
|
||||
created_at = Timestamp()
|
||||
_timestamp = Timestamp()
|
||||
|
||||
class EarnedReward(RowModel):
|
||||
_tablename_ = "campaign_rewards_earned"
|
||||
# _cache_ = {}
|
||||
|
||||
earned_id = Integer(primary=True)
|
||||
campaign_id = Integer()
|
||||
profileid = Integer()
|
||||
|
||||
event_id = Integer()
|
||||
twitch_user_id = String()
|
||||
twitch_user_name = String()
|
||||
|
||||
fulfilled_at = Timestamp()
|
||||
fulfilled_note = String()
|
||||
|
||||
earned_at = Timestamp()
|
||||
earned_from = String()
|
||||
modnote = String()
|
||||
|
||||
userid = String(primary=True)
|
||||
_timestamp = Timestamp()
|
||||
|
||||
|
||||
class AwesomeData(Registry):
|
||||
VERSION = ("AWESOME", 1)
|
||||
|
||||
AwesomeTable = AwesomeTable
|
||||
awesome_table = AwesomeTable.table
|
||||
class CampaignData(Registry):
|
||||
VERSION = ("CAMPAIGN", 1)
|
||||
|
||||
Campaign = Campaign
|
||||
campaigns = Campaign.table
|
||||
|
||||
EarnedReward = EarnedReward
|
||||
campaign_rewards_earned = EarnedReward.table
|
||||
|
||||
@@ -2,6 +2,6 @@ from .. import logger
|
||||
|
||||
|
||||
async def setup(bot):
|
||||
from .cog import AwesomeCog
|
||||
from .cog import CampaignCog
|
||||
|
||||
await bot.add_cog(AwesomeCog(bot))
|
||||
await bot.add_cog(CampaignCog(bot))
|
||||
|
||||
@@ -9,18 +9,18 @@ from meta import LionBot, LionCog, LionContext
|
||||
from meta.logger import log_wrap
|
||||
from utils.lib import utc_now
|
||||
|
||||
from ..data import AwesomeData
|
||||
from ..awesome import AwesomeRegistry
|
||||
from ..data import CampaignData
|
||||
from ..campaigns import CampaignRegistry
|
||||
|
||||
|
||||
class AwesomeCog(LionCog):
|
||||
class CampaignCog(LionCog):
|
||||
def __init__(self, bot: LionBot):
|
||||
self.bot = bot
|
||||
|
||||
self.data = bot.db.load_registry(AwesomeData())
|
||||
self.profiles = AwesomeRegistry(self.data)
|
||||
self.data = bot.db.load_registry(CampaignData())
|
||||
self.campaigns = CampaignRegistry(self.data)
|
||||
|
||||
async def cog_load(self):
|
||||
await self.data.init()
|
||||
await self.bot.version_check(*self.data.VERSION)
|
||||
await self.profiles.init()
|
||||
await self.campaigns.init()
|
||||
|
||||
@@ -6,6 +6,6 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
async def setup(bot: "Bot"):
|
||||
from .component import AwesomeComponent
|
||||
from .component import CampaignComponent
|
||||
|
||||
await bot.add_component(AwesomeComponent(bot))
|
||||
await bot.add_component(CampaignComponent(bot))
|
||||
|
||||
@@ -10,22 +10,22 @@ from utils.lib import utc_now
|
||||
|
||||
from . import logger
|
||||
|
||||
from ..data import AwesomeData
|
||||
from ..awesome import AwesomeRegistry
|
||||
from ..data import CampaignData
|
||||
from ..campaign import CampaignRegistry
|
||||
|
||||
|
||||
class AwesomeComponent(cmds.Component):
|
||||
class CampaignComponent(cmds.Component):
|
||||
def __init__(self, bot: Bot):
|
||||
self.bot = bot
|
||||
|
||||
self.data = bot.dbconn.load_registry(AwesomeData())
|
||||
self.awesome = AwesomeRegistry(self.data)
|
||||
self.data = bot.dbconn.load_registry(CampaignData())
|
||||
self.campaigns = CampaignRegistry(self.data)
|
||||
|
||||
# ----- API -----
|
||||
async def component_load(self):
|
||||
await self.data.init()
|
||||
await self.bot.version_check(*self.data.VERSION)
|
||||
await self.profiles.init()
|
||||
await self.campaigns.init()
|
||||
|
||||
async def component_teardown(self):
|
||||
pass
|
||||
|
||||
Reference in New Issue
Block a user