From b908ce17ed6051e5f45b93cf540b4ef199d2b7e1 Mon Sep 17 00:00:00 2001 From: suti7yk5032 Date: Sun, 21 Jul 2024 16:36:16 +0900 Subject: [PATCH] =?UTF-8?q?=E3=83=9C=E3=82=BF=E3=83=B3=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E3=81=8C=E3=81=A7=E3=81=8D=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= =?UTF-8?q?=E3=80=81=E3=82=BF=E3=82=A4=E3=83=A0=E3=82=A2=E3=82=A6=E3=83=88?= =?UTF-8?q?=E6=A9=9F=E8=83=BD=E3=81=AE=E5=AE=9F=E8=A3=85=E3=80=81=E3=82=B9?= =?UTF-8?q?=E3=83=A9=E3=83=83=E3=82=B7=E3=83=A5=E3=82=B3=E3=83=9E=E3=83=B3?= =?UTF-8?q?=E3=83=89=E5=AF=BE=E5=BF=9C=E3=81=B8=E3=81=AE=E6=BA=96=E5=82=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dislocker.py | 232 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 230 insertions(+), 2 deletions(-) diff --git a/dislocker.py b/dislocker.py index 0c50952..695e58c 100644 --- a/dislocker.py +++ b/dislocker.py @@ -1,13 +1,17 @@ import json import discord +from discord import Interaction, TextStyle, app_commands +from discord.ui import TextInput, View, Modal import os import psycopg2 from psycopg2 import sql import hashlib import string import random -from datetime import datetime +from datetime import datetime, timedelta from openpyxl import Workbook +import threading +import time class DL(): def __init__(self): @@ -70,7 +74,10 @@ class DL(): print(find_pc_list_table) if find_pc_list_table[0][0] == False: cursor.execute("CREATE TABLE pc_list (pc_number INTEGER NOT NULL, using_user_id INTEGER, password_hash VARCHAR(32), PRIMARY KEY (pc_number), FOREIGN KEY (using_user_id) REFERENCES club_member(id))") - self.db.commit + for i in range(10): + print(i) + cursor.execute("INSERT INTO pc_list (pc_number) VALUES (%s)", (i + 1,)) + self.db.commit() cursor.execute("SELECT EXISTS (SELECT FROM information_schema.tables WHERE table_schema = 'public' AND table_name = 'pc_usage_history')") find_pc_usage_history_table = cursor.fetchall() @@ -91,6 +98,7 @@ class DL(): class Bot(discord.Client): + def password_generate(self, length): numbers = string.digits # (1) password = ''.join(random.choice(numbers) for _ in range(length)) # (2) @@ -370,10 +378,37 @@ class Bot(discord.Client): finally: cursor.close() return result + + + async def timeout_notify(self, **kwargs): + try: + pc_number = kwargs["pc_number"] + discord_display_name = kwargs["discord_display_name"] + + await self.get_channel(dislocker.server_config["bot"]["log_channel_id"]).send(f':negative_squared_cross_mark: {discord_display_name} さんのPC {pc_number} の使用登録はタイムアウトにより解除されました。') + result = {"result": "ok"} + + except Exception as error: + print("自動停止処理中にエラーが発生しました。\nエラー内容") + print(str(error.__class__.__name__)) + print(str(error.args)) + print(str(error)) + result = {"result": "error"} + + finally: + return result + async def on_ready(self): print("DiscordのBotが起動しました。") + async def on_interaction(self, interaction:discord.Interaction): + try: + if interaction.data["component_type"] == 2: + await self.on_button(interaction) + except KeyError: + pass + async def on_message(self, message): if message.author.bot: pass @@ -490,6 +525,29 @@ class Bot(discord.Client): else: await message.channel.send("# :warning: PCを登録できませんでした。\n構文が間違っています。\n-# /pcregister PC番号") + elif msg_split[0] == "/registerbutton": + pc_button_view = View(timeout=None) + for i in range(1, 11): + pc_register_button = discord.ui.Button(style=discord.ButtonStyle.primary, label=f"{i}", custom_id=f"pcregister_{i}") + pc_button_view.add_item(pc_register_button) + + await self.get_channel(dislocker.server_config["bot"]["config_public_channel_id"]).send(f'# :index_pointing_at_the_viewer: 使いたいPCの番号を選んでください!', view=pc_button_view) + + elif msg_split[0] == "/stopbutton": + stop_button_view = View(timeout=None) + stop_button = discord.ui.Button(style=discord.ButtonStyle.danger, label="PCの使用を停止", custom_id="stop") + stop_button_view.add_item(stop_button) + + await self.get_channel(dislocker.server_config["bot"]["config_public_channel_id"]).send(f'# :index_pointing_at_the_viewer: 使用を停止しますか?', view=stop_button_view) + + elif msg_split[0] == "/userbutton": + user_register_button_view = View(timeout=None) + user_register_button = discord.ui.Button(style=discord.ButtonStyle.green, label="ユーザー登録", custom_id="user_register") + user_register_button_view.add_item(user_register_button) + + await self.get_channel(dislocker.server_config["bot"]["config_public_channel_id"]).send(f'# :index_pointing_at_the_viewer: ユーザー登録はお済ですか?', view=user_register_button_view) + + elif message.channel.id == dislocker.server_config["bot"]["config_public_channel_id"]: msg_split = message.content.split() @@ -507,6 +565,174 @@ class Bot(discord.Client): else: await message.channel.send("# :skull_crossbones: 登録できませんでした。\n\n-# もしかして...\n-# 手動でメンバーを登録したいですか?\n-# もしそうなら、このチャンネルにはその権限がありません。\n-# そのチャンネルに移動してから、もう一度試してみてください!") + async def on_button(self, interaction: Interaction): + custom_id = interaction.data["custom_id"] + custom_id_split = custom_id.split("_") + print(custom_id, custom_id_split[0]) + + if custom_id_split[0] == "pcregister": + device_register_view = View(timeout=15) + pc_number = custom_id_split[1] + print(custom_id_split) + for i in range(1, 20): + device_register_button = discord.ui.Button(style=discord.ButtonStyle.primary, label=f"{i}", custom_id=f"deviceregister_{str(pc_number)}_{i}") + device_register_view.add_item(device_register_button) + + await interaction.response.send_message(f"# :keyboard: デバイス番号を選んでください!\n>>> # PC番号 | {str(pc_number)}", view=device_register_view, ephemeral=True) + + elif custom_id_split[0] == "deviceregister": + pc_number = custom_id_split[1] + device_number = custom_id_split[2] + reason_register_view = View(timeout=15) + reason_button = discord.ui.Button(style=discord.ButtonStyle.primary, label="使用目的を入力する", custom_id=f"reasonregister_{str(pc_number)}_{str(device_number)}") + reason_register_view.add_item(reason_button) + + await interaction.response.send_message(f"# :regional_indicator_q: 使用目的を書いてください!\n>>> # PC番号 | {str(pc_number)}\n# デバイス番号 | {str(device_number)}", view=reason_register_view, ephemeral=True) + + elif custom_id_split[0] == "reasonregister": + pc_number = custom_id_split[1] + device_number = custom_id_split[2] + reason_input_form = Reason(title="Dislocker | 登録", pc_number=str(pc_number), device_number=str(device_number)) + await interaction.response.send_modal(reason_input_form) + + elif custom_id_split[0] == "stop": + print("STOP running") + pc_stop = self.stop(user_id=interaction.user.id) + print(pc_stop) + stop_view = View(timeout=15) + if pc_stop["result"] == "unused": + await interaction.response.send_message("# :shaking_face: 使用されていないようです...", ephemeral=True) + elif pc_stop["result"] == "ok": + await interaction.response.send_message(f":white_check_mark: PC番号 {pc_stop["pc_number"]} の使用が終了されました。", ephemeral=True) + await self.get_channel(dislocker.server_config["bot"]["log_channel_id"]).send(f':negative_squared_cross_mark: {pc_stop["name"]} さんがPC {pc_stop["pc_number"]} の使用を終了しました。') + else: + await interaction.response.send_message("# :skull_crossbones: 停止できませんでした。\n内部エラーが発生しています。", ephemeral=True) + + elif custom_id_split[0] == "user" and custom_id_split[1] == "register": + print("User Register RUnning") + user_register = self.user_register(name=interaction.user.display_name, discord_user_name=interaction.user.name, discord_user_id=interaction.user.id) + if user_register["result"] == "ok": + await interaction.response.send_message(f"# :white_check_mark: ユーザー情報が登録されました。\n>>> ユーザー名:{interaction.user.display_name}", ephemeral=True) + elif user_register["result"] == "already_exists": + await interaction.response.send_message("# :no_entry: 登録できませんでした。\nもう登録されている可能性があります。", ephemeral=True) + else: + await interaction.response.send_message("# :no_entry: 登録できませんでした。\n内部エラーが発生しています。", ephemeral=True) + +class Monitor(): + def __init__(self) -> None: + pass + + def start(self, **kwargs): + self.serach_time = kwargs["search_time"] + self.allowable_time = kwargs["allowable_time"] + serach_thread = threading.Thread(target=self.search) + serach_thread.start() + + + + def search(self): + try: + while True: + cursor = dislocker.db.cursor() + cursor.execute("SELECT * FROM pc_list WHERE password_hash IS NOT NULL") + pc_list = cursor.fetchall() + print(pc_list) + print(len(pc_list)) + if pc_list: + if len(pc_list) == 1: + user_id = pc_list[0][1] + cursor.execute("SELECT * FROM pc_usage_history WHERE member_id= %s AND end_use_time IS NULL ORDER BY id DESC LIMIT 1", (user_id,)) + pc_usage = cursor.fetchall() + print(pc_usage) + start_time = pc_usage[0][4] + print(start_time) + print(type(start_time)) + current_time = datetime.now() + time_difference = current_time - start_time + if time_difference >= timedelta(seconds=self.allowable_time): + cursor.execute("SELECT * FROM club_member WHERE id = %s", (user_id,)) + user_info = cursor.fetchall() + stop = bot.stop(user_id=user_info[0][3]) + + bot.timeout_notify(pc_number=pc_list[0][0], discord_display_name=user_info[0][1]) + time.sleep(1) + + + elif len(pc_list) >= 2: + for i in pc_list: + print(i) + user_id = i[1] + cursor.execute("SELECT * FROM pc_usage_history WHERE member_id= %s AND end_use_time IS NULL ORDER BY id DESC LIMIT 1", (user_id,)) + pc_usage = cursor.fetchall() + print(pc_usage) + start_time = pc_usage[0][4] + print(start_time) + print(type(start_time)) + current_time = datetime.now() + time_difference = current_time - start_time + if time_difference >= timedelta(seconds=self.allowable_time): + cursor.execute("SELECT * FROM club_member WHERE id = %s", (user_id,)) + user_info = cursor.fetchall() + stop = bot.stop(user_id=user_info[0][3]) + + bot.timeout_notify(pc_number=i[0], discord_display_name=user_info[0][1]) + time.sleep(0.1) + + else: + result = {"result": "NONE"} + else: + result = {"result": "NONE"} + + cursor.close() + + print(result["result"]) + time.sleep(self.serach_time) + + except Exception as error: + print("自動停止処理中にエラーが発生しました。\nエラー内容") + print(str(error.__class__.__name__)) + print(str(error.args)) + print(str(error)) + result = {"result": "error"} + dislocker.db.rollback() + + finally: + cursor.close() + print(result["result"]) + return result + + + +class Reason(Modal): + def __init__(self, title: str, pc_number: str, device_number: str, timeout=15) -> None: + super().__init__(title=title, timeout=timeout) + print(pc_number) + print(device_number) + self.reason_input_form = TextInput(label="使用目的を入力してください", style=TextStyle.short, custom_id=f"register_{pc_number}_{device_number}") + self.add_item(self.reason_input_form) + + async def on_submit(self, interaction: Interaction) -> None: + custom_id = interaction.data["components"][0]["components"][0]["custom_id"] + print(custom_id) + custom_id_split = custom_id.split("_") + pc_number = custom_id_split[1] + device_number = custom_id_split[2] + register = bot.register(user_id=interaction.user.id, name=interaction.user.name, display_name=interaction.user.display_name, pc_number=pc_number, device_number=device_number, detail=self.reason_input_form.value) + print(register["result"]) + + if register["result"] == "ok": + await interaction.response.send_message(f":white_check_mark: 使用が開始されました。\n>>> # パスワード | {register["password"]}\n## PC番号 | {pc_number}\n## デバイス番号 | {device_number}\n## 使用目的 | {self.reason_input_form.value}", ephemeral=True) + await bot.get_channel(dislocker.server_config["bot"]["log_channel_id"]).send(f':white_check_mark: {register["name"]} さんがPC {pc_number} の使用を開始しました。') + elif register["result"] == "pc_already_in_use_by_you": + await interaction.response.send_message(f"# :exploding_head: あなたはPCをもう使用されているようです。\n使用状態を解除するには 終了ボタン で使用終了をお知らせください。\n>>> # PC番号 | {register["pc_number"]}\n# デバイス番号 | {register["device_number"]}\n# 使用開始時刻 | {register["start_time"]}\n# 使用目的 | {register["detail"]}", ephemeral=True) + elif register["result"] == "pc_already_in_use_by_other": + await interaction.response.send_message(f"# :man_gesturing_no: そのPCは他のメンバーによって使用されています。\n別のPC番号を指定して、再度お試しください。", ephemeral=True) + elif register["result"] == "user_data_not_found": + await interaction.response.send_message("# :dizzy_face: ユーザーとして登録されていないようです。\n最初にサーバーで登録を行ってください。", ephemeral=True) + else: + await interaction.response.send_message("# :skull_crossbones: 登録できませんでした。\n内部エラーが発生しています。", ephemeral=True) + + dislocker = DL() if dislocker.init_result == "ok": @@ -514,6 +740,8 @@ if dislocker.init_result == "ok": intents = discord.Intents.default() intents.message_content = True bot = Bot(intents=intents) + monitor = Monitor() + monitor.start(search_time=10, allowable_time=30) bot.run(dislocker.server_config['bot']['token']) else: pass \ No newline at end of file