mirror of
https://github.com/studio-neptune/yuuki.git
synced 2024-09-20 08:25:56 +08:00
Merge pull request #21 from star-inc/rolling
v6.5.3-alpha_RC1 from Rolling
This commit is contained in:
commit
107ae56f88
|
@ -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)
|
||||
|
|
|
@ -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']
|
||||
|
|
|
@ -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]
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
58
libs/data.py
58
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):
|
||||
|
|
173
libs/data_mds.py
173
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('''
|
||||
<b>Python MDS Server</b><br>
|
||||
To switch data in multiprocessing.<hr>
|
||||
(c)2020 <a href="https://starinc.xyz">Star Inc.</a>
|
||||
''')
|
||||
|
||||
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('''
|
||||
<b>Python MDS Server</b><br>
|
||||
To switch data in multiprocessing.<hr>
|
||||
(c)2019 <a href="https://starinc.xyz">Star Inc.</a>
|
||||
''')
|
||||
|
||||
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()
|
||||
|
|
|
@ -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"]
|
||||
|
|
47
libs/events/callback.py
Normal file
47
libs/events/callback.py
Normal file
|
@ -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)
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
26
libs/poll.py
26
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()
|
||||
self._exception()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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!")
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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/<code>")
|
||||
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()
|
||||
|
|
|
@ -9,29 +9,29 @@
|
|||
<!-- Bootstrap CSS -->
|
||||
{{ bootstrap.load_css() }}
|
||||
<link rel="stylesheet" href="https://unpkg.com/lookforward@0.1.1/css/lookforward.min.css">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}" />
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}"/>
|
||||
|
||||
<title>Star Yuuki BOT - WebAdmin</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
{% from 'bootstrap/nav.html' import render_nav_item %}
|
||||
{% from 'bootstrap/nav.html' import render_nav_item %}
|
||||
|
||||
<div id="header"></div>
|
||||
<div id="header"></div>
|
||||
|
||||
<main role="main" class="container">
|
||||
<div class="my-3 p-3 bg-white rounded shadow-sm">
|
||||
<div id="events">
|
||||
<p class="pt-3">Loading...</p>
|
||||
</div>
|
||||
<main role="main" class="container">
|
||||
<div class="my-3 p-3 bg-white rounded shadow-sm">
|
||||
<div id="events">
|
||||
<p class="pt-3">Loading...</p>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- Optional JavaScript -->
|
||||
{{ bootstrap.load_js() }}
|
||||
<script src="{{ url_for('static', filename='js/header.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/events.js') }}"></script>
|
||||
<!-- Optional JavaScript -->
|
||||
{{ bootstrap.load_js() }}
|
||||
<script src="{{ url_for('static', filename='js/header.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/events.js') }}"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -9,31 +9,31 @@
|
|||
<!-- Bootstrap CSS -->
|
||||
{{ bootstrap.load_css() }}
|
||||
<link rel="stylesheet" href="https://unpkg.com/lookforward@0.1.1/css/lookforward.min.css">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}" />
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}"/>
|
||||
|
||||
<title>Star Yuuki BOT - WebAdmin</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
{% from 'bootstrap/nav.html' import render_nav_item %}
|
||||
{% from 'bootstrap/nav.html' import render_nav_item %}
|
||||
|
||||
<div id="header"></div>
|
||||
<div id="header"></div>
|
||||
|
||||
<main role="main" class="container">
|
||||
<div class="my-3 p-3 bg-white rounded shadow-sm">
|
||||
<h6 class="border-bottom border-gray pb-2 mb-0">Groups</h6>
|
||||
<div id="groups">
|
||||
<p class="pt-3">Loading...</p>
|
||||
</div>
|
||||
<main role="main" class="container">
|
||||
<div class="my-3 p-3 bg-white rounded shadow-sm">
|
||||
<h6 class="border-bottom border-gray pb-2 mb-0">Groups</h6>
|
||||
<div id="groups">
|
||||
<p class="pt-3">Loading...</p>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- Optional JavaScript -->
|
||||
{{ bootstrap.load_js() }}
|
||||
<script>var object_server="{{ LINE_Media_server }}";</script>
|
||||
<script src="{{ url_for('static', filename='js/header.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/groups.js') }}"></script>
|
||||
<!-- Optional JavaScript -->
|
||||
{{ bootstrap.load_js() }}
|
||||
<script>var object_server="{{ LINE_Media_server }}";</script>
|
||||
<script src="{{ url_for('static', filename='js/header.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/groups.js') }}"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -9,30 +9,30 @@
|
|||
<!-- Bootstrap CSS -->
|
||||
{{ bootstrap.load_css() }}
|
||||
<link rel="stylesheet" href="https://unpkg.com/lookforward@0.1.1/css/lookforward.min.css">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}" />
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}"/>
|
||||
|
||||
<title>Star Yuuki BOT - WebAdmin</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
{% from 'bootstrap/nav.html' import render_nav_item %}
|
||||
{% from 'bootstrap/nav.html' import render_nav_item %}
|
||||
|
||||
<div id="header"></div>
|
||||
<div id="header"></div>
|
||||
|
||||
<main role="main" class="container">
|
||||
<div class="my-3 p-3 bg-white rounded shadow-sm">
|
||||
<h6 class="border-bottom border-gray pb-2 mb-0">Helpers</h6>
|
||||
<div id="helpers">
|
||||
<p class="pt-3">Loading...</p>
|
||||
</div>
|
||||
<main role="main" class="container">
|
||||
<div class="my-3 p-3 bg-white rounded shadow-sm">
|
||||
<h6 class="border-bottom border-gray pb-2 mb-0">Helpers</h6>
|
||||
<div id="helpers">
|
||||
<p class="pt-3">Loading...</p>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- Optional JavaScript -->
|
||||
{{ bootstrap.load_js() }}
|
||||
<script src="{{ url_for('static', filename='js/header.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/helpers.js') }}"></script>
|
||||
<!-- Optional JavaScript -->
|
||||
{{ bootstrap.load_js() }}
|
||||
<script src="{{ url_for('static', filename='js/header.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/helpers.js') }}"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -9,83 +9,83 @@
|
|||
<!-- Bootstrap CSS -->
|
||||
{{ bootstrap.load_css() }}
|
||||
<link rel="stylesheet" href="https://unpkg.com/lookforward@0.1.1/css/lookforward.min.css">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}" />
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}"/>
|
||||
|
||||
<title>Star Yuuki BOT - WebAdmin</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
{% from 'bootstrap/nav.html' import render_nav_item %}
|
||||
{% from 'bootstrap/nav.html' import render_nav_item %}
|
||||
|
||||
<div id="header"></div>
|
||||
<div id="header"></div>
|
||||
|
||||
<main role="main" class="container">
|
||||
<div class="d-flex align-items-center p-3 my-3 text-white-50 bg-purple rounded shadow-sm">
|
||||
<img class="mr-3" src="{{ LINE_Media_server}}/{{pictureStatus }}" alt="" width="48" height="48">
|
||||
<div class="lh-100">
|
||||
<h6 class="mb-0 text-white lh-100">{{ profileName }}</h6>
|
||||
<small>on {{ name }} {{ version }}</small>
|
||||
</div>
|
||||
<main role="main" class="container">
|
||||
<div class="d-flex align-items-center p-3 my-3 text-white-50 bg-purple rounded shadow-sm">
|
||||
<img class="mr-3" src="{{ LINE_Media_server}}/{{pictureStatus }}" alt="" width="48" height="48">
|
||||
<div class="lh-100">
|
||||
<h6 class="mb-0 text-white lh-100">{{ profileName }}</h6>
|
||||
<small>on {{ name }} {{ version }}</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="my-3 p-3 bg-white rounded shadow-sm">
|
||||
<h6 class="border-bottom border-gray pb-2 mb-0">Recent updates</h6>
|
||||
<a class="media text-muted pt-3" href="/events#JoinGroup">
|
||||
<svg class="bd-placeholder-img mr-2 rounded" width="32" height="32" xmlns="http://www.w3.org/2000/svg"
|
||||
preserveAspectRatio="xMidYMid slice" focusable="false" role="img" aria-label="Placeholder: 32x32">
|
||||
<title>Join Event</title>
|
||||
<rect width="100%" height="100%" fill="#6f42c1" />
|
||||
<text x="50%" y="50%" fill="#6f42c1" dy=".3em">32x32</text>
|
||||
</svg>
|
||||
<p class="media-body pb-3 mb-0 small lh-125 border-bottom border-gray">
|
||||
<strong class="d-block text-gray-dark">[Join Event]</strong>
|
||||
<span id="Join_Event">Please wait.</span>
|
||||
</p>
|
||||
</a>
|
||||
<a class="media text-muted pt-3" href="/events#KickEvent">
|
||||
<svg class="bd-placeholder-img mr-2 rounded" width="32" height="32" xmlns="http://www.w3.org/2000/svg"
|
||||
preserveAspectRatio="xMidYMid slice" focusable="false" role="img" aria-label="Placeholder: 32x32">
|
||||
<title>Kick Event</title>
|
||||
<rect width="100%" height="100%" fill="#007bff" />
|
||||
<text x="50%" y="50%" fill="#007bff" dy=".3em">32x32</text>
|
||||
</svg>
|
||||
<p class="media-body pb-3 mb-0 small lh-125 border-bottom border-gray">
|
||||
<strong class="d-block text-gray-dark">[Kick Event]</strong>
|
||||
<span id="Kick_Event">Please wait.</span>
|
||||
</p>
|
||||
</a>
|
||||
<a class="media text-muted pt-3" href="/events#CancelEvent">
|
||||
<svg class="bd-placeholder-img mr-2 rounded" width="32" height="32" xmlns="http://www.w3.org/2000/svg"
|
||||
preserveAspectRatio="xMidYMid slice" focusable="false" role="img" aria-label="Placeholder: 32x32">
|
||||
<title>Cancel Event</title>
|
||||
<rect width="100%" height="100%" fill="#e83e8c" />
|
||||
<text x="50%" y="50%" fill="#e83e8c" dy=".3em">32x32</text>
|
||||
</svg>
|
||||
<p class="media-body pb-3 mb-0 small lh-125 border-bottom border-gray">
|
||||
<strong class="d-block text-gray-dark">[Cancel Event]</strong>
|
||||
<span id="Cancel_Event">Please wait.</span>
|
||||
</p>
|
||||
</a>
|
||||
<a class="media text-muted pt-3" href="/events#BlackList">
|
||||
<svg class="bd-placeholder-img mr-2 rounded" width="32" height="32" xmlns="http://www.w3.org/2000/svg"
|
||||
preserveAspectRatio="xMidYMid slice" focusable="false" role="img" aria-label="Placeholder: 32x32">
|
||||
<title>Block Event</title>
|
||||
<rect width="100%" height="100%" fill="#00ff00" />
|
||||
<text x="50%" y="50%" fill="#00ff00" dy=".3em">32x32</text>
|
||||
</svg>
|
||||
<p class="media-body pb-3 mb-0 small lh-125 border-bottom border-gray">
|
||||
<strong class="d-block text-gray-dark">[Block Event]</strong>
|
||||
<span id="Block_Event">Please wait.</span>
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
</main>
|
||||
<div class="my-3 p-3 bg-white rounded shadow-sm">
|
||||
<h6 class="border-bottom border-gray pb-2 mb-0">Recent updates</h6>
|
||||
<a class="media text-muted pt-3" href="/events#JoinGroup">
|
||||
<svg class="bd-placeholder-img mr-2 rounded" width="32" height="32" xmlns="http://www.w3.org/2000/svg"
|
||||
preserveAspectRatio="xMidYMid slice" focusable="false" role="img" aria-label="Placeholder: 32x32">
|
||||
<title>Join Event</title>
|
||||
<rect width="100%" height="100%" fill="#6f42c1"/>
|
||||
<text x="50%" y="50%" fill="#6f42c1" dy=".3em">32x32</text>
|
||||
</svg>
|
||||
<p class="media-body pb-3 mb-0 small lh-125 border-bottom border-gray">
|
||||
<strong class="d-block text-gray-dark">[Join Event]</strong>
|
||||
<span id="Join_Event">Please wait.</span>
|
||||
</p>
|
||||
</a>
|
||||
<a class="media text-muted pt-3" href="/events#KickEvent">
|
||||
<svg class="bd-placeholder-img mr-2 rounded" width="32" height="32" xmlns="http://www.w3.org/2000/svg"
|
||||
preserveAspectRatio="xMidYMid slice" focusable="false" role="img" aria-label="Placeholder: 32x32">
|
||||
<title>Kick Event</title>
|
||||
<rect width="100%" height="100%" fill="#007bff"/>
|
||||
<text x="50%" y="50%" fill="#007bff" dy=".3em">32x32</text>
|
||||
</svg>
|
||||
<p class="media-body pb-3 mb-0 small lh-125 border-bottom border-gray">
|
||||
<strong class="d-block text-gray-dark">[Kick Event]</strong>
|
||||
<span id="Kick_Event">Please wait.</span>
|
||||
</p>
|
||||
</a>
|
||||
<a class="media text-muted pt-3" href="/events#CancelEvent">
|
||||
<svg class="bd-placeholder-img mr-2 rounded" width="32" height="32" xmlns="http://www.w3.org/2000/svg"
|
||||
preserveAspectRatio="xMidYMid slice" focusable="false" role="img" aria-label="Placeholder: 32x32">
|
||||
<title>Cancel Event</title>
|
||||
<rect width="100%" height="100%" fill="#e83e8c"/>
|
||||
<text x="50%" y="50%" fill="#e83e8c" dy=".3em">32x32</text>
|
||||
</svg>
|
||||
<p class="media-body pb-3 mb-0 small lh-125 border-bottom border-gray">
|
||||
<strong class="d-block text-gray-dark">[Cancel Event]</strong>
|
||||
<span id="Cancel_Event">Please wait.</span>
|
||||
</p>
|
||||
</a>
|
||||
<a class="media text-muted pt-3" href="/events#BlackList">
|
||||
<svg class="bd-placeholder-img mr-2 rounded" width="32" height="32" xmlns="http://www.w3.org/2000/svg"
|
||||
preserveAspectRatio="xMidYMid slice" focusable="false" role="img" aria-label="Placeholder: 32x32">
|
||||
<title>Block Event</title>
|
||||
<rect width="100%" height="100%" fill="#00ff00"/>
|
||||
<text x="50%" y="50%" fill="#00ff00" dy=".3em">32x32</text>
|
||||
</svg>
|
||||
<p class="media-body pb-3 mb-0 small lh-125 border-bottom border-gray">
|
||||
<strong class="d-block text-gray-dark">[Block Event]</strong>
|
||||
<span id="Block_Event">Please wait.</span>
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- Optional JavaScript -->
|
||||
{{ bootstrap.load_js() }}
|
||||
<script src="{{ url_for('static', filename='js/header.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/index.js') }}"></script>
|
||||
<!-- Optional JavaScript -->
|
||||
{{ bootstrap.load_js() }}
|
||||
<script src="{{ url_for('static', filename='js/header.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/index.js') }}"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -9,66 +9,66 @@
|
|||
<!-- Bootstrap CSS -->
|
||||
{{ bootstrap.load_css() }}
|
||||
<link rel="stylesheet" href="https://unpkg.com/lookforward@0.1.1/css/lookforward.min.css">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}" />
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}"/>
|
||||
|
||||
<title>Star Yuuki BOT - WebAdmin</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
{% from 'bootstrap/nav.html' import render_nav_item %}
|
||||
{% from 'bootstrap/nav.html' import render_nav_item %}
|
||||
|
||||
<div id="header"></div>
|
||||
<div id="header"></div>
|
||||
|
||||
<main role="main" class="container">
|
||||
<div class="my-3 p-3 bg-white rounded shadow-sm">
|
||||
<h6 class="border-bottom border-gray pb-2 mb-0">Settings</h6>
|
||||
<a class="media text-muted pt-3" href="#">
|
||||
<svg class="bd-placeholder-img mr-2 rounded" width="32" height="32" xmlns="http://www.w3.org/2000/svg"
|
||||
preserveAspectRatio="xMidYMid slice" focusable="false" role="img" aria-label="Placeholder: 32x32">
|
||||
<title>Profile</title>
|
||||
<rect width="100%" height="100%" fill="#007bff" />
|
||||
<text x="50%" y="50%" fill="#007bff" dy=".3em">32x32</text>
|
||||
</svg>
|
||||
<p class="media-body pb-3 mb-0 small lh-125 border-bottom border-gray">
|
||||
<strong class="d-block text-gray-dark">Profile</strong>
|
||||
Edit LINE profile of the console BOT.
|
||||
</p>
|
||||
</a>
|
||||
<a class="media text-muted pt-3" href="#">
|
||||
<svg class="bd-placeholder-img mr-2 rounded" width="32" height="32" xmlns="http://www.w3.org/2000/svg"
|
||||
preserveAspectRatio="xMidYMid slice" focusable="false" role="img" aria-label="Placeholder: 32x32">
|
||||
<title>Yuuki Configure</title>
|
||||
<rect width="100%" height="100%" fill="#e83e8c" />
|
||||
<text x="50%" y="50%" fill="#e83e8c" dy=".3em">32x32</text>
|
||||
</svg>
|
||||
<p class="media-body pb-3 mb-0 small lh-125 border-bottom border-gray">
|
||||
<strong class="d-block text-gray-dark">Yuuki Configure</strong>
|
||||
Settings for the BOT works.
|
||||
</p>
|
||||
</a>
|
||||
<a class="media text-muted pt-3" href="#" onclick="shutdown();">
|
||||
<svg class="bd-placeholder-img mr-2 rounded" width="32" height="32" xmlns="http://www.w3.org/2000/svg"
|
||||
preserveAspectRatio="xMidYMid slice" focusable="false" role="img" aria-label="Placeholder: 32x32">
|
||||
<title>Shutdown</title>
|
||||
<rect width="100%" height="100%" fill="#6f42c1" />
|
||||
<text x="50%" y="50%" fill="#6f42c1" dy=".3em">32x32</text>
|
||||
</svg>
|
||||
<p class="media-body pb-3 mb-0 small lh-125 border-bottom border-gray">
|
||||
<strong class="d-block text-gray-dark">Shutdown</strong>
|
||||
Turn off the BOT.
|
||||
</p>
|
||||
</a>
|
||||
<small class="d-block text-right mt-3">
|
||||
<a href="{{ project_url }}" target="_blank">Version: {{ version }}</a>
|
||||
</small>
|
||||
</div>
|
||||
</main>
|
||||
<main role="main" class="container">
|
||||
<div class="my-3 p-3 bg-white rounded shadow-sm">
|
||||
<h6 class="border-bottom border-gray pb-2 mb-0">Settings</h6>
|
||||
<a class="media text-muted pt-3" href="#">
|
||||
<svg class="bd-placeholder-img mr-2 rounded" width="32" height="32" xmlns="http://www.w3.org/2000/svg"
|
||||
preserveAspectRatio="xMidYMid slice" focusable="false" role="img" aria-label="Placeholder: 32x32">
|
||||
<title>Profile</title>
|
||||
<rect width="100%" height="100%" fill="#007bff"/>
|
||||
<text x="50%" y="50%" fill="#007bff" dy=".3em">32x32</text>
|
||||
</svg>
|
||||
<p class="media-body pb-3 mb-0 small lh-125 border-bottom border-gray">
|
||||
<strong class="d-block text-gray-dark">Profile</strong>
|
||||
Edit LINE profile of the console BOT.
|
||||
</p>
|
||||
</a>
|
||||
<a class="media text-muted pt-3" href="#">
|
||||
<svg class="bd-placeholder-img mr-2 rounded" width="32" height="32" xmlns="http://www.w3.org/2000/svg"
|
||||
preserveAspectRatio="xMidYMid slice" focusable="false" role="img" aria-label="Placeholder: 32x32">
|
||||
<title>Yuuki Configure</title>
|
||||
<rect width="100%" height="100%" fill="#e83e8c"/>
|
||||
<text x="50%" y="50%" fill="#e83e8c" dy=".3em">32x32</text>
|
||||
</svg>
|
||||
<p class="media-body pb-3 mb-0 small lh-125 border-bottom border-gray">
|
||||
<strong class="d-block text-gray-dark">Yuuki Configure</strong>
|
||||
Settings for the BOT works.
|
||||
</p>
|
||||
</a>
|
||||
<a class="media text-muted pt-3" href="#" onclick="shutdown();">
|
||||
<svg class="bd-placeholder-img mr-2 rounded" width="32" height="32" xmlns="http://www.w3.org/2000/svg"
|
||||
preserveAspectRatio="xMidYMid slice" focusable="false" role="img" aria-label="Placeholder: 32x32">
|
||||
<title>Shutdown</title>
|
||||
<rect width="100%" height="100%" fill="#6f42c1"/>
|
||||
<text x="50%" y="50%" fill="#6f42c1" dy=".3em">32x32</text>
|
||||
</svg>
|
||||
<p class="media-body pb-3 mb-0 small lh-125 border-bottom border-gray">
|
||||
<strong class="d-block text-gray-dark">Shutdown</strong>
|
||||
Turn off the BOT.
|
||||
</p>
|
||||
</a>
|
||||
<small class="d-block text-right mt-3">
|
||||
<a href="{{ project_url }}" target="_blank">Version: {{ version }}</a>
|
||||
</small>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- Optional JavaScript -->
|
||||
{{ bootstrap.load_js() }}
|
||||
<script src="{{ url_for('static', filename='js/header.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/settings.js') }}"></script>
|
||||
<!-- Optional JavaScript -->
|
||||
{{ bootstrap.load_js() }}
|
||||
<script src="{{ url_for('static', filename='js/header.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/settings.js') }}"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -6,19 +6,21 @@ 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 platform
|
||||
import random
|
||||
import sys
|
||||
import time
|
||||
|
||||
import requests
|
||||
from git import Repo
|
||||
from yuuki_core.TalkService import *
|
||||
from yuuki_core.ttypes import OpType
|
||||
|
||||
from .connection import Yuuki_Connect
|
||||
from .data import Yuuki_Data
|
||||
from .events import Yuuki_Command, Yuuki_JoinGroup, Yuuki_Security, Yuuki_Callback
|
||||
from .i18n import Yuuki_LangSetting
|
||||
from .poll import Yuuki_Poll
|
||||
from .events import Yuuki_Command, Yuuki_JoinGroup, Yuuki_Security
|
||||
from .thread_control import Yuuki_Multiprocess
|
||||
from .webadmin.server import Yuuki_WebAdmin
|
||||
|
||||
|
@ -30,7 +32,6 @@ class Yuuki:
|
|||
self.YuukiConfigs = Yuuki_Settings.systemConfig
|
||||
|
||||
# Static_Variable
|
||||
|
||||
self.Thread_Control = Yuuki_Multiprocess()
|
||||
|
||||
self.Seq = self.YuukiConfigs["Seq"]
|
||||
|
@ -51,11 +52,11 @@ class Yuuki:
|
|||
if self.YuukiConfigs["version_check"]:
|
||||
# noinspection PyBroadException
|
||||
try:
|
||||
GitRemote = Repo('.').remote()
|
||||
UpdateStatus = GitRemote.fetch()[0]
|
||||
if UpdateStatus.flags == 64:
|
||||
git_remote = Repo('.').remote()
|
||||
update_status = git_remote.fetch()[0]
|
||||
if update_status.flags == 64:
|
||||
git_result = "New version found."
|
||||
elif UpdateStatus.flags == 4:
|
||||
elif update_status.flags == 4:
|
||||
git_result = "This is the latest version."
|
||||
except:
|
||||
git_result = "Something was wrong."
|
||||
|
@ -93,6 +94,7 @@ class Yuuki:
|
|||
self.JoinGroup = Yuuki_JoinGroup(self).action
|
||||
self.Command = Yuuki_Command(self).action
|
||||
self.Security = Yuuki_Security(self).action
|
||||
self.Callback = Yuuki_Callback(self).action
|
||||
|
||||
self.data = Yuuki_Data(self.Threading)
|
||||
|
||||
|
@ -112,10 +114,13 @@ class Yuuki:
|
|||
self._Setup_WebAdmin()
|
||||
|
||||
def _Setup_WebAdmin(self):
|
||||
if self.Threading:
|
||||
if self.Threading and self.YuukiConfigs.get("WebAdmin"):
|
||||
password = str(hash(random.random()))
|
||||
self.webAdmin = Yuuki_WebAdmin(self)
|
||||
self.Thread_Control.add(self.webAdmin.start, (password,))
|
||||
self.shutdown_password = str(hash(random.random()))
|
||||
self.web_admin = Yuuki_WebAdmin(self)
|
||||
self.web_admin.set_password(password)
|
||||
self.web_admin.set_shutdown_password(self.shutdown_password)
|
||||
self.Thread_Control.add(self.web_admin.wa_listen)
|
||||
print(
|
||||
"<*> Yuuki WebAdmin - Enable\n"
|
||||
"<*> http://localhost:2020\n"
|
||||
|
@ -126,13 +131,18 @@ class Yuuki:
|
|||
|
||||
def exit(self, restart=False):
|
||||
print("System Exit")
|
||||
self.data.updateData(["Global", "Power"], False)
|
||||
while self.data.syncData():
|
||||
self.data.updateData(["Global", "Power"], False)
|
||||
if self.Threading:
|
||||
try:
|
||||
self.data.mdsShake("EXT", "")
|
||||
self.webAdmin.stop()
|
||||
except:
|
||||
pass
|
||||
self.data.mdsShake("EXT", None, None)
|
||||
time.sleep(1)
|
||||
self.data.MdsThreadControl.stop("mds_listen")
|
||||
if self.YuukiConfigs.get("WebAdmin"):
|
||||
requests.get(
|
||||
"http://localhost:2020/api/shutdown/{}".format(self.shutdown_password)
|
||||
)
|
||||
time.sleep(1)
|
||||
self.data.MdsThreadControl.stop("wa_listen")
|
||||
if restart:
|
||||
if platform.system() == "Windows":
|
||||
with open("cache.bat", "w") as c:
|
||||
|
@ -148,14 +158,14 @@ class Yuuki:
|
|||
print("Star Yuuki BOT - Restart Error\n\nUnknown Platform")
|
||||
sys.exit(0)
|
||||
|
||||
def threadExec(self, Function, args):
|
||||
def threadExec(self, function, args):
|
||||
if self.Threading:
|
||||
self.Thread_Control.add(Function, args)
|
||||
self.Thread_Control.add(function, args)
|
||||
else:
|
||||
Function(*args)
|
||||
function(*args)
|
||||
|
||||
def taskDemux(self, catchedNews):
|
||||
for ncMessage in catchedNews:
|
||||
def taskDemux(self, catched_news):
|
||||
for ncMessage in catched_news:
|
||||
if ncMessage.type == OpType.NOTIFIED_INVITE_INTO_GROUP:
|
||||
self.threadExec(self.JoinGroup, (ncMessage,))
|
||||
elif ncMessage.type == OpType.NOTIFIED_KICKOUT_FROM_GROUP:
|
||||
|
@ -166,7 +176,9 @@ class Yuuki:
|
|||
self.threadExec(self.Security, (ncMessage,))
|
||||
elif ncMessage.type == OpType.RECEIVE_MESSAGE:
|
||||
self.threadExec(self.Command, (ncMessage,))
|
||||
elif ncMessage.type == OpType.SEND_MESSAGE:
|
||||
self.threadExec(self.Callback, (ncMessage,))
|
||||
|
||||
def main(self):
|
||||
handle = Yuuki_Poll(self)
|
||||
handle.init()
|
||||
handle.init()
|
||||
|
|
|
@ -4,14 +4,14 @@ flask==1.1.1
|
|||
bootstrap-flask==1.2.0
|
||||
certifi==2019.11.28
|
||||
chardet==3.0.4
|
||||
gitdb2==2.0.6
|
||||
GitPython==3.0.5
|
||||
idna==2.8
|
||||
gitdb2==3.0.2
|
||||
GitPython==3.0.8
|
||||
idna==2.9
|
||||
PyYAML==5.3
|
||||
requests==2.22.0
|
||||
requests==2.23.0
|
||||
six==1.14.0
|
||||
smmap2==2.0.5
|
||||
thrift==0.13.0
|
||||
tornado==6.0.3
|
||||
urllib3==1.25.8
|
||||
yuuki-core==6.5
|
||||
yuuki-core==6.5.1
|
||||
|
|
Loading…
Reference in a new issue