diff --git a/README.md b/README.md
index 83e3848..c505bf6 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@ Star Yuuki(pYthon) BOT - Yuuki
==================
![Version](https://img.shields.io/badge/v6.5.3-OpenSource-FF0033.svg) ![Series](https://img.shields.io/badge/syb-Series-7700FF.svg) ![License](https://img.shields.io/badge/license-MPL--2.0-FF6600.svg) ![Python](https://img.shields.io/badge/python-3.x-0066FF.svg) ![Platform](https://img.shields.io/badge/base_on-LINE-00DD00.svg)
-![Scrutinizer-CI_Build](https://scrutinizer-ci.com/g/star-inc/star_yuuki_bot/badges/build.png?b=master) ![Scrutinizer-CI_Quality](https://scrutinizer-ci.com/g/star-inc/star_yuuki_bot/badges/quality-score.png?b=master) ![Code-Inspector_Score](https://www.code-inspector.com/project/3632/score/svg) ![Code-Inspector_Score](https://www.code-inspector.com/project/3632/status/svg)
+[![Scrutinizer-CI_Build](https://scrutinizer-ci.com/g/star-inc/star_yuuki_bot/badges/build.png?b=master) ![Scrutinizer-CI_Quality](https://scrutinizer-ci.com/g/star-inc/star_yuuki_bot/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/star-inc/star_yuuki_bot/) [![Code-Inspector_Score](https://www.code-inspector.com/project/3632/score/svg) ![Code-Inspector_Score](https://www.code-inspector.com/project/3632/status/svg)](https://frontend.code-inspector.com/public/project/3632/star_yuuki_bot/dashboard)
A Python BOT for LINE Group Protection.
![ICON](logo.png)
diff --git a/libs/__init__.py b/libs/__init__.py
index 365e21f..5f7ce8c 100644
--- a/libs/__init__.py
+++ b/libs/__init__.py
@@ -6,7 +6,7 @@ This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
"""
-from .yuuki import Yuuki
from .config import Yuuki_Config
+from .yuuki import Yuuki
__all__ = ['connection', 'data', 'data_mds', 'thread_control', 'Yuuki', 'Yuuki_Config']
diff --git a/libs/config.py b/libs/config.py
index b419019..5160bc0 100644
--- a/libs/config.py
+++ b/libs/config.py
@@ -6,11 +6,22 @@ This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
"""
+import os
+
import yaml
class Yuuki_Config:
- """ Configure Yuuki """
+ """
+
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ !! DO NOT TOUCH DEFAULT SETTINGS !!
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+ Please config the value you want to set though `config.yaml`.
+ It will overwrite these settings.
+
+ """
connectInfo = {
"Host": "",
@@ -26,7 +37,7 @@ class Yuuki_Config:
systemConfig = {
"name": "Yuuki",
- "version": "v6.5.3-alpha",
+ "version": "v6.5.3-alpha_RC1",
"version_check": True,
"project_url": "https://tinyurl.com/syb-yuuki",
"man_page": "https://tinyurl.com/yuuki-manual",
@@ -36,6 +47,7 @@ class Yuuki_Config:
"Seq": 0,
"Admin": [],
"Advanced": False,
+ "WebAdmin": False, # Advanced Mode Required
"SecurityService": False,
"Hour_KickLimit": 10,
"Hour_CancelLimit": 10,
@@ -45,11 +57,13 @@ class Yuuki_Config:
}
def __init__(self, config_path="config.yaml"):
+ assert os.path.isfile(config_path), "The configure file, `config.yaml` was not found."
with open(config_path, "r") as configfile:
self.config = yaml.load(configfile, Loader=yaml.FullLoader)
self._yuuki_config()
def _yuuki_config(self):
+ assert self.config is not None, "Invalid configure file"
if "Yuuki" in self.config:
for key in self.config["Yuuki"]:
if key in self.systemConfig:
@@ -67,7 +81,7 @@ class Yuuki_Config:
if "Account" in self.config.get("LINE"):
for key in self.config["LINE"]["Account"]:
if key in ["X-Line-Application", "User-Agent"]:
- self.config["LINE"]["Account"][key] = self.config["LINE"]["Account"][key].replace("\\t","\t")
+ self.config["LINE"]["Account"][key] = self.config["LINE"]["Account"][key].replace("\\t", "\t")
if key in self.connectHeader:
self.connectHeader[key] = self.config["LINE"]["Account"][key]
diff --git a/libs/connection.py b/libs/connection.py
index 809b8ac..e13a459 100644
--- a/libs/connection.py
+++ b/libs/connection.py
@@ -11,12 +11,11 @@ from thrift.transport import THttpClient
from yuuki_core.TalkService import Client
-""" NC HightSpeed Lib """
+# NC HighSpeed Library
try:
from thrift.protocol import fastbinary
except ImportError:
print("[No fast_binary using]")
-##########################################
class Yuuki_Connect:
diff --git a/libs/data.py b/libs/data.py
index 8884140..de986be 100644
--- a/libs/data.py
+++ b/libs/data.py
@@ -11,16 +11,15 @@ import os
import random
import time
-import requests
+from tornado.httpclient import HTTPClient, HTTPRequest
from yuuki_core.ttypes import OpType
-from .data_mds import listen as msd_listen
+from .data_mds import PythonMDS
from .thread_control import Yuuki_Multiprocess
from .thread_control import Yuuki_Thread
class Yuuki_Data:
-
# Data Struct Define
Data = {}
@@ -80,49 +79,42 @@ class Yuuki_Data:
if not os.path.isdir(self.DataPath):
os.mkdir(self.DataPath)
- for Type in self.DataType:
- name = self.DataPath + self.DataName.format(Type)
+ for data_type in self.DataType:
+ name = self.DataPath + self.DataName.format(data_type)
+
+ test_result = 0
if not os.path.isfile(name):
with open(name, "w") as f:
f.write("")
- Type = 0
else:
with open(name, "r") as f:
try:
json.load(f)
- Type = 0
except ValueError:
- Type = 1
- assert Type == 0, "{}\nJson Test Error".format(name)
+ test_result = 1
+ assert test_result == 0, "{}\nJson Test Error".format(name)
- for Type in self.DataType:
- name = self.DataPath + self.DataName.format(Type)
with open(name, "r+") as f:
text = f.read()
if text != "":
- self.Data[Type] = json.loads(text)
+ self.Data[data_type] = json.loads(text)
else:
- self.Data[Type] = self.DataType[Type]
- f.write(json.dumps(self.Data[Type]))
+ self.Data[data_type] = self.DataType[data_type]
+ f.write(json.dumps(self.Data[data_type]))
+
return self._MDS_Initialize()
def _MDS_Initialize(self):
if self.threading:
+ mds = PythonMDS()
self.mdsHost = "http://localhost:2019/"
self.mdsCode = "{}.{}".format(random.random(), time.time())
- self.MdsThreadControl.add(msd_listen, (self.mdsCode,))
+ self.MdsThreadControl.add(mds.mds_listen, (self.mdsCode,))
# MDS Sync
time.sleep(1)
- requests.post(
- url=self.mdsHost,
- json={
- "code": self.mdsCode,
- "do": "SYC",
- "path": self.Data
- }
- )
+ self.mdsShake("SYC", self.Data)
return self._Log_Initialize()
def _Log_Initialize(self):
@@ -144,22 +136,28 @@ class Yuuki_Data:
Function(*args)
def mdsShake(self, do, path, data=None):
+ status = 0
if self.threading:
- mds = requests.post(
+ http_client = HTTPClient()
+ http_request = HTTPRequest(
url=self.mdsHost,
- json={
+ method="POST",
+ body=json.dumps({
"code": self.mdsCode,
"do": do,
"path": path,
"data": data
- }
+ })
)
- over = mds.json()
- assert_result = "mds - ERROR\n{} on {}".format(do, path)
- assert over["status"] == 200, assert_result
+ response = http_client.fetch(http_request)
+ over = json.loads(response.body)
+ if "status" in over:
+ status = over["status"]
+ assert_result = "mds - ERROR {}\n{} on {}".format(status, do, path)
+ assert status == 200, assert_result
return over
else:
- status = {"status": 0}
+ status = {"status": status}
return json.dumps(status)
def _local_query(self, query_data):
diff --git a/libs/data_mds.py b/libs/data_mds.py
index 65107a1..df6708f 100644
--- a/libs/data_mds.py
+++ b/libs/data_mds.py
@@ -10,54 +10,67 @@
# Initializing
import json
+import types
+from abc import ABC
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop
from tornado.web import Application, RequestHandler
-switch_data = {}
+# Works
+_work = {}
auth_code = 0
-# Functions
-def mds_exit(data):
- if data:
- exit(0)
+class IndexHandler(RequestHandler, ABC):
+ def get(self):
+ self.write('''
+ Python MDS Server
+ To switch data in multiprocessing.
+ (c)2020 Star Inc.
+ ''')
+
+ def post(self):
+ global auth_code
+ req_body = self.request.body
+ req_str = req_body.decode('utf8')
+ req_res = json.loads(req_str)
+ if req_res.get("code") == auth_code:
+ result = _work[req_res.get("do")](
+ {
+ "path": req_res.get("path"),
+ "data": req_res.get("data")
+ }
+ )
+ else:
+ result = {"status": 401}
+ if isinstance(result, types.GeneratorType):
+ result = {"status": 200}
+ self.write(json.dumps(result))
-def update(data):
- global switch_data
- # noinspection PyBroadException
- try:
- if type(data["path"]) is list:
- over = query({"path": data["path"]})
- over.get("data").update(data["data"])
- return {"status": 200}
- return {"status": 400}
- except:
- return {"status": 500}
+class PythonMDS:
+ switch_data = {}
+ # Main
+ app = Application([
+ ('/', IndexHandler)
+ ])
+ server = HTTPServer(app)
+ async_lock = IOLoop.current()
-def delete(data):
- global switch_data
- # noinspection PyBroadException
- try:
- if type(data["path"]) is list:
- over = query({"path": data["path"]})
- over.get("data").pop(data["data"])
- return {"status": 200}
- return {"status": 400}
- except:
- return {"status": 500}
+ def __init__(self):
+ _work["UPT"] = self._update
+ _work["DEL"] = self._delete
+ _work["GET"] = self._query
+ _work["SYC"] = self._sync
+ _work["YLD"] = self._yuuki_limit_decrease
+ _work["EXT"] = self._shutdown
-
-def query(data):
- global switch_data
- query_data = data["path"]
- # noinspection PyBroadException
- try:
- if type(switch_data) is dict and type(query_data) is list:
- result = switch_data
+ def _query(self, data):
+ query_data = data["path"]
+ if type(self.switch_data) is dict and type(query_data) is list:
+ result = self.switch_data
query_len = len(query_data) - 1
for count, key in enumerate(query_data):
if key in result:
@@ -72,73 +85,39 @@ def query(data):
return {"status": 200, "data": result}
return {"status": 400}
- except:
- return {"status": 500}
+ def _update(self, data):
+ if type(data["path"]) is list:
+ over = self._query({"path": data["path"]})
+ over.get("data").update(data["data"])
+ return {"status": 200}
+ return {"status": 400}
-def sync(data):
- global switch_data
- # noinspection PyBroadException
- try:
- switch_data = data["path"]
+ def _delete(self, data):
+ if type(data["path"]) is list:
+ over = self._query({"path": data["path"]})
+ over.get("data").pop(data["data"])
+ return {"status": 200}
+ return {"status": 400}
+
+ def _sync(self, data):
+ self.switch_data = data["path"]
return {"status": 200}
- except:
- return {"status": 500}
-
-def yuukiLimitDecrease(data):
- global switch_data
- # noinspection PyBroadException
- try:
- switch_data["LimitInfo"][data["path"]][data["userId"]] -= 1
+ def _yuuki_limit_decrease(self, data):
+ self.switch_data["LimitInfo"][data["path"]][data["userId"]] -= 1
return {"status": 200}
- except:
- return {"status": 500}
+ def _shutdown(self, data):
+ if data:
+ pass
+ self.server.stop()
+ yield True
+ self.async_lock.stop()
+ self.async_lock.close()
-# Works
-_work = {
- "EXT": mds_exit,
- "UPT": update,
- "DEL": delete,
- "GET": query,
- "SYC": sync,
- "YLD": yuukiLimitDecrease
-}
-
-
-class IndexHandler(RequestHandler):
- def get(self):
- self.write('''
- Python MDS Server
- To switch data in multiprocessing.
- (c)2019 Star Inc.
- ''')
-
- def post(self):
+ def mds_listen(self, code):
global auth_code
- req_body = self.request.body
- req_str = req_body.decode('utf8')
- req_res = json.loads(req_str)
- if req_res.get("code") == auth_code:
- result = _work[req_res.get("do")](
- {
- "path":req_res.get("path"),
- "data":req_res.get("data")
- }
- )
- else:
- result = {"status": 401}
- if not result:
- result = {"status": 500}
- self.write(json.dumps(result))
-
-
-# Main
-def listen(code):
- global auth_code
- auth_code = code
- app = Application([('/', IndexHandler)])
- server = HTTPServer(app)
- server.listen(2019)
- IOLoop.current().start()
+ auth_code = code
+ self.server.listen(2019)
+ self.async_lock.start()
diff --git a/libs/events/__init__.py b/libs/events/__init__.py
index f7574ec..8787d02 100644
--- a/libs/events/__init__.py
+++ b/libs/events/__init__.py
@@ -7,8 +7,9 @@ License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
"""
+from .callback import Yuuki_Callback
from .command import Yuuki_Command
from .join_group import Yuuki_JoinGroup
from .security import Yuuki_Security
-__all__ = ["Yuuki_Command", "Yuuki_JoinGroup", "Yuuki_Security"]
+__all__ = ["Yuuki_Command", "Yuuki_JoinGroup", "Yuuki_Security", "Yuuki_Callback"]
diff --git a/libs/events/callback.py b/libs/events/callback.py
new file mode 100644
index 0000000..4c89a70
--- /dev/null
+++ b/libs/events/callback.py
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+"""
+Yuuki_Libs
+(c) 2020 Star Inc.
+This Source Code Form is subject to the terms of the Mozilla Public
+License, v. 2.0. If a copy of the MPL was not distributed with this
+file, You can obtain one at http://mozilla.org/MPL/2.0/.
+"""
+import time
+
+from yuuki_core.ttypes import ContentType
+
+from ..tools import Yuuki_StaticTools, Yuuki_DynamicTools
+
+
+class Yuuki_Callback:
+ def __init__(self, Yuuki):
+ """
+ Event Type:
+ SEND_MESSAGE(25)
+ """
+ self.Yuuki = Yuuki
+
+ self.Yuuki_StaticTools = Yuuki_StaticTools()
+ self.Yuuki_DynamicTools = Yuuki_DynamicTools(self.Yuuki)
+
+ def _shutdown(self, ncMessage):
+ self.Yuuki.Thread_Control.add(self._shutdown_reply, (ncMessage,))
+ self.Yuuki.exit()
+
+ def _shutdown_reply(self, ncMessage):
+ time.sleep(1)
+ self.Yuuki_DynamicTools.sendText(
+ ncMessage.message.to,
+ self.Yuuki.get_text("Exit.")
+ )
+
+ def _text(self, ncMessage):
+ actions = {
+ '[Yuuki] Remote Shutdown': self._shutdown,
+ }
+ if ncMessage.message.text in actions:
+ actions[ncMessage.message.text](ncMessage)
+
+ def action(self, ncMessage):
+ if ncMessage.message.contentType == ContentType.NONE:
+ self._text(ncMessage)
diff --git a/libs/events/command.py b/libs/events/command.py
index 464f1cf..9a47787 100644
--- a/libs/events/command.py
+++ b/libs/events/command.py
@@ -275,9 +275,7 @@ class Yuuki_Command:
if ncMessage.message.toType == MIDType.GROUP:
GroupInfo = self.Yuuki_DynamicTools.getClient(
self.Yuuki.MyMID).getGroup(ncMessage.message.to)
- GroupPrivilege = self.Yuuki.Admin + \
- [self.Yuuki_StaticTools.sybGetGroupCreator(
- GroupInfo).mid]
+ GroupPrivilege = self.Yuuki.Admin + [self.Yuuki_StaticTools.sybGetGroupCreator(GroupInfo).mid]
if ncMessage.message.from_ in GroupPrivilege:
self.Yuuki_DynamicTools.sendText(self.Yuuki_StaticTools.sendToWho(
ncMessage), self.Yuuki.get_text("Bye Bye"))
@@ -296,11 +294,13 @@ class Yuuki_Command:
def _Exit(self, ncMessage):
if ncMessage.message.from_ in self.Yuuki.Admin:
- self.Yuuki_DynamicTools.sendText(self.Yuuki_StaticTools.sendToWho(
- ncMessage), self.Yuuki.get_text("Exit."))
+ self.Yuuki_DynamicTools.sendText(
+ self.Yuuki_StaticTools.sendToWho(ncMessage),
+ self.Yuuki.get_text("Exit.")
+ )
self.Yuuki.exit()
- def _Com(self, ncMessage):
+ def _SystemCall(self, ncMessage):
msgSep = ncMessage.message.text.split(" ")
if ncMessage.message.from_ in self.Yuuki.Admin:
# noinspection PyBroadException
@@ -330,7 +330,7 @@ class Yuuki_Command:
'GroupBackup': self._GroupBackup,
'Quit': self._Quit,
'Exit': self._Exit,
- 'Com': self._Com,
+ 'SystemCall': self._SystemCall,
}
if Yuuki_Name == msgSep[0] and msgSep[1] in actions:
actions[msgSep[1]](ncMessage)
diff --git a/libs/events/security.py b/libs/events/security.py
index 51991ac..4ea461e 100644
--- a/libs/events/security.py
+++ b/libs/events/security.py
@@ -7,10 +7,10 @@ License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
"""
-from ..tools import Yuuki_StaticTools, Yuuki_DynamicTools
-
from yuuki_core.ttypes import OpType
+from ..tools import Yuuki_StaticTools, Yuuki_DynamicTools
+
class Yuuki_Security:
def __init__(self, Yuuki):
@@ -268,11 +268,11 @@ class Yuuki_Security:
SecurityInfo = self.Yuuki_StaticTools.securityForWhere(ncMessage)
GroupInfo = self.Yuuki_DynamicTools.getClient(self.Yuuki.MyMID).getGroup(SecurityInfo["GroupID"])
- SecurityInfo["GroupPrivilege"] = self.Yuuki.Admin +\
- [self.Yuuki_StaticTools.sybGetGroupCreator(GroupInfo).mid] +\
- self.Yuuki.data.getGroup(GroupInfo.id)["Ext_Admin"]
+ SecurityInfo["GroupPrivilege"] = self.Yuuki.Admin + \
+ [self.Yuuki_StaticTools.sybGetGroupCreator(GroupInfo).mid] + \
+ self.Yuuki.data.getGroup(GroupInfo.id)["Ext_Admin"]
- if SecurityInfo["Action"] in SecurityInfo["GroupPrivilege"] or\
+ if SecurityInfo["Action"] in SecurityInfo["GroupPrivilege"] or \
SecurityInfo["Another"] in SecurityInfo["GroupPrivilege"]:
if ncMessage.type != OpType.NOTIFIED_KICKOUT_FROM_GROUP:
return
diff --git a/libs/poll.py b/libs/poll.py
index 0eaddf4..967317e 100644
--- a/libs/poll.py
+++ b/libs/poll.py
@@ -6,14 +6,13 @@ This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
"""
-
-import time
import socket
-import requests
+import time
+
+from yuuki_core.ttypes import Operation
from .tools import Yuuki_StaticTools, Yuuki_DynamicTools
-from yuuki_core.ttypes import Operation
class Yuuki_Poll:
Power = True
@@ -71,14 +70,17 @@ class Yuuki_Poll:
if ncMessage.revision != self.Yuuki.revision:
self.Yuuki.revision = self.Yuuki.client.getLastOpRevision()
for Root in self.Yuuki.Admin:
- self.Yuuki.sendText(Root, "Star Yuuki BOT - Something was wrong...\nError:\n%s\n%s\n%s\n\n%s" %
- (err1, err2, err3, ErrorInfo))
+ self.Yuuki_DynamicTools.sendText(
+ Root,
+ "Star Yuuki BOT - Something was wrong...\nError:\n%s\n%s\n%s\n\n%s" %
+ (err1, err2, err3, ErrorInfo)
+ )
except:
print("Star Yuuki BOT - Damage!\nError:\n%s\n%s\n%s\n\n%s" % (err1, err2, err3, ErrorInfo))
self.Yuuki.exit()
def init(self):
- self.Yuuki.data.updateData(["Global", "self.Power"], self.Power)
+ self.Yuuki.data.updateData(["Global", "Power"], self.Power)
if "LastResetLimitTime" not in self.Yuuki.data.getData(["Global"]):
self.Yuuki.data.updateData(["Global", "LastResetLimitTime"], None)
@@ -87,10 +89,10 @@ class Yuuki_Poll:
# noinspection PyBroadException
try:
self._action()
- self.Power = self.Yuuki.data.syncData()
-
- except requests.exceptions.ConnectionError:
- self.Power = False
+ try:
+ self.Power = self.Yuuki.data.syncData()
+ except ConnectionRefusedError:
+ self.Power = False
except SystemExit:
self.Power = False
@@ -102,4 +104,4 @@ class Yuuki_Poll:
pass
except:
- self._exception()
\ No newline at end of file
+ self._exception()
diff --git a/libs/thread_control.py b/libs/thread_control.py
index 489efc7..35ddff9 100644
--- a/libs/thread_control.py
+++ b/libs/thread_control.py
@@ -15,8 +15,8 @@ class Yuuki_Thread:
self.lock = threading.Lock()
@staticmethod
- def add(Yuuki_Func, args=()):
- added_thread = threading.Thread(name=Yuuki_Func.__name__, target=Yuuki_Func, args=args)
+ def add(function, args=()):
+ added_thread = threading.Thread(name=function.__name__, target=function, args=args)
added_thread.start()
@staticmethod
@@ -27,7 +27,13 @@ class Yuuki_Thread:
class Yuuki_Multiprocess:
- @staticmethod
- def add(Yuuki_Func, args=()):
- added_multiprocess = multiprocessing.Process(name=Yuuki_Func.__name__, target=Yuuki_Func, args=args)
+ multiprocess_list = {}
+
+ def add(self, function, args=()):
+ added_multiprocess = multiprocessing.Process(name=function.__name__, target=function, args=args)
+ self.multiprocess_list[function.__name__] = added_multiprocess
added_multiprocess.start()
+
+ def stop(self, function_name):
+ assert function_name in self.multiprocess_list
+ self.multiprocess_list[function_name].terminate()
diff --git a/libs/tools.py b/libs/tools.py
index 63f002d..4f2bb20 100644
--- a/libs/tools.py
+++ b/libs/tools.py
@@ -6,15 +6,14 @@ This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
"""
-
-import os
-import sys
import json
import ntpath
+import os
import random
-import requests
+import sys
import traceback
+import requests
from yuuki_core.ttypes import OpType, MIDType, ContentType, Group, Message
@@ -62,9 +61,9 @@ class Yuuki_StaticTools:
:param ncMessage: Operation
:return: tuple
"""
- if ncMessage.type == OpType.NOTIFIED_UPDATE_GROUP or\
- ncMessage.type == OpType.NOTIFIED_INVITE_INTO_GROUP or\
- ncMessage.type == OpType.NOTIFIED_ACCEPT_GROUP_INVITATION or\
+ if ncMessage.type == OpType.NOTIFIED_UPDATE_GROUP or \
+ ncMessage.type == OpType.NOTIFIED_INVITE_INTO_GROUP or \
+ ncMessage.type == OpType.NOTIFIED_ACCEPT_GROUP_INVITATION or \
ncMessage.type == OpType.NOTIFIED_KICKOUT_FROM_GROUP:
return {
"GroupID": ncMessage.param1,
@@ -347,7 +346,6 @@ class Yuuki_DynamicTools:
'params': json.dumps(params)
}
url = self.Yuuki.LINE_Media_server + '/talk/m/upload.nhn'
- r = requests.post(
- url, headers=self.Yuuki.connectHeader, data=data, files=files)
+ r = requests.post(url, headers=self.Yuuki.connectHeader, data=data, files=files)
if r.status_code != 201:
self.sendText(send_to, "Error!")
diff --git a/libs/webadmin/api.py b/libs/webadmin/api.py
index dfcea5e..b092d2f 100644
--- a/libs/webadmin/api.py
+++ b/libs/webadmin/api.py
@@ -7,10 +7,13 @@ License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
"""
from .reader import Yuuki_WebDataReader
+from ..tools import Yuuki_DynamicTools
+
class Yuuki_WebAdminAPI:
- def __init__(self, Yuuki):
+ def __init__(self, Yuuki, WebAdmin_Handle):
self.Yuuki = Yuuki
+ self.WebAdmin = WebAdmin_Handle
self.YuukiData = self.Yuuki.data
self.Yuuki_DataHandle = Yuuki_WebDataReader(self.YuukiData)
self.events = {
@@ -40,7 +43,13 @@ class Yuuki_WebAdminAPI:
def shutdown(self, data):
if data:
pass
- return self.Yuuki.exit()
+ return Yuuki_DynamicTools(self.Yuuki).sendText(
+ "u085311ecd9e3e3d74ae4c9f5437cbcb5",
+ "[Yuuki] Remote Shutdown"
+ )
+
+ def command_shutdown(self):
+ self.WebAdmin.wa_shutdown()
@staticmethod
def nothing(data):
diff --git a/libs/webadmin/server.py b/libs/webadmin/server.py
index b44eb65..4fed6a7 100644
--- a/libs/webadmin/server.py
+++ b/libs/webadmin/server.py
@@ -23,6 +23,7 @@ Yuuki_APIHandle = None
passports = []
password = str(hash(random.random()))
+shutdown_password = str(hash(random.random()))
class Yuuki_WebAdmin:
@@ -32,7 +33,7 @@ class Yuuki_WebAdmin:
def __init__(self, Yuuki):
global Yuuki_Handle, Yuuki_APIHandle
Yuuki_Handle = Yuuki
- Yuuki_APIHandle = Yuuki_WebAdminAPI(Yuuki_Handle)
+ Yuuki_APIHandle = Yuuki_WebAdminAPI(Yuuki_Handle, self)
@staticmethod
@wa_app.route("/")
@@ -172,21 +173,34 @@ class Yuuki_WebAdmin:
result = {"status": 401}
return Response(json.dumps(result), mimetype='application/json')
+ @staticmethod
+ @wa_app.route("/api/shutdown")
+ @wa_app.route("/api/shutdown/")
+ def shutdown(code=None):
+ if code == shutdown_password:
+ Yuuki_APIHandle.command_shutdown()
+ return "200"
+ return "401"
+
@staticmethod
@wa_app.route("/api/i")
def i():
return Yuuki_Handle.YuukiConfigs["name"]
+ @staticmethod
+ def set_shutdown_password(code):
+ global shutdown_password
+ shutdown_password = code
+
@staticmethod
def set_password(code):
global password
password = code
- def start(self, admin_password):
- self.set_password(admin_password)
+ def wa_shutdown(self):
+ self.http_server.stop()
+ self.http_server.close()
+
+ def wa_listen(self):
self.http_server = WSGIServer(('', 2020), wa_app)
self.http_server.serve_forever()
-
- def stop(self):
- self.http_server.close()
- self.http_server.stop()
diff --git a/libs/webadmin/templates/manage/events.html b/libs/webadmin/templates/manage/events.html
index 2bb3a3b..7c1a5b5 100644
--- a/libs/webadmin/templates/manage/events.html
+++ b/libs/webadmin/templates/manage/events.html
@@ -9,29 +9,29 @@
{{ bootstrap.load_css() }}
-
+
Star Yuuki BOT - WebAdmin
- {% from 'bootstrap/nav.html' import render_nav_item %}
+{% from 'bootstrap/nav.html' import render_nav_item %}
-
+
-
-
-
+
+
+
-
- {{ bootstrap.load_js() }}
-
-
+
+{{ bootstrap.load_js() }}
+
+