Compare commits
No commits in common. "d448ad7707f57c997b3e7aae6e568117ad9a50e4" and "3cba8de67508847a091251cd849094d79bb43108" have entirely different histories.
d448ad7707
...
3cba8de675
@ -17,7 +17,6 @@
|
|||||||
"permission": "src/modules/permission/permission.json",
|
"permission": "src/modules/permission/permission.json",
|
||||||
"technician": "src/modules/technician/technician.json",
|
"technician": "src/modules/technician/technician.json",
|
||||||
"short-role-name": "src/modules/short_role_name/short-role-name.json",
|
"short-role-name": "src/modules/short_role_name/short-role-name.json",
|
||||||
"special-offers": "src/modules/special_offers/special-offers.json",
|
|
||||||
"checks": "tools/checks/checks.json",
|
"checks": "tools/checks/checks.json",
|
||||||
"get-version": "tools/get_version/get-version.json",
|
"get-version": "tools/get_version/get-version.json",
|
||||||
"post-build": "tools/post_build/post-build.json",
|
"post-build": "tools/post_build/post-build.json",
|
||||||
|
@ -69,7 +69,6 @@
|
|||||||
"../modules/level/level.json",
|
"../modules/level/level.json",
|
||||||
"../modules/permission/permission.json",
|
"../modules/permission/permission.json",
|
||||||
"../modules/short_role_name/short-role-name.json",
|
"../modules/short_role_name/short-role-name.json",
|
||||||
"../modules/special_offers/special-offers.json",
|
|
||||||
"../modules/technician/technician.json"
|
"../modules/technician/technician.json"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 839bbb823a6e0c9e1443e0844446bfe240284063
|
Subproject commit 23eafb2e211241acbbc52833d139c67f1ecc69f5
|
@ -14,7 +14,6 @@ from modules.database.database_module import DatabaseModule
|
|||||||
from modules.level.level_module import LevelModule
|
from modules.level.level_module import LevelModule
|
||||||
from modules.permission.permission_module import PermissionModule
|
from modules.permission.permission_module import PermissionModule
|
||||||
from modules.short_role_name.short_role_name_module import ShortRoleNameModule
|
from modules.short_role_name.short_role_name_module import ShortRoleNameModule
|
||||||
from modules.special_offers.special_offers_module import SteamSpecialOffersModule
|
|
||||||
from modules.technician.technician_module import TechnicianModule
|
from modules.technician.technician_module import TechnicianModule
|
||||||
|
|
||||||
|
|
||||||
@ -38,7 +37,6 @@ class ModuleList:
|
|||||||
TechnicianModule,
|
TechnicianModule,
|
||||||
AchievementsModule,
|
AchievementsModule,
|
||||||
ShortRoleNameModule,
|
ShortRoleNameModule,
|
||||||
SteamSpecialOffersModule,
|
|
||||||
# has to be last!
|
# has to be last!
|
||||||
BootLogModule,
|
BootLogModule,
|
||||||
CoreExtensionModule,
|
CoreExtensionModule,
|
||||||
|
@ -16,7 +16,6 @@ from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings
|
|||||||
from bot_core.logging.command_logger import CommandLogger
|
from bot_core.logging.command_logger import CommandLogger
|
||||||
from bot_core.logging.database_logger import DatabaseLogger
|
from bot_core.logging.database_logger import DatabaseLogger
|
||||||
from bot_core.logging.message_logger import MessageLogger
|
from bot_core.logging.message_logger import MessageLogger
|
||||||
from bot_core.logging.task_logger import TaskLogger
|
|
||||||
from bot_data.db_context import DBContext
|
from bot_data.db_context import DBContext
|
||||||
|
|
||||||
|
|
||||||
@ -44,7 +43,6 @@ class Startup(StartupABC):
|
|||||||
services.add_singleton(CustomFileLoggerABC, CommandLogger)
|
services.add_singleton(CustomFileLoggerABC, CommandLogger)
|
||||||
services.add_singleton(CustomFileLoggerABC, DatabaseLogger)
|
services.add_singleton(CustomFileLoggerABC, DatabaseLogger)
|
||||||
services.add_singleton(CustomFileLoggerABC, MessageLogger)
|
services.add_singleton(CustomFileLoggerABC, MessageLogger)
|
||||||
services.add_singleton(CustomFileLoggerABC, TaskLogger)
|
|
||||||
|
|
||||||
if self._feature_flags.get_flag(FeatureFlagsEnum.api_module):
|
if self._feature_flags.get_flag(FeatureFlagsEnum.api_module):
|
||||||
services.add_singleton(CustomFileLoggerABC, ApiLogger)
|
services.add_singleton(CustomFileLoggerABC, ApiLogger)
|
||||||
|
@ -22,7 +22,6 @@ from bot_data.migration.remove_stats_migration import RemoveStatsMigration
|
|||||||
from bot_data.migration.short_role_name_migration import ShortRoleNameMigration
|
from bot_data.migration.short_role_name_migration import ShortRoleNameMigration
|
||||||
from bot_data.migration.short_role_name_only_highest_migration import ShortRoleNameOnlyHighestMigration
|
from bot_data.migration.short_role_name_only_highest_migration import ShortRoleNameOnlyHighestMigration
|
||||||
from bot_data.migration.stats_migration import StatsMigration
|
from bot_data.migration.stats_migration import StatsMigration
|
||||||
from bot_data.migration.steam_special_offer_migration import SteamSpecialOfferMigration
|
|
||||||
from bot_data.migration.user_joined_game_server_migration import UserJoinedGameServerMigration
|
from bot_data.migration.user_joined_game_server_migration import UserJoinedGameServerMigration
|
||||||
from bot_data.migration.user_message_count_per_hour_migration import (
|
from bot_data.migration.user_message_count_per_hour_migration import (
|
||||||
UserMessageCountPerHourMigration,
|
UserMessageCountPerHourMigration,
|
||||||
@ -61,4 +60,3 @@ class StartupMigrationExtension(StartupExtensionABC):
|
|||||||
services.add_transient(MigrationABC, ShortRoleNameOnlyHighestMigration) # 02.10.2023 #391 - 1.1.9
|
services.add_transient(MigrationABC, ShortRoleNameOnlyHighestMigration) # 02.10.2023 #391 - 1.1.9
|
||||||
services.add_transient(MigrationABC, FixUserHistoryMigration) # 10.10.2023 #401 - 1.2.0
|
services.add_transient(MigrationABC, FixUserHistoryMigration) # 10.10.2023 #401 - 1.2.0
|
||||||
services.add_transient(MigrationABC, BirthdayMigration) # 10.10.2023 #401 - 1.2.0
|
services.add_transient(MigrationABC, BirthdayMigration) # 10.10.2023 #401 - 1.2.0
|
||||||
services.add_transient(MigrationABC, SteamSpecialOfferMigration) # 10.10.2023 #188 - 1.2.0
|
|
||||||
|
@ -94,11 +94,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"modules": {
|
"modules": {
|
||||||
"special_offers": {
|
|
||||||
"price": "Preis",
|
|
||||||
"discount": "Rabatt",
|
|
||||||
"discount_price": "Neuer Preis"
|
|
||||||
},
|
|
||||||
"achievements": {
|
"achievements": {
|
||||||
"commands": {
|
"commands": {
|
||||||
"check": "Alles klar, ich schaue eben nach... nom nom"
|
"check": "Alles klar, ich schaue eben nach... nom nom"
|
||||||
|
@ -17,7 +17,6 @@ class FeatureFlagsEnum(Enum):
|
|||||||
moderator_module = "ModeratorModule"
|
moderator_module = "ModeratorModule"
|
||||||
permission_module = "PermissionModule"
|
permission_module = "PermissionModule"
|
||||||
short_role_name_module = "ShortRoleNameModule"
|
short_role_name_module = "ShortRoleNameModule"
|
||||||
steam_special_offers_module = "SteamSpecialOffersModule"
|
|
||||||
# features
|
# features
|
||||||
api_only = "ApiOnly"
|
api_only = "ApiOnly"
|
||||||
presence = "Presence"
|
presence = "Presence"
|
||||||
@ -26,4 +25,3 @@ class FeatureFlagsEnum(Enum):
|
|||||||
sync_xp = "SyncXp"
|
sync_xp = "SyncXp"
|
||||||
short_role_name = "ShortRoleName"
|
short_role_name = "ShortRoleName"
|
||||||
technician_full_access = "TechnicianFullAccess"
|
technician_full_access = "TechnicianFullAccess"
|
||||||
steam_special_offers = "SteamSpecialOffers"
|
|
||||||
|
@ -19,7 +19,6 @@ class FeatureFlagsSettings(ConfigurationModelABC):
|
|||||||
FeatureFlagsEnum.permission_module.value: True, # 02.10.2022 #48
|
FeatureFlagsEnum.permission_module.value: True, # 02.10.2022 #48
|
||||||
FeatureFlagsEnum.config_module.value: True, # 19.07.2023 #127
|
FeatureFlagsEnum.config_module.value: True, # 19.07.2023 #127
|
||||||
FeatureFlagsEnum.short_role_name_module.value: True, # 28.09.2023 #378
|
FeatureFlagsEnum.short_role_name_module.value: True, # 28.09.2023 #378
|
||||||
FeatureFlagsEnum.steam_special_offers_module.value: True, # 11.10.2023 #188
|
|
||||||
# features
|
# features
|
||||||
FeatureFlagsEnum.api_only.value: False, # 13.10.2022 #70
|
FeatureFlagsEnum.api_only.value: False, # 13.10.2022 #70
|
||||||
FeatureFlagsEnum.presence.value: True, # 03.10.2022 #56
|
FeatureFlagsEnum.presence.value: True, # 03.10.2022 #56
|
||||||
@ -28,7 +27,6 @@ class FeatureFlagsSettings(ConfigurationModelABC):
|
|||||||
FeatureFlagsEnum.sync_xp.value: False, # 25.09.2023 #366
|
FeatureFlagsEnum.sync_xp.value: False, # 25.09.2023 #366
|
||||||
FeatureFlagsEnum.short_role_name.value: False, # 28.09.2023 #378
|
FeatureFlagsEnum.short_role_name.value: False, # 28.09.2023 #378
|
||||||
FeatureFlagsEnum.technician_full_access.value: False, # 03.10.2023 #393
|
FeatureFlagsEnum.technician_full_access.value: False, # 03.10.2023 #393
|
||||||
FeatureFlagsEnum.steam_special_offers.value: False, # 11.10.2023 #188
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, **kwargs: dict):
|
def __init__(self, **kwargs: dict):
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
from cpl_core.configuration import ConfigurationABC
|
|
||||||
from cpl_core.environment import ApplicationEnvironmentABC
|
|
||||||
from cpl_core.time import TimeFormatSettings
|
|
||||||
|
|
||||||
from bot_core.abc.custom_file_logger_abc import CustomFileLoggerABC
|
|
||||||
|
|
||||||
|
|
||||||
class TaskLogger(CustomFileLoggerABC):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
config: ConfigurationABC,
|
|
||||||
time_format: TimeFormatSettings,
|
|
||||||
env: ApplicationEnvironmentABC,
|
|
||||||
):
|
|
||||||
CustomFileLoggerABC.__init__(self, "Task", config, time_format, env)
|
|
@ -71,7 +71,7 @@ class MessageService(MessageServiceABC):
|
|||||||
async def send_channel_message(
|
async def send_channel_message(
|
||||||
self,
|
self,
|
||||||
channel: discord.TextChannel,
|
channel: discord.TextChannel,
|
||||||
message: Union[str, discord.Embed, list[discord.Embed]],
|
message: Union[str, discord.Embed],
|
||||||
is_persistent: bool = False,
|
is_persistent: bool = False,
|
||||||
wait_before_delete: int = None,
|
wait_before_delete: int = None,
|
||||||
without_tracking=False,
|
without_tracking=False,
|
||||||
@ -81,8 +81,6 @@ class MessageService(MessageServiceABC):
|
|||||||
try:
|
try:
|
||||||
if isinstance(message, discord.Embed):
|
if isinstance(message, discord.Embed):
|
||||||
msg = await channel.send(embed=message)
|
msg = await channel.send(embed=message)
|
||||||
elif isinstance(message, list):
|
|
||||||
msg = await channel.send(embeds=message)
|
|
||||||
else:
|
else:
|
||||||
msg = await channel.send(message)
|
msg = await channel.send(message)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
from abc import ABC, abstractmethod
|
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
from cpl_query.extension import List
|
|
||||||
|
|
||||||
from bot_data.model.steam_special_offer import SteamSpecialOffer
|
|
||||||
|
|
||||||
|
|
||||||
class SteamSpecialOfferRepositoryABC(ABC):
|
|
||||||
@abstractmethod
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_steam_special_offers(self) -> List[SteamSpecialOffer]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def get_steam_special_offer_by_name(self, name: str) -> SteamSpecialOffer:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def add_steam_special_offer(self, steam_special_offer: SteamSpecialOffer):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def update_steam_special_offer(self, steam_special_offer: SteamSpecialOffer):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def delete_steam_special_offer(self, steam_special_offer: SteamSpecialOffer):
|
|
||||||
pass
|
|
@ -17,7 +17,6 @@ from bot_data.abc.level_repository_abc import LevelRepositoryABC
|
|||||||
from bot_data.abc.server_config_repository_abc import ServerConfigRepositoryABC
|
from bot_data.abc.server_config_repository_abc import ServerConfigRepositoryABC
|
||||||
from bot_data.abc.server_repository_abc import ServerRepositoryABC
|
from bot_data.abc.server_repository_abc import ServerRepositoryABC
|
||||||
from bot_data.abc.short_role_name_repository_abc import ShortRoleNameRepositoryABC
|
from bot_data.abc.short_role_name_repository_abc import ShortRoleNameRepositoryABC
|
||||||
from bot_data.abc.steam_special_offer_repository_abc import SteamSpecialOfferRepositoryABC
|
|
||||||
from bot_data.abc.technician_config_repository_abc import TechnicianConfigRepositoryABC
|
from bot_data.abc.technician_config_repository_abc import TechnicianConfigRepositoryABC
|
||||||
from bot_data.abc.user_game_ident_repository_abc import UserGameIdentRepositoryABC
|
from bot_data.abc.user_game_ident_repository_abc import UserGameIdentRepositoryABC
|
||||||
from bot_data.abc.user_joined_game_server_repository_abc import UserJoinedGameServerRepositoryABC
|
from bot_data.abc.user_joined_game_server_repository_abc import UserJoinedGameServerRepositoryABC
|
||||||
@ -44,7 +43,6 @@ from bot_data.service.server_config_repository_service import ServerConfigReposi
|
|||||||
from bot_data.service.server_config_seeder import ServerConfigSeeder
|
from bot_data.service.server_config_seeder import ServerConfigSeeder
|
||||||
from bot_data.service.server_repository_service import ServerRepositoryService
|
from bot_data.service.server_repository_service import ServerRepositoryService
|
||||||
from bot_data.service.short_role_name_repository_service import ShortRoleNameRepositoryService
|
from bot_data.service.short_role_name_repository_service import ShortRoleNameRepositoryService
|
||||||
from bot_data.service.steam_special_offer_repository_service import SteamSpecialOfferRepositoryService
|
|
||||||
from bot_data.service.technician_config_repository_service import TechnicianConfigRepositoryService
|
from bot_data.service.technician_config_repository_service import TechnicianConfigRepositoryService
|
||||||
from bot_data.service.technician_config_seeder import TechnicianConfigSeeder
|
from bot_data.service.technician_config_seeder import TechnicianConfigSeeder
|
||||||
from bot_data.service.user_game_ident_repository_service import UserGameIdentRepositoryService
|
from bot_data.service.user_game_ident_repository_service import UserGameIdentRepositoryService
|
||||||
@ -94,7 +92,6 @@ class DataModule(ModuleABC):
|
|||||||
services.add_transient(TechnicianConfigRepositoryABC, TechnicianConfigRepositoryService)
|
services.add_transient(TechnicianConfigRepositoryABC, TechnicianConfigRepositoryService)
|
||||||
services.add_transient(ServerConfigRepositoryABC, ServerConfigRepositoryService)
|
services.add_transient(ServerConfigRepositoryABC, ServerConfigRepositoryService)
|
||||||
services.add_transient(ShortRoleNameRepositoryABC, ShortRoleNameRepositoryService)
|
services.add_transient(ShortRoleNameRepositoryABC, ShortRoleNameRepositoryService)
|
||||||
services.add_transient(SteamSpecialOfferRepositoryABC, SteamSpecialOfferRepositoryService)
|
|
||||||
|
|
||||||
services.add_transient(SeederService)
|
services.add_transient(SeederService)
|
||||||
services.add_transient(DataSeederABC, TechnicianConfigSeeder)
|
services.add_transient(DataSeederABC, TechnicianConfigSeeder)
|
||||||
|
@ -1,68 +0,0 @@
|
|||||||
from bot_core.logging.database_logger import DatabaseLogger
|
|
||||||
from bot_data.abc.migration_abc import MigrationABC
|
|
||||||
from bot_data.db_context import DBContext
|
|
||||||
|
|
||||||
|
|
||||||
class SteamSpecialOfferMigration(MigrationABC):
|
|
||||||
name = "1.2.0_SteamSpecialOfferMigration"
|
|
||||||
|
|
||||||
def __init__(self, logger: DatabaseLogger, db: DBContext):
|
|
||||||
MigrationABC.__init__(self)
|
|
||||||
self._logger = logger
|
|
||||||
self._db = db
|
|
||||||
self._cursor = db.cursor
|
|
||||||
|
|
||||||
def upgrade(self):
|
|
||||||
self._logger.debug(__name__, "Running upgrade")
|
|
||||||
|
|
||||||
self._cursor.execute(
|
|
||||||
str(
|
|
||||||
f"""
|
|
||||||
CREATE TABLE IF NOT EXISTS `SteamSpecialOffers` (
|
|
||||||
`Id` BIGINT NOT NULL AUTO_INCREMENT,
|
|
||||||
`Game` VARCHAR(255) NOT NULL,
|
|
||||||
`OriginalPrice` FLOAT NOT NULL,
|
|
||||||
`DiscountPrice` FLOAT NOT NULL,
|
|
||||||
`DiscountPct` BIGINT NOT NULL,
|
|
||||||
`CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6),
|
|
||||||
`LastModifiedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
|
||||||
PRIMARY KEY(`Id`)
|
|
||||||
);
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
self._cursor.execute(
|
|
||||||
str(
|
|
||||||
f"""
|
|
||||||
ALTER TABLE CFG_Server
|
|
||||||
ADD COLUMN IF NOT EXISTS GameOfferNotificationChatId BIGINT NULL AFTER ShortRoleNameSetOnlyHighest;
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
self._cursor.execute(
|
|
||||||
str(
|
|
||||||
f"""
|
|
||||||
ALTER TABLE CFG_ServerHistory
|
|
||||||
ADD COLUMN IF NOT EXISTS GameOfferNotificationChatId BIGINT NULL AFTER ShortRoleNameSetOnlyHighest;
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
def downgrade(self):
|
|
||||||
self._cursor.execute("DROP TABLE `SteamSpecialOffers`;")
|
|
||||||
self._cursor.execute(
|
|
||||||
str(
|
|
||||||
f"""
|
|
||||||
ALTER TABLE CFG_Server DROP COLUMN ShortRoleNameSetOnlyHighest;
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
||||||
self._cursor.execute(
|
|
||||||
str(
|
|
||||||
f"""
|
|
||||||
ALTER TABLE CFG_ServerHistory DROP COLUMN ShortRoleNameSetOnlyHighest;
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
)
|
|
@ -31,7 +31,6 @@ class ServerConfig(TableABC, ConfigurationModelABC):
|
|||||||
login_message_channel_id: int,
|
login_message_channel_id: int,
|
||||||
default_role_id: Optional[int],
|
default_role_id: Optional[int],
|
||||||
short_role_name_only_set_highest_role: bool,
|
short_role_name_only_set_highest_role: bool,
|
||||||
game_offer_notification_chat_id: int,
|
|
||||||
feature_flags: dict[FeatureFlagsEnum],
|
feature_flags: dict[FeatureFlagsEnum],
|
||||||
server: Server,
|
server: Server,
|
||||||
afk_channel_ids: List[int],
|
afk_channel_ids: List[int],
|
||||||
@ -57,7 +56,6 @@ class ServerConfig(TableABC, ConfigurationModelABC):
|
|||||||
self._login_message_channel_id = login_message_channel_id
|
self._login_message_channel_id = login_message_channel_id
|
||||||
self._default_role_id = default_role_id
|
self._default_role_id = default_role_id
|
||||||
self._short_role_name_only_set_highest_role = short_role_name_only_set_highest_role
|
self._short_role_name_only_set_highest_role = short_role_name_only_set_highest_role
|
||||||
self._game_offer_notification_chat_id = game_offer_notification_chat_id
|
|
||||||
|
|
||||||
self._feature_flags = feature_flags
|
self._feature_flags = feature_flags
|
||||||
self._server = server
|
self._server = server
|
||||||
@ -87,7 +85,6 @@ class ServerConfig(TableABC, ConfigurationModelABC):
|
|||||||
guild.system_channel.id,
|
guild.system_channel.id,
|
||||||
None,
|
None,
|
||||||
False,
|
False,
|
||||||
guild.system_channel.id,
|
|
||||||
{},
|
{},
|
||||||
server,
|
server,
|
||||||
List(int),
|
List(int),
|
||||||
@ -226,14 +223,6 @@ class ServerConfig(TableABC, ConfigurationModelABC):
|
|||||||
def short_role_name_only_set_highest_role(self, value: bool):
|
def short_role_name_only_set_highest_role(self, value: bool):
|
||||||
self._short_role_name_only_set_highest_role = value
|
self._short_role_name_only_set_highest_role = value
|
||||||
|
|
||||||
@property
|
|
||||||
def game_offer_notification_chat_id(self) -> int:
|
|
||||||
return self._game_offer_notification_chat_id
|
|
||||||
|
|
||||||
@game_offer_notification_chat_id.setter
|
|
||||||
def game_offer_notification_chat_id(self, value: int):
|
|
||||||
self._game_offer_notification_chat_id = value
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def feature_flags(self) -> dict[FeatureFlagsEnum]:
|
def feature_flags(self) -> dict[FeatureFlagsEnum]:
|
||||||
return self._feature_flags
|
return self._feature_flags
|
||||||
@ -309,7 +298,6 @@ class ServerConfig(TableABC, ConfigurationModelABC):
|
|||||||
`LoginMessageChannelId`,
|
`LoginMessageChannelId`,
|
||||||
`DefaultRoleId`,
|
`DefaultRoleId`,
|
||||||
`ShortRoleNameSetOnlyHighest`,
|
`ShortRoleNameSetOnlyHighest`,
|
||||||
`GameOfferNotificationChatId`,
|
|
||||||
`FeatureFlags`,
|
`FeatureFlags`,
|
||||||
`ServerId`
|
`ServerId`
|
||||||
) VALUES (
|
) VALUES (
|
||||||
@ -329,7 +317,6 @@ class ServerConfig(TableABC, ConfigurationModelABC):
|
|||||||
{self._login_message_channel_id},
|
{self._login_message_channel_id},
|
||||||
{"NULL" if self._default_role_id is None else self._default_role_id},
|
{"NULL" if self._default_role_id is None else self._default_role_id},
|
||||||
{self._short_role_name_only_set_highest_role},
|
{self._short_role_name_only_set_highest_role},
|
||||||
{self._game_offer_notification_chat_id},
|
|
||||||
'{json.dumps(self._feature_flags)}',
|
'{json.dumps(self._feature_flags)}',
|
||||||
{self._server.id}
|
{self._server.id}
|
||||||
);
|
);
|
||||||
@ -357,7 +344,6 @@ class ServerConfig(TableABC, ConfigurationModelABC):
|
|||||||
`LoginMessageChannelId` = {self._login_message_channel_id},
|
`LoginMessageChannelId` = {self._login_message_channel_id},
|
||||||
`DefaultRoleId` = {"NULL" if self._default_role_id is None else self._default_role_id},
|
`DefaultRoleId` = {"NULL" if self._default_role_id is None else self._default_role_id},
|
||||||
`ShortRoleNameSetOnlyHighest` = {self._short_role_name_only_set_highest_role},
|
`ShortRoleNameSetOnlyHighest` = {self._short_role_name_only_set_highest_role},
|
||||||
`GameOfferNotificationChatId` = {self._game_offer_notification_chat_id},
|
|
||||||
`FeatureFlags` = '{json.dumps(self._feature_flags)}',
|
`FeatureFlags` = '{json.dumps(self._feature_flags)}',
|
||||||
`ServerId` = {self._server.id}
|
`ServerId` = {self._server.id}
|
||||||
WHERE `Id` = {self._id};
|
WHERE `Id` = {self._id};
|
||||||
|
@ -1,115 +0,0 @@
|
|||||||
from datetime import datetime
|
|
||||||
|
|
||||||
from cpl_core.database import TableABC
|
|
||||||
|
|
||||||
|
|
||||||
class SteamSpecialOffer(TableABC):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
name: str,
|
|
||||||
original_price: float,
|
|
||||||
discount_price: float,
|
|
||||||
discount_pct: int,
|
|
||||||
created_at: datetime = None,
|
|
||||||
modified_at: datetime = None,
|
|
||||||
id=0,
|
|
||||||
):
|
|
||||||
self._id = id
|
|
||||||
self._name = name
|
|
||||||
self._original_price = original_price
|
|
||||||
self._discount_price = discount_price
|
|
||||||
self._discount_pct = discount_pct
|
|
||||||
|
|
||||||
TableABC.__init__(self)
|
|
||||||
self._created_at = created_at if created_at is not None else self._created_at
|
|
||||||
self._modified_at = modified_at if modified_at is not None else self._modified_at
|
|
||||||
|
|
||||||
@property
|
|
||||||
def id(self) -> int:
|
|
||||||
return self._id
|
|
||||||
|
|
||||||
@property
|
|
||||||
def name(self) -> str:
|
|
||||||
return self._name
|
|
||||||
|
|
||||||
@name.setter
|
|
||||||
def name(self, value: str):
|
|
||||||
self._name = value
|
|
||||||
|
|
||||||
@property
|
|
||||||
def original_price(self) -> float:
|
|
||||||
return self._original_price
|
|
||||||
|
|
||||||
@original_price.setter
|
|
||||||
def original_price(self, value: float):
|
|
||||||
self._original_price = value
|
|
||||||
|
|
||||||
@property
|
|
||||||
def discount_price(self) -> float:
|
|
||||||
return self._discount_price
|
|
||||||
|
|
||||||
@discount_price.setter
|
|
||||||
def discount_price(self, value: float):
|
|
||||||
self._discount_price = value
|
|
||||||
|
|
||||||
@property
|
|
||||||
def discount_pct(self) -> int:
|
|
||||||
return self._discount_pct
|
|
||||||
|
|
||||||
@discount_pct.setter
|
|
||||||
def discount_pct(self, value: int):
|
|
||||||
self._discount_pct = value
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_select_all_string() -> str:
|
|
||||||
return str(
|
|
||||||
f"""
|
|
||||||
SELECT * FROM `SteamSpecialOffers`;
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_select_by_name_string(name: str) -> str:
|
|
||||||
return str(
|
|
||||||
f"""
|
|
||||||
SELECT * FROM `SteamSpecialOffers`
|
|
||||||
WHERE `Game` = '{name}';
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def insert_string(self) -> str:
|
|
||||||
return str(
|
|
||||||
f"""
|
|
||||||
INSERT INTO `SteamSpecialOffers` (
|
|
||||||
`Game`, `OriginalPrice`, `DiscountPrice`, `DiscountPct`
|
|
||||||
) VALUES (
|
|
||||||
'{self._name}',
|
|
||||||
{self._original_price},
|
|
||||||
{self._discount_price},
|
|
||||||
{self._discount_pct}
|
|
||||||
);
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def udpate_string(self) -> str:
|
|
||||||
return str(
|
|
||||||
f"""
|
|
||||||
UPDATE `SteamSpecialOffers`
|
|
||||||
SET `Game` = '{self._name}',
|
|
||||||
`OriginalPrice` = {self._original_price},
|
|
||||||
`DiscountPrice` = {self._discount_price},
|
|
||||||
`DiscountPct` = {self._discount_pct}
|
|
||||||
WHERE `Id` = {self._id};
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def delete_string(self) -> str:
|
|
||||||
return str(
|
|
||||||
f"""
|
|
||||||
DELETE FROM `SteamSpecialOffers`
|
|
||||||
WHERE `Id` = {self._id};
|
|
||||||
"""
|
|
||||||
)
|
|
@ -67,13 +67,12 @@ class ServerConfigRepositoryService(ServerConfigRepositoryABC):
|
|||||||
result[14],
|
result[14],
|
||||||
result[15],
|
result[15],
|
||||||
result[16],
|
result[16],
|
||||||
result[17],
|
json.loads(result[17]),
|
||||||
json.loads(result[18]),
|
self._servers.get_server_by_id(result[18]),
|
||||||
self._servers.get_server_by_id(result[19]),
|
self._get_afk_channel_ids(result[18]),
|
||||||
self._get_afk_channel_ids(result[19]),
|
self._get_team_role_ids(result[18]),
|
||||||
self._get_team_role_ids(result[19]),
|
result[19],
|
||||||
result[20],
|
result[20],
|
||||||
result[21],
|
|
||||||
id=result[0],
|
id=result[0],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,68 +0,0 @@
|
|||||||
from typing import Optional
|
|
||||||
|
|
||||||
from cpl_core.database.context import DatabaseContextABC
|
|
||||||
from cpl_query.extension import List
|
|
||||||
|
|
||||||
from bot_core.logging.database_logger import DatabaseLogger
|
|
||||||
from bot_data.abc.server_repository_abc import ServerRepositoryABC
|
|
||||||
from bot_data.abc.steam_special_offer_repository_abc import SteamSpecialOfferRepositoryABC
|
|
||||||
from bot_data.model.steam_special_offer import SteamSpecialOffer
|
|
||||||
|
|
||||||
|
|
||||||
class SteamSpecialOfferRepositoryService(SteamSpecialOfferRepositoryABC):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
logger: DatabaseLogger,
|
|
||||||
db_context: DatabaseContextABC,
|
|
||||||
servers: ServerRepositoryABC,
|
|
||||||
):
|
|
||||||
self._logger = logger
|
|
||||||
self._context = db_context
|
|
||||||
|
|
||||||
self._servers = servers
|
|
||||||
|
|
||||||
SteamSpecialOfferRepositoryABC.__init__(self)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _get_value_from_result(value: any) -> Optional[any]:
|
|
||||||
if isinstance(value, str) and "NULL" in value:
|
|
||||||
return None
|
|
||||||
|
|
||||||
return value
|
|
||||||
|
|
||||||
def _steam_special_offer_from_result(self, sql_result: tuple) -> SteamSpecialOffer:
|
|
||||||
return SteamSpecialOffer(
|
|
||||||
self._get_value_from_result(sql_result[1]), # name
|
|
||||||
float(self._get_value_from_result(sql_result[2])), # original_price
|
|
||||||
float(self._get_value_from_result(sql_result[3])), # discount_price
|
|
||||||
int(self._get_value_from_result(sql_result[4])), # discount_pct
|
|
||||||
id=self._get_value_from_result(sql_result[0]), # id
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_steam_special_offers(self) -> List[SteamSpecialOffer]:
|
|
||||||
steam_special_offers = List(SteamSpecialOffer)
|
|
||||||
self._logger.trace(__name__, f"Send SQL command: {SteamSpecialOffer.get_select_all_string()}")
|
|
||||||
results = self._context.select(SteamSpecialOffer.get_select_all_string())
|
|
||||||
for result in results:
|
|
||||||
self._logger.trace(__name__, f"Get steam_special_offer with id {result[0]}")
|
|
||||||
steam_special_offers.append(self._steam_special_offer_from_result(result))
|
|
||||||
|
|
||||||
return steam_special_offers
|
|
||||||
|
|
||||||
def get_steam_special_offer_by_name(self, name: str) -> SteamSpecialOffer:
|
|
||||||
self._logger.trace(__name__, f"Send SQL command: {SteamSpecialOffer.get_select_by_name_string(name)}")
|
|
||||||
result = self._context.select(SteamSpecialOffer.get_select_by_name_string(name))[0]
|
|
||||||
|
|
||||||
return self._steam_special_offer_from_result(result)
|
|
||||||
|
|
||||||
def add_steam_special_offer(self, steam_special_offer: SteamSpecialOffer):
|
|
||||||
self._logger.trace(__name__, f"Send SQL command: {steam_special_offer.insert_string}")
|
|
||||||
self._context.cursor.execute(steam_special_offer.insert_string)
|
|
||||||
|
|
||||||
def update_steam_special_offer(self, steam_special_offer: SteamSpecialOffer):
|
|
||||||
self._logger.trace(__name__, f"Send SQL command: {steam_special_offer.udpate_string}")
|
|
||||||
self._context.cursor.execute(steam_special_offer.udpate_string)
|
|
||||||
|
|
||||||
def delete_steam_special_offer(self, steam_special_offer: SteamSpecialOffer):
|
|
||||||
self._logger.trace(__name__, f"Send SQL command: {steam_special_offer.delete_string}")
|
|
||||||
self._context.cursor.execute(steam_special_offer.delete_string)
|
|
@ -16,7 +16,6 @@ type ServerConfig implements TableWithHistoryQuery {
|
|||||||
loginMessageChannelId: String
|
loginMessageChannelId: String
|
||||||
defaultRoleId: String
|
defaultRoleId: String
|
||||||
shortRoleNameOnlySetHighestRole: Boolean
|
shortRoleNameOnlySetHighestRole: Boolean
|
||||||
gameOfferNotificationChatId: String
|
|
||||||
featureFlagCount: Int
|
featureFlagCount: Int
|
||||||
featureFlags: [FeatureFlag]
|
featureFlags: [FeatureFlag]
|
||||||
|
|
||||||
@ -50,7 +49,6 @@ type ServerConfigHistory implements HistoryTableQuery {
|
|||||||
loginMessageChannelId: String
|
loginMessageChannelId: String
|
||||||
defaultRoleId: String
|
defaultRoleId: String
|
||||||
shortRoleNameOnlySetHighestRole: Boolean
|
shortRoleNameOnlySetHighestRole: Boolean
|
||||||
gameOfferNotificationChatId: String
|
|
||||||
featureFlagCount: Int
|
featureFlagCount: Int
|
||||||
featureFlags: [FeatureFlag]
|
featureFlags: [FeatureFlag]
|
||||||
|
|
||||||
@ -102,7 +100,6 @@ input ServerConfigInput {
|
|||||||
loginMessageChannelId: String
|
loginMessageChannelId: String
|
||||||
defaultRoleId: String
|
defaultRoleId: String
|
||||||
shortRoleNameOnlySetHighestRole: Boolean
|
shortRoleNameOnlySetHighestRole: Boolean
|
||||||
gameOfferNotificationChatId: String
|
|
||||||
featureFlags: [FeatureFlagInput]
|
featureFlags: [FeatureFlagInput]
|
||||||
|
|
||||||
afkChannelIds: [String]
|
afkChannelIds: [String]
|
||||||
|
@ -94,11 +94,6 @@ class ServerConfigMutation(QueryABC):
|
|||||||
if "shortRoleNameOnlySetHighestRole" in input
|
if "shortRoleNameOnlySetHighestRole" in input
|
||||||
else server_config.short_role_name_only_set_highest_role
|
else server_config.short_role_name_only_set_highest_role
|
||||||
)
|
)
|
||||||
server_config.game_offer_notification_chat_id = (
|
|
||||||
input["gameOfferNotificationChatId"]
|
|
||||||
if "gameOfferNotificationChatId" in input
|
|
||||||
else server_config.game_offer_notification_chat_id
|
|
||||||
)
|
|
||||||
server_config.feature_flags = (
|
server_config.feature_flags = (
|
||||||
dict(zip([x["key"] for x in input["featureFlags"]], [x["value"] for x in input["featureFlags"]]))
|
dict(zip([x["key"] for x in input["featureFlags"]], [x["value"] for x in input["featureFlags"]]))
|
||||||
if "featureFlags" in input
|
if "featureFlags" in input
|
||||||
|
@ -29,7 +29,6 @@ class ServerConfigQuery(DataQueryWithHistoryABC):
|
|||||||
self.set_field(
|
self.set_field(
|
||||||
"shortRoleNameOnlySetHighestRole", lambda config, *_: config.short_role_name_only_set_highest_role
|
"shortRoleNameOnlySetHighestRole", lambda config, *_: config.short_role_name_only_set_highest_role
|
||||||
)
|
)
|
||||||
self.set_field("gameOfferNotificationChatId", lambda config, *_: config.game_offer_notification_chat_id)
|
|
||||||
self.add_collection(
|
self.add_collection(
|
||||||
"featureFlag",
|
"featureFlag",
|
||||||
lambda config, *_: List(any, [{"key": x, "value": config.feature_flags[x]} for x in config.feature_flags]),
|
lambda config, *_: List(any, [{"key": x, "value": config.feature_flags[x]} for x in config.feature_flags]),
|
||||||
|
@ -1 +0,0 @@
|
|||||||
# imports
|
|
@ -1 +0,0 @@
|
|||||||
# imports
|
|
@ -1,13 +0,0 @@
|
|||||||
from abc import ABC, abstractmethod
|
|
||||||
|
|
||||||
from discord.ext import commands
|
|
||||||
|
|
||||||
|
|
||||||
class SpecialOfferWatcherABC(commands.Cog):
|
|
||||||
@abstractmethod
|
|
||||||
def __init__(self):
|
|
||||||
commands.Cog.__init__(self)
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def start(self):
|
|
||||||
pass
|
|
@ -1 +0,0 @@
|
|||||||
# imports
|
|
@ -1,25 +0,0 @@
|
|||||||
from cpl_core.logging import LoggerABC
|
|
||||||
from cpl_discord.events import OnReadyABC
|
|
||||||
from cpl_discord.service import DiscordBotServiceABC
|
|
||||||
|
|
||||||
from bot_core.logging.task_logger import TaskLogger
|
|
||||||
from modules.special_offers.base.special_offer_watcher_abc import SpecialOfferWatcherABC
|
|
||||||
|
|
||||||
|
|
||||||
class SpecialOfferOnReadyEvent(OnReadyABC):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
logger: TaskLogger,
|
|
||||||
bot: DiscordBotServiceABC,
|
|
||||||
watchers: list[SpecialOfferWatcherABC],
|
|
||||||
):
|
|
||||||
OnReadyABC.__init__(self)
|
|
||||||
|
|
||||||
self._logger = logger
|
|
||||||
self._bot = bot
|
|
||||||
self._watchers = watchers
|
|
||||||
|
|
||||||
async def on_ready(self):
|
|
||||||
for watcher in self._watchers:
|
|
||||||
self._logger.info(__name__, f"Starting watcher {type(watcher).__name__}")
|
|
||||||
watcher.start()
|
|
@ -1,46 +0,0 @@
|
|||||||
{
|
|
||||||
"ProjectSettings": {
|
|
||||||
"Name": "steam-special-offers",
|
|
||||||
"Version": {
|
|
||||||
"Major": "0",
|
|
||||||
"Minor": "0",
|
|
||||||
"Micro": "0"
|
|
||||||
},
|
|
||||||
"Author": "",
|
|
||||||
"AuthorEmail": "",
|
|
||||||
"Description": "",
|
|
||||||
"LongDescription": "",
|
|
||||||
"URL": "",
|
|
||||||
"CopyrightDate": "",
|
|
||||||
"CopyrightName": "",
|
|
||||||
"LicenseName": "",
|
|
||||||
"LicenseDescription": "",
|
|
||||||
"Dependencies": [
|
|
||||||
"cpl-core>=2023.4.0.post5"
|
|
||||||
],
|
|
||||||
"DevDependencies": [
|
|
||||||
"cpl-cli>=2023.4.0.post3"
|
|
||||||
],
|
|
||||||
"PythonVersion": ">=3.10.4",
|
|
||||||
"PythonPath": {
|
|
||||||
"linux": ""
|
|
||||||
},
|
|
||||||
"Classifiers": []
|
|
||||||
},
|
|
||||||
"BuildSettings": {
|
|
||||||
"ProjectType": "library",
|
|
||||||
"SourcePath": "",
|
|
||||||
"OutputPath": "../../dist",
|
|
||||||
"Main": "steam_special_offers.main",
|
|
||||||
"EntryPoint": "steam-special-offers",
|
|
||||||
"IncludePackageData": false,
|
|
||||||
"Included": [],
|
|
||||||
"Excluded": [
|
|
||||||
"*/__pycache__",
|
|
||||||
"*/logs",
|
|
||||||
"*/tests"
|
|
||||||
],
|
|
||||||
"PackageData": {},
|
|
||||||
"ProjectReferences": []
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
from cpl_core.configuration import ConfigurationABC
|
|
||||||
from cpl_core.dependency_injection import ServiceCollectionABC
|
|
||||||
from cpl_core.environment import ApplicationEnvironmentABC
|
|
||||||
from cpl_discord.discord_event_types_enum import DiscordEventTypesEnum
|
|
||||||
from cpl_discord.service.discord_collection_abc import DiscordCollectionABC
|
|
||||||
|
|
||||||
from bot_core.abc.module_abc import ModuleABC
|
|
||||||
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
|
||||||
from modules.special_offers.base.special_offer_watcher_abc import SpecialOfferWatcherABC
|
|
||||||
from modules.special_offers.events.special_offer_on_ready_event import SpecialOfferOnReadyEvent
|
|
||||||
from modules.special_offers.steam_offer_watcher import SteamOfferWatcher
|
|
||||||
|
|
||||||
|
|
||||||
class SteamSpecialOffersModule(ModuleABC):
|
|
||||||
def __init__(self, dc: DiscordCollectionABC):
|
|
||||||
ModuleABC.__init__(self, dc, FeatureFlagsEnum.steam_special_offers_module)
|
|
||||||
|
|
||||||
def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC):
|
|
||||||
services.add_singleton(SpecialOfferWatcherABC, SteamOfferWatcher)
|
|
||||||
# commands
|
|
||||||
# events
|
|
||||||
self._dc.add_event(DiscordEventTypesEnum.on_ready.value, SpecialOfferOnReadyEvent)
|
|
@ -1,210 +0,0 @@
|
|||||||
from datetime import datetime
|
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
import bs4
|
|
||||||
import discord
|
|
||||||
import requests
|
|
||||||
from cpl_core.configuration import ConfigurationABC
|
|
||||||
from cpl_core.database.context import DatabaseContextABC
|
|
||||||
from cpl_discord.service import DiscordBotServiceABC
|
|
||||||
from cpl_query.extension import List
|
|
||||||
from cpl_translation import TranslatePipe
|
|
||||||
from discord.ext import tasks
|
|
||||||
|
|
||||||
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
|
|
||||||
from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings
|
|
||||||
from bot_core.logging.task_logger import TaskLogger
|
|
||||||
from bot_core.service.message_service import MessageService
|
|
||||||
from bot_data.abc.steam_special_offer_repository_abc import SteamSpecialOfferRepositoryABC
|
|
||||||
from bot_data.model.server_config import ServerConfig
|
|
||||||
from bot_data.model.steam_special_offer import SteamSpecialOffer
|
|
||||||
from modules.special_offers.base.special_offer_watcher_abc import SpecialOfferWatcherABC
|
|
||||||
|
|
||||||
|
|
||||||
class SteamOfferWatcher(SpecialOfferWatcherABC):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
config: ConfigurationABC,
|
|
||||||
bot: DiscordBotServiceABC,
|
|
||||||
logger: TaskLogger,
|
|
||||||
db: DatabaseContextABC,
|
|
||||||
offers: SteamSpecialOfferRepositoryABC,
|
|
||||||
message_service: MessageService,
|
|
||||||
t: TranslatePipe,
|
|
||||||
):
|
|
||||||
SpecialOfferWatcherABC.__init__(self)
|
|
||||||
|
|
||||||
self._config = config
|
|
||||||
self._logger = logger
|
|
||||||
self._db = db
|
|
||||||
self._offers = offers
|
|
||||||
self._bot = bot
|
|
||||||
self._message_service = message_service
|
|
||||||
self._t = t
|
|
||||||
|
|
||||||
self._is_new = False
|
|
||||||
self._urls = {}
|
|
||||||
self._image_urls = {}
|
|
||||||
|
|
||||||
def start(self):
|
|
||||||
self.watch.start()
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _get_max_count() -> int:
|
|
||||||
count = 0
|
|
||||||
result = requests.get(f"https://store.steampowered.com/search/results?specials=1")
|
|
||||||
soup = bs4.BeautifulSoup(result.text, "lxml")
|
|
||||||
element = soup.find_all("div", {"class": "search_results_count"})
|
|
||||||
if len(element) < 1:
|
|
||||||
return count
|
|
||||||
|
|
||||||
count = int(element[0].contents[0].split(" ")[0].replace(",", ""))
|
|
||||||
|
|
||||||
return count
|
|
||||||
|
|
||||||
def _get_games_from_page(self, start: int, count: int) -> List[SteamSpecialOffer]:
|
|
||||||
games = List(SteamSpecialOffer)
|
|
||||||
result = requests.get(
|
|
||||||
f"https://store.steampowered.com/search/results?query&start={start}&count={count}&force_infinite=1&specials=1"
|
|
||||||
)
|
|
||||||
soup = bs4.BeautifulSoup(result.text, "lxml")
|
|
||||||
elements = soup.find_all("a", {"class": "search_result_row"})
|
|
||||||
if len(elements) < 1:
|
|
||||||
return games
|
|
||||||
|
|
||||||
for element in elements:
|
|
||||||
name_element = element.find("span", {"class": "title"})
|
|
||||||
original_price_element = element.find("div", {"class": "discount_original_price"})
|
|
||||||
discount_element = element.find("div", {"class": "discount_pct"})
|
|
||||||
discount_price_element = element.find("div", {"class": "discount_final_price"})
|
|
||||||
|
|
||||||
if (
|
|
||||||
name_element is None
|
|
||||||
or len(name_element.contents) < 1
|
|
||||||
or original_price_element is None
|
|
||||||
or len(original_price_element.contents) < 1
|
|
||||||
or discount_element is None
|
|
||||||
or len(discount_element.contents) < 1
|
|
||||||
or discount_price_element is None
|
|
||||||
or len(discount_price_element.contents) < 1
|
|
||||||
):
|
|
||||||
continue
|
|
||||||
|
|
||||||
name = name_element.contents[0].replace("'", "`").replace('"', "`")
|
|
||||||
original_price = float(
|
|
||||||
original_price_element.contents[0].replace(" ", "").replace("€", "").replace(",", ".")
|
|
||||||
)
|
|
||||||
discount = int(discount_element.contents[0].replace("%", ""))
|
|
||||||
discount_price = float(
|
|
||||||
discount_price_element.contents[0].replace(" ", "").replace("€", "").replace(",", ".")
|
|
||||||
)
|
|
||||||
games.add(SteamSpecialOffer(name, original_price, discount_price, discount))
|
|
||||||
self._urls[name] = element.attrs["href"]
|
|
||||||
self._image_urls[name] = element.find("div", {"class": "search_capsule"}).find("img").attrs["src"]
|
|
||||||
|
|
||||||
return games
|
|
||||||
|
|
||||||
def _get_new_game_offers(self) -> List[SteamSpecialOffer]:
|
|
||||||
new_offers = List(SteamSpecialOffer)
|
|
||||||
|
|
||||||
sale_count = self._get_max_count() + 100
|
|
||||||
sale_count = 300
|
|
||||||
self._logger.debug(__name__, f"Get special offers from 0 to {sale_count}")
|
|
||||||
for i in range(0, sale_count, 100):
|
|
||||||
new_offers.extend(self._get_games_from_page(i, 100))
|
|
||||||
|
|
||||||
self._logger.debug(__name__, f"Got {new_offers.count()} offers")
|
|
||||||
|
|
||||||
return new_offers
|
|
||||||
|
|
||||||
def _build_embed_for_offer(self, offer: SteamSpecialOffer) -> discord.Embed:
|
|
||||||
embed = discord.Embed(
|
|
||||||
title=offer.name,
|
|
||||||
url=self._urls[offer.name],
|
|
||||||
color=int("ef9d0d", 16),
|
|
||||||
timestamp=datetime.now(),
|
|
||||||
)
|
|
||||||
|
|
||||||
embed.add_field(
|
|
||||||
name=self._t.transform("modules.special_offers.price"),
|
|
||||||
value=f"~~{offer.original_price}€~~",
|
|
||||||
inline=True,
|
|
||||||
)
|
|
||||||
embed.add_field(
|
|
||||||
name=self._t.transform("modules.special_offers.discount"), value=f"{offer.discount_pct}%", inline=True
|
|
||||||
)
|
|
||||||
embed.add_field(
|
|
||||||
name=self._t.transform("modules.special_offers.discount_price"),
|
|
||||||
value=f"{offer.discount_price}€",
|
|
||||||
inline=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
embed.set_image(url=self._image_urls[offer.name])
|
|
||||||
return embed
|
|
||||||
|
|
||||||
async def _watch(self):
|
|
||||||
self._is_new = self._offers.get_steam_special_offers().count() == 0
|
|
||||||
new_offers = self._get_new_game_offers()
|
|
||||||
new_offers_names = new_offers.select(lambda x: x.name).to_list()
|
|
||||||
|
|
||||||
old_offers = self._offers.get_steam_special_offers()
|
|
||||||
old_offers_names = old_offers.select(lambda x: x.name).to_list()
|
|
||||||
|
|
||||||
offers_for_notifications = List(SteamSpecialOffer)
|
|
||||||
|
|
||||||
for offer in old_offers:
|
|
||||||
offer: SteamSpecialOffer = offer
|
|
||||||
if offer.name in new_offers_names:
|
|
||||||
continue
|
|
||||||
|
|
||||||
self._offers.delete_steam_special_offer(offer)
|
|
||||||
self._db.save_changes()
|
|
||||||
|
|
||||||
for offer in new_offers:
|
|
||||||
if offer.name in old_offers_names:
|
|
||||||
self._offers.update_steam_special_offer(offer)
|
|
||||||
self._db.save_changes()
|
|
||||||
continue
|
|
||||||
|
|
||||||
self._offers.add_steam_special_offer(offer)
|
|
||||||
self._db.save_changes()
|
|
||||||
offers_for_notifications.add(offer)
|
|
||||||
|
|
||||||
self._logger.trace(__name__, "Finished watching")
|
|
||||||
# if self._is_new:
|
|
||||||
# return
|
|
||||||
|
|
||||||
self._logger.debug(__name__, f"Sending offer notifications for {offers_for_notifications.count()} offers")
|
|
||||||
for guild in self._bot.guilds:
|
|
||||||
settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{guild.id}")
|
|
||||||
if (
|
|
||||||
not FeatureFlagsSettings.get_flag_from_dict(
|
|
||||||
settings.feature_flags, FeatureFlagsEnum.steam_special_offers
|
|
||||||
)
|
|
||||||
and settings.game_offer_notification_chat_id is None
|
|
||||||
):
|
|
||||||
continue
|
|
||||||
|
|
||||||
embeds = []
|
|
||||||
|
|
||||||
for offer in offers_for_notifications:
|
|
||||||
embed = self._build_embed_for_offer(offer)
|
|
||||||
if embed is None:
|
|
||||||
continue
|
|
||||||
embeds.append(embed)
|
|
||||||
|
|
||||||
print(embeds)
|
|
||||||
# await self._message_service.send_channel_message(
|
|
||||||
# self._bot.get_channel(settings.game_offer_notification_chat_id),
|
|
||||||
# embeds,
|
|
||||||
# is_persistent=True,
|
|
||||||
# )
|
|
||||||
|
|
||||||
@tasks.loop(minutes=60)
|
|
||||||
async def watch(self):
|
|
||||||
self._logger.info(__name__, "Watching steam special offers")
|
|
||||||
try:
|
|
||||||
pass
|
|
||||||
# await self._watch()
|
|
||||||
except Exception as e:
|
|
||||||
self._logger.error(__name__, f"Steam offer watcher failed", e)
|
|
@ -18,7 +18,6 @@ export interface ServerConfig extends DataWithHistory {
|
|||||||
loginMessageChannelId?: string;
|
loginMessageChannelId?: string;
|
||||||
defaultRoleId?: string;
|
defaultRoleId?: string;
|
||||||
shortRoleNameOnlySetHighestRole?: boolean;
|
shortRoleNameOnlySetHighestRole?: boolean;
|
||||||
gameOfferNotificationChatId?: string;
|
|
||||||
featureFlags: FeatureFlag[];
|
featureFlags: FeatureFlag[];
|
||||||
afkChannelIds: string[];
|
afkChannelIds: string[];
|
||||||
moderatorRoleIds: string[];
|
moderatorRoleIds: string[];
|
||||||
|
@ -261,8 +261,7 @@ export class Mutations {
|
|||||||
$teamChannelId: String,
|
$teamChannelId: String,
|
||||||
$loginMessageChannelId: String,
|
$loginMessageChannelId: String,
|
||||||
$defaultRoleId: String,
|
$defaultRoleId: String,
|
||||||
$shortRoleNameOnlySetHighestRole: Boolean,
|
$shortRoleNameOnlySetHighestRole: Boolean
|
||||||
$gameOfferNotificationChatId: String,
|
|
||||||
$featureFlags: [FeatureFlagInput],
|
$featureFlags: [FeatureFlagInput],
|
||||||
$afkChannelIds: [String],
|
$afkChannelIds: [String],
|
||||||
$moderatorRoleIds: [String],
|
$moderatorRoleIds: [String],
|
||||||
@ -286,7 +285,6 @@ export class Mutations {
|
|||||||
loginMessageChannelId: $loginMessageChannelId,
|
loginMessageChannelId: $loginMessageChannelId,
|
||||||
defaultRoleId: $defaultRoleId,
|
defaultRoleId: $defaultRoleId,
|
||||||
shortRoleNameOnlySetHighestRole: $shortRoleNameOnlySetHighestRole,
|
shortRoleNameOnlySetHighestRole: $shortRoleNameOnlySetHighestRole,
|
||||||
gameOfferNotificationChatId: $gameOfferNotificationChatId,
|
|
||||||
featureFlags: $featureFlags,
|
featureFlags: $featureFlags,
|
||||||
afkChannelIds: $afkChannelIds,
|
afkChannelIds: $afkChannelIds,
|
||||||
moderatorRoleIds: $moderatorRoleIds,
|
moderatorRoleIds: $moderatorRoleIds,
|
||||||
@ -308,7 +306,6 @@ export class Mutations {
|
|||||||
loginMessageChannelId
|
loginMessageChannelId
|
||||||
defaultRoleId
|
defaultRoleId
|
||||||
shortRoleNameOnlySetHighestRole
|
shortRoleNameOnlySetHighestRole
|
||||||
gameOfferNotificationChatId
|
|
||||||
featureFlags {
|
featureFlags {
|
||||||
key
|
key
|
||||||
value
|
value
|
||||||
|
@ -130,14 +130,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content-row">
|
|
||||||
<div class="content-column">
|
|
||||||
<div class="content-data-name">{{'view.server.config.bot.game_offer_notification_chat_id' | translate}}:</div>
|
|
||||||
<p-dropdown class="content-data-value" [options]="textChannels" optionLabel="name" optionValue="id" [(ngModel)]="config.gameOfferNotificationChatId"
|
|
||||||
placeholder="{{'view.server.config.bot.game_offer_notification_chat_id' | translate}}"></p-dropdown>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="content-divider"></div>
|
<div class="content-divider"></div>
|
||||||
<app-config-list [options]="voiceChannels" optionLabel="name" optionValue="id" translationKey="view.server.config.bot.afk_channels"
|
<app-config-list [options]="voiceChannels" optionLabel="name" optionValue="id" translationKey="view.server.config.bot.afk_channels"
|
||||||
[(data)]="config.afkChannelIds"></app-config-list>
|
[(data)]="config.afkChannelIds"></app-config-list>
|
||||||
|
@ -124,7 +124,6 @@ export class ConfigComponent implements OnInit {
|
|||||||
loginMessageChannelId: this.config.loginMessageChannelId,
|
loginMessageChannelId: this.config.loginMessageChannelId,
|
||||||
defaultRoleId: this.config.defaultRoleId,
|
defaultRoleId: this.config.defaultRoleId,
|
||||||
shortRoleNameOnlySetHighestRole: this.config.shortRoleNameOnlySetHighestRole,
|
shortRoleNameOnlySetHighestRole: this.config.shortRoleNameOnlySetHighestRole,
|
||||||
gameOfferNotificationChatId: this.config.gameOfferNotificationChatId,
|
|
||||||
featureFlags: this.config.featureFlags,
|
featureFlags: this.config.featureFlags,
|
||||||
afkChannelIds: this.config.afkChannelIds,
|
afkChannelIds: this.config.afkChannelIds,
|
||||||
moderatorRoleIds: this.config.moderatorRoleIds,
|
moderatorRoleIds: this.config.moderatorRoleIds,
|
||||||
|
@ -122,13 +122,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
|
"edit": "Bearbeiten",
|
||||||
|
"user_warnings": "Verwarnungen",
|
||||||
|
"author": "Autor",
|
||||||
"404": "404 - Der Eintrag konnte nicht gefunden werden",
|
"404": "404 - Der Eintrag konnte nicht gefunden werden",
|
||||||
"actions": "Aktionen",
|
"actions": "Aktionen",
|
||||||
"active": "Aktiv",
|
"active": "Aktiv",
|
||||||
"add": "Hinzufügen",
|
"add": "Hinzufügen",
|
||||||
"attribute": "Attribut",
|
"attribute": "Attribut",
|
||||||
"auth_role": "Rolle",
|
"auth_role": "Rolle",
|
||||||
"author": "Autor",
|
|
||||||
"bool_as_string": {
|
"bool_as_string": {
|
||||||
"false": "Nein",
|
"false": "Nein",
|
||||||
"true": "Ja"
|
"true": "Ja"
|
||||||
@ -139,7 +141,6 @@
|
|||||||
"created_at": "Erstellt am",
|
"created_at": "Erstellt am",
|
||||||
"description": "Beschreibung",
|
"description": "Beschreibung",
|
||||||
"discord_id": "Discord Id",
|
"discord_id": "Discord Id",
|
||||||
"edit": "Bearbeiten",
|
|
||||||
"email": "E-Mail",
|
"email": "E-Mail",
|
||||||
"emoji": "Emoji",
|
"emoji": "Emoji",
|
||||||
"error": "Fehler",
|
"error": "Fehler",
|
||||||
@ -194,7 +195,6 @@
|
|||||||
"role": "Rolle",
|
"role": "Rolle",
|
||||||
"rule_count": "Regeln",
|
"rule_count": "Regeln",
|
||||||
"save": "Speichern",
|
"save": "Speichern",
|
||||||
"user_warnings": "Verwarnungen",
|
|
||||||
"users": "Benutzer",
|
"users": "Benutzer",
|
||||||
"value": "Wert",
|
"value": "Wert",
|
||||||
"xp": "XP"
|
"xp": "XP"
|
||||||
@ -422,7 +422,7 @@
|
|||||||
"afk_channels": "AFK Sprachkanäle",
|
"afk_channels": "AFK Sprachkanäle",
|
||||||
"afk_command_channel_id": "AFK Kanal für den Befehl /afk",
|
"afk_command_channel_id": "AFK Kanal für den Befehl /afk",
|
||||||
"default_role_id": "Standardrolle des Servers",
|
"default_role_id": "Standardrolle des Servers",
|
||||||
"game_offer_notification_chat_id": "Benachrichtungskanal für Spiel Angebote",
|
"short_role_name_only_set_highest_role": "Bei Rollen Kürzeln nur die höchste Rolle verwenden",
|
||||||
"header": "Bot Konfiguration",
|
"header": "Bot Konfiguration",
|
||||||
"help_voice_channel_id": "Sprachkanal für Hilfsbenachrichtung",
|
"help_voice_channel_id": "Sprachkanal für Hilfsbenachrichtung",
|
||||||
"login_message_channel_id": "Kanal für die Nachricht vom Bot nach Start",
|
"login_message_channel_id": "Kanal für die Nachricht vom Bot nach Start",
|
||||||
@ -431,7 +431,6 @@
|
|||||||
"message_delete_timer": "Zeit bis zum löschen einer Botnachricht in sekunden",
|
"message_delete_timer": "Zeit bis zum löschen einer Botnachricht in sekunden",
|
||||||
"moderator_roles": "Moderator Rollen",
|
"moderator_roles": "Moderator Rollen",
|
||||||
"notification_chat_id": "Benachrichtungskanal",
|
"notification_chat_id": "Benachrichtungskanal",
|
||||||
"short_role_name_only_set_highest_role": "Bei Rollen Kürzeln nur die höchste Rolle verwenden",
|
|
||||||
"team_channel_id": "Team chat",
|
"team_channel_id": "Team chat",
|
||||||
"xp_per_achievement": "XP für Errungenschaft",
|
"xp_per_achievement": "XP für Errungenschaft",
|
||||||
"xp_per_event_participation": "XP für Event Teilnahme",
|
"xp_per_event_participation": "XP für Event Teilnahme",
|
||||||
@ -486,11 +485,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"profile": {
|
"profile": {
|
||||||
|
"message_count": "Anzahl Nachrichten",
|
||||||
|
"reaction_count": "Anzahl Reaktionen",
|
||||||
|
"birthday": "Geburtstag",
|
||||||
"achievements": {
|
"achievements": {
|
||||||
"header": "Errungeschaften",
|
"header": "Errungeschaften",
|
||||||
"time": "Erreicht am"
|
"time": "Erreicht am"
|
||||||
},
|
},
|
||||||
"birthday": "Geburtstag",
|
|
||||||
"header": "Dein Profil",
|
"header": "Dein Profil",
|
||||||
"joined_game_server": {
|
"joined_game_server": {
|
||||||
"header": "Gameserver-beitritte",
|
"header": "Gameserver-beitritte",
|
||||||
@ -508,13 +509,11 @@
|
|||||||
},
|
},
|
||||||
"left_server": "Hat Server verlassen",
|
"left_server": "Hat Server verlassen",
|
||||||
"level": "Level",
|
"level": "Level",
|
||||||
"message_count": "Anzahl Nachrichten",
|
|
||||||
"minecraft_id": "Minecraft Id",
|
"minecraft_id": "Minecraft Id",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
"ontime": "Ontime",
|
"ontime": "Ontime",
|
||||||
"permission_denied": "Zugriff verweigert!",
|
"permission_denied": "Zugriff verweigert!",
|
||||||
"permission_denied_d": "Du musst Moderator sein, um andere Profile sehen zu können!",
|
"permission_denied_d": "Du musst Moderator sein, um andere Profile sehen zu können!",
|
||||||
"reaction_count": "Anzahl Reaktionen",
|
|
||||||
"xp": "XP"
|
"xp": "XP"
|
||||||
},
|
},
|
||||||
"short_role_names": {
|
"short_role_names": {
|
||||||
|
@ -128,7 +128,6 @@
|
|||||||
"add": "Add",
|
"add": "Add",
|
||||||
"attribute": "Attribute",
|
"attribute": "Attribute",
|
||||||
"auth_role": "Role",
|
"auth_role": "Role",
|
||||||
"author": "Author",
|
|
||||||
"bool_as_string": {
|
"bool_as_string": {
|
||||||
"false": "No",
|
"false": "No",
|
||||||
"true": "Yes"
|
"true": "Yes"
|
||||||
@ -139,7 +138,6 @@
|
|||||||
"created_at": "Created at",
|
"created_at": "Created at",
|
||||||
"description": "Description",
|
"description": "Description",
|
||||||
"discord_id": "Discord Id",
|
"discord_id": "Discord Id",
|
||||||
"edit": "Edit",
|
|
||||||
"email": "E-Mail",
|
"email": "E-Mail",
|
||||||
"emoji": "Emoji",
|
"emoji": "Emoji",
|
||||||
"error": "Error",
|
"error": "Error",
|
||||||
@ -194,7 +192,6 @@
|
|||||||
"role": "Role",
|
"role": "Role",
|
||||||
"rule_count": "Rules",
|
"rule_count": "Rules",
|
||||||
"save": "Save",
|
"save": "Save",
|
||||||
"user_warnings": "User warnings",
|
|
||||||
"users": "User",
|
"users": "User",
|
||||||
"value": "Value",
|
"value": "Value",
|
||||||
"xp": "XP"
|
"xp": "XP"
|
||||||
@ -422,7 +419,7 @@
|
|||||||
"afk_channels": "AFK Voicechannel",
|
"afk_channels": "AFK Voicechannel",
|
||||||
"afk_command_channel_id": "AFK Channel for the command /afk",
|
"afk_command_channel_id": "AFK Channel for the command /afk",
|
||||||
"default_role_id": "Default role",
|
"default_role_id": "Default role",
|
||||||
"game_offer_notification_chat_id": "Notification channel for game sales",
|
"short_role_name_only_set_highest_role": "For role abbreviations use only the highest role",
|
||||||
"header": "Bot configuration",
|
"header": "Bot configuration",
|
||||||
"help_voice_channel_id": "Voicechannel für help notifications",
|
"help_voice_channel_id": "Voicechannel für help notifications",
|
||||||
"login_message_channel_id": "Channel for bot message after start",
|
"login_message_channel_id": "Channel for bot message after start",
|
||||||
@ -431,7 +428,6 @@
|
|||||||
"message_delete_timer": "Time to wait before delete bot messages",
|
"message_delete_timer": "Time to wait before delete bot messages",
|
||||||
"moderator_roles": "Moderator roles",
|
"moderator_roles": "Moderator roles",
|
||||||
"notification_chat_id": "Notification channel",
|
"notification_chat_id": "Notification channel",
|
||||||
"short_role_name_only_set_highest_role": "For role abbreviations use only the highest role",
|
|
||||||
"team_channel_id": "Team chat",
|
"team_channel_id": "Team chat",
|
||||||
"xp_per_achievement": "XP for achievement",
|
"xp_per_achievement": "XP for achievement",
|
||||||
"xp_per_event_participation": "XP for event participation",
|
"xp_per_event_participation": "XP for event participation",
|
||||||
@ -490,7 +486,6 @@
|
|||||||
"header": "Achievements",
|
"header": "Achievements",
|
||||||
"time": "Reached at"
|
"time": "Reached at"
|
||||||
},
|
},
|
||||||
"birthday": "Birthday",
|
|
||||||
"header": "Profile",
|
"header": "Profile",
|
||||||
"joined_game_server": {
|
"joined_game_server": {
|
||||||
"header": "Game server accessions",
|
"header": "Game server accessions",
|
||||||
@ -508,13 +503,11 @@
|
|||||||
},
|
},
|
||||||
"left_server": "Leaved server",
|
"left_server": "Leaved server",
|
||||||
"level": "Level",
|
"level": "Level",
|
||||||
"message_count": "Message count",
|
|
||||||
"minecraft_id": "Minecraft Id",
|
"minecraft_id": "Minecraft Id",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
"ontime": "Ontime",
|
"ontime": "Ontime",
|
||||||
"permission_denied": "Access denied!",
|
"permission_denied": "Access denied!",
|
||||||
"permission_denied_d": "You have to be moderator to see other profiles!",
|
"permission_denied_d": "You have to be moderator to see other profiles!",
|
||||||
"reaction_count": "Reaction count",
|
|
||||||
"xp": "XP"
|
"xp": "XP"
|
||||||
},
|
},
|
||||||
"short_role_names": {
|
"short_role_names": {
|
||||||
|
Loading…
Reference in New Issue
Block a user