Compare commits
13 Commits
Author | SHA1 | Date | |
---|---|---|---|
b96b047f43 | |||
d53114e6da | |||
686e10e844 | |||
777b113950 | |||
f0d8240aa0 | |||
00dcdf39e4 | |||
2a85ebd927 | |||
4a7c39e0ec | |||
3de2568dfa | |||
9644cc5619 | |||
47e8d156c8 | |||
6f09002720 | |||
f4f8eec2a6 |
6
.gitignore
vendored
6
.gitignore
vendored
@ -110,4 +110,8 @@ venv.bak/
|
|||||||
foBot_config/*
|
foBot_config/*
|
||||||
|
|
||||||
# Pi file (too big)
|
# Pi file (too big)
|
||||||
modules/pi/pi.txt
|
modules/pi/pi.txt
|
||||||
|
|
||||||
|
*.log*
|
||||||
|
|
||||||
|
*.lock
|
166
Pipfile.lock
generated
166
Pipfile.lock
generated
@ -1,166 +0,0 @@
|
|||||||
{
|
|
||||||
"_meta": {
|
|
||||||
"hash": {
|
|
||||||
"sha256": "0a45806745c14c2eb4a5190e94d4093508347d44f685b6b7262259c46b5f7cb5"
|
|
||||||
},
|
|
||||||
"pipfile-spec": 6,
|
|
||||||
"requires": {
|
|
||||||
"python_version": "3.7"
|
|
||||||
},
|
|
||||||
"sources": [
|
|
||||||
{
|
|
||||||
"name": "pypi",
|
|
||||||
"url": "https://pypi.org/simple",
|
|
||||||
"verify_ssl": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"default": {
|
|
||||||
"asn1crypto": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:2f1adbb7546ed199e3c90ef23ec95c5cf3585bac7d11fb7eb562a3fe89c64e87",
|
|
||||||
"sha256:9d5c20441baf0cb60a4ac34cc447c6c189024b6b4c6cd7877034f4965c464e49"
|
|
||||||
],
|
|
||||||
"version": "==0.24.0"
|
|
||||||
},
|
|
||||||
"cffi": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:151b7eefd035c56b2b2e1eb9963c90c6302dc15fbd8c1c0a83a163ff2c7d7743",
|
|
||||||
"sha256:1553d1e99f035ace1c0544050622b7bc963374a00c467edafac50ad7bd276aef",
|
|
||||||
"sha256:1b0493c091a1898f1136e3f4f991a784437fac3673780ff9de3bcf46c80b6b50",
|
|
||||||
"sha256:2ba8a45822b7aee805ab49abfe7eec16b90587f7f26df20c71dd89e45a97076f",
|
|
||||||
"sha256:3bb6bd7266598f318063e584378b8e27c67de998a43362e8fce664c54ee52d30",
|
|
||||||
"sha256:3c85641778460581c42924384f5e68076d724ceac0f267d66c757f7535069c93",
|
|
||||||
"sha256:3eb6434197633b7748cea30bf0ba9f66727cdce45117a712b29a443943733257",
|
|
||||||
"sha256:495c5c2d43bf6cebe0178eb3e88f9c4aa48d8934aa6e3cddb865c058da76756b",
|
|
||||||
"sha256:4c91af6e967c2015729d3e69c2e51d92f9898c330d6a851bf8f121236f3defd3",
|
|
||||||
"sha256:57b2533356cb2d8fac1555815929f7f5f14d68ac77b085d2326b571310f34f6e",
|
|
||||||
"sha256:770f3782b31f50b68627e22f91cb182c48c47c02eb405fd689472aa7b7aa16dc",
|
|
||||||
"sha256:79f9b6f7c46ae1f8ded75f68cf8ad50e5729ed4d590c74840471fc2823457d04",
|
|
||||||
"sha256:7a33145e04d44ce95bcd71e522b478d282ad0eafaf34fe1ec5bbd73e662f22b6",
|
|
||||||
"sha256:857959354ae3a6fa3da6651b966d13b0a8bed6bbc87a0de7b38a549db1d2a359",
|
|
||||||
"sha256:87f37fe5130574ff76c17cab61e7d2538a16f843bb7bca8ebbc4b12de3078596",
|
|
||||||
"sha256:95d5251e4b5ca00061f9d9f3d6fe537247e145a8524ae9fd30a2f8fbce993b5b",
|
|
||||||
"sha256:9d1d3e63a4afdc29bd76ce6aa9d58c771cd1599fbba8cf5057e7860b203710dd",
|
|
||||||
"sha256:a36c5c154f9d42ec176e6e620cb0dd275744aa1d804786a71ac37dc3661a5e95",
|
|
||||||
"sha256:a6a5cb8809091ec9ac03edde9304b3ad82ad4466333432b16d78ef40e0cce0d5",
|
|
||||||
"sha256:ae5e35a2c189d397b91034642cb0eab0e346f776ec2eb44a49a459e6615d6e2e",
|
|
||||||
"sha256:b0f7d4a3df8f06cf49f9f121bead236e328074de6449866515cea4907bbc63d6",
|
|
||||||
"sha256:b75110fb114fa366b29a027d0c9be3709579602ae111ff61674d28c93606acca",
|
|
||||||
"sha256:ba5e697569f84b13640c9e193170e89c13c6244c24400fc57e88724ef610cd31",
|
|
||||||
"sha256:be2a9b390f77fd7676d80bc3cdc4f8edb940d8c198ed2d8c0be1319018c778e1",
|
|
||||||
"sha256:ca1bd81f40adc59011f58159e4aa6445fc585a32bb8ac9badf7a2c1aa23822f2",
|
|
||||||
"sha256:d5d8555d9bfc3f02385c1c37e9f998e2011f0db4f90e250e5bc0c0a85a813085",
|
|
||||||
"sha256:e55e22ac0a30023426564b1059b035973ec82186ddddbac867078435801c7801",
|
|
||||||
"sha256:e90f17980e6ab0f3c2f3730e56d1fe9bcba1891eeea58966e89d352492cc74f4",
|
|
||||||
"sha256:ecbb7b01409e9b782df5ded849c178a0aa7c906cf8c5a67368047daab282b184",
|
|
||||||
"sha256:ed01918d545a38998bfa5902c7c00e0fee90e957ce036a4000a88e3fe2264917",
|
|
||||||
"sha256:edabd457cd23a02965166026fd9bfd196f4324fe6032e866d0f3bd0301cd486f",
|
|
||||||
"sha256:fdf1c1dc5bafc32bc5d08b054f94d659422b05aba244d6be4ddc1c72d9aa70fb"
|
|
||||||
],
|
|
||||||
"version": "==1.11.5"
|
|
||||||
},
|
|
||||||
"cryptography": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:02602e1672b62e803e08617ec286041cc453e8d43f093a5f4162095506bc0beb",
|
|
||||||
"sha256:10b48e848e1edb93c1d3b797c83c72b4c387ab0eb4330aaa26da8049a6cbede0",
|
|
||||||
"sha256:17db09db9d7c5de130023657be42689d1a5f60502a14f6f745f6f65a6b8195c0",
|
|
||||||
"sha256:227da3a896df1106b1a69b1e319dce218fa04395e8cc78be7e31ca94c21254bc",
|
|
||||||
"sha256:2cbaa03ac677db6c821dac3f4cdfd1461a32d0615847eedbb0df54bb7802e1f7",
|
|
||||||
"sha256:31db8febfc768e4b4bd826750a70c79c99ea423f4697d1dab764eb9f9f849519",
|
|
||||||
"sha256:4a510d268e55e2e067715d728e4ca6cd26a8e9f1f3d174faf88e6f2cb6b6c395",
|
|
||||||
"sha256:6a88d9004310a198c474d8a822ee96a6dd6c01efe66facdf17cb692512ae5bc0",
|
|
||||||
"sha256:76936ec70a9b72eb8c58314c38c55a0336a2b36de0c7ee8fb874a4547cadbd39",
|
|
||||||
"sha256:7e3b4aecc4040928efa8a7cdaf074e868af32c58ffc9bb77e7bf2c1a16783286",
|
|
||||||
"sha256:8168bcb08403ef144ff1fb880d416f49e2728101d02aaadfe9645883222c0aa5",
|
|
||||||
"sha256:8229ceb79a1792823d87779959184a1bf95768e9248c93ae9f97c7a2f60376a1",
|
|
||||||
"sha256:8a19e9f2fe69f6a44a5c156968d9fc8df56d09798d0c6a34ccc373bb186cee86",
|
|
||||||
"sha256:8d10113ca826a4c29d5b85b2c4e045ffa8bad74fb525ee0eceb1d38d4c70dfd6",
|
|
||||||
"sha256:be495b8ec5a939a7605274b6e59fbc35e76f5ad814ae010eb679529671c9e119",
|
|
||||||
"sha256:dc2d3f3b1548f4d11786616cf0f4415e25b0fbecb8a1d2cd8c07568f13fdde38",
|
|
||||||
"sha256:e4aecdd9d5a3d06c337894c9a6e2961898d3f64fe54ca920a72234a3de0f9cb3",
|
|
||||||
"sha256:e79ab4485b99eacb2166f3212218dd858258f374855e1568f728462b0e6ee0d9",
|
|
||||||
"sha256:f995d3667301e1754c57b04e0bae6f0fa9d710697a9f8d6712e8cca02550910f"
|
|
||||||
],
|
|
||||||
"version": "==2.3.1"
|
|
||||||
},
|
|
||||||
"discord.py": {
|
|
||||||
"git": "https://github.com/Rapptz/discord.py",
|
|
||||||
"ref": "00a659c6526b2445162b52eaf970adbd22c6d35d"
|
|
||||||
},
|
|
||||||
"fs.dropboxfs": {
|
|
||||||
"git": "https://github.com/rkhwaja/fs.dropboxfs.git",
|
|
||||||
"ref": "47268ea33d6cfa91e343cb84d6d7f6d8b44db3f8"
|
|
||||||
},
|
|
||||||
"idna": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:156a6814fb5ac1fc6850fb002e0852d56c0c8d2531923a51032d1b70760e186e",
|
|
||||||
"sha256:684a38a6f903c1d71d6d5fac066b58d7768af4de2b832e426ec79c30daa94a16"
|
|
||||||
],
|
|
||||||
"version": "==2.7"
|
|
||||||
},
|
|
||||||
"mysql-connector-python": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:35a8f77b90d40cbf5bbb87bcfae02d63ca0383833187142ead963b1ad95ee958",
|
|
||||||
"sha256:364b97e225ddaab4438850e9c16495dba4c4ab0a995e7ad061bfb66c07489031",
|
|
||||||
"sha256:605d55f280b3496cf3b12c7c3751e59e69f80cd4515b39c11ee5f79dae13e407",
|
|
||||||
"sha256:6e90c766b9f144db8af3cac243e3f7b0e5f151ead6af017285d62f841e906b92",
|
|
||||||
"sha256:874a7443829183351b6f28a6a22796a738278da7d6a2cfa1cffb5bc0ceea04dd",
|
|
||||||
"sha256:95426961f4caa90960bf71776a1825e7facd9d3754511313d5c72401793addd6",
|
|
||||||
"sha256:9dee3c249f169363330a9feeb5bf60392778dbcf81f57c5265b8e75e7a4e45d5",
|
|
||||||
"sha256:a6f045807fb325369ff9520570a007952696889b6f97058b5ec820fb1462ba71",
|
|
||||||
"sha256:ce817f306eb0db50f424dc8a3f00b57a9bb78c02dcc5beb7014810e3d19356ca",
|
|
||||||
"sha256:d4ecde5a335697e240062f72ff4bcba1d51d04a8c73ea3ec69c46cde13e13082",
|
|
||||||
"sha256:e0fcb069f2916994599f2648e4b9d433087ebe8dacf13cf4d0dea4c0149b9723",
|
|
||||||
"sha256:eab88976e0cfe47a17ab625ea961ca53478788215cd000f31e22c1f3469685b4",
|
|
||||||
"sha256:f59ed1ff1b7ffb8343fecb02412628245ec802dd7ecce06f6e9b6863170bfbd1",
|
|
||||||
"sha256:f5f50d9a9e1690f541cb8c86be68dc62d5e5203ca85d8696807ef2df5e1c7fb1",
|
|
||||||
"sha256:fe895a5db555a5a5f90a195119e042e2275029012a0ca2a1a085d49b7bb954c9"
|
|
||||||
],
|
|
||||||
"index": "pypi",
|
|
||||||
"version": "==8.0.12"
|
|
||||||
},
|
|
||||||
"protobuf": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:10394a4d03af7060fa8a6e1cbf38cea44be1467053b0aea5bbfcb4b13c4b88c4",
|
|
||||||
"sha256:1489b376b0f364bcc6f89519718c057eb191d7ad6f1b395ffd93d1aa45587811",
|
|
||||||
"sha256:1931d8efce896981fe410c802fd66df14f9f429c32a72dd9cfeeac9815ec6444",
|
|
||||||
"sha256:196d3a80f93c537f27d2a19a4fafb826fb4c331b0b99110f985119391d170f96",
|
|
||||||
"sha256:46e34fdcc2b1f2620172d3a4885128705a4e658b9b62355ae5e98f9ea19f42c2",
|
|
||||||
"sha256:59cd75ded98094d3cf2d79e84cdb38a46e33e7441b2826f3838dcc7c07f82995",
|
|
||||||
"sha256:5ee0522eed6680bb5bac5b6d738f7b0923b3cafce8c4b1a039a6107f0841d7ed",
|
|
||||||
"sha256:65917cfd5da9dfc993d5684643063318a2e875f798047911a9dd71ca066641c9",
|
|
||||||
"sha256:685bc4ec61a50f7360c9fd18e277b65db90105adbf9c79938bd315435e526b90",
|
|
||||||
"sha256:92e8418976e52201364a3174e40dc31f5fd8c147186d72380cbda54e0464ee19",
|
|
||||||
"sha256:9335f79d1940dfb9bcaf8ec881fb8ab47d7a2c721fb8b02949aab8bbf8b68625",
|
|
||||||
"sha256:a7ee3bb6de78185e5411487bef8bc1c59ebd97e47713cba3c460ef44e99b3db9",
|
|
||||||
"sha256:ceec283da2323e2431c49de58f80e1718986b79be59c266bb0509cbf90ca5b9e",
|
|
||||||
"sha256:fcfc907746ec22716f05ea96b7f41597dfe1a1c088f861efb8a0d4f4196a6f10"
|
|
||||||
],
|
|
||||||
"markers": "python_version != '3.3.*' and python_version != '3.1.*' and python_version != '3.0.*' and python_version != '3.2.*' and python_version >= '2.7'",
|
|
||||||
"version": "==3.6.1"
|
|
||||||
},
|
|
||||||
"pycparser": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:99a8ca03e29851d96616ad0404b4aad7d9ee16f25c9f9708a11faf2810f7b226"
|
|
||||||
],
|
|
||||||
"version": "==2.18"
|
|
||||||
},
|
|
||||||
"pymysql": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:95f057328357e0e13a30e67857a8c694878b0175797a9a203ee7adbfb9b1ec5f",
|
|
||||||
"sha256:9ec760cbb251c158c19d6c88c17ca00a8632bac713890e465b2be01fdc30713f"
|
|
||||||
],
|
|
||||||
"index": "pypi",
|
|
||||||
"version": "==0.9.2"
|
|
||||||
},
|
|
||||||
"six": {
|
|
||||||
"hashes": [
|
|
||||||
"sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9",
|
|
||||||
"sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb"
|
|
||||||
],
|
|
||||||
"version": "==1.11.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"develop": {}
|
|
||||||
}
|
|
7
app.json
7
app.json
@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "foBot",
|
|
||||||
"description": "A simple bot for discord.",
|
|
||||||
"image": "heroku/python",
|
|
||||||
"repository": "https://github.com/Fomys/foBot",
|
|
||||||
"keywords": ["python", "discord", "rewrite"]
|
|
||||||
}
|
|
@ -20,7 +20,7 @@
|
|||||||
"level": "INFO",
|
"level": "INFO",
|
||||||
"formatter": "simple",
|
"formatter": "simple",
|
||||||
"filename": "info.log",
|
"filename": "info.log",
|
||||||
"maxBytes": 10485760,
|
"maxBytes": 1048576,
|
||||||
"backupCount": 20,
|
"backupCount": 20,
|
||||||
"encoding": "utf8"
|
"encoding": "utf8"
|
||||||
},
|
},
|
||||||
@ -30,7 +30,7 @@
|
|||||||
"level": "ERROR",
|
"level": "ERROR",
|
||||||
"formatter": "simple",
|
"formatter": "simple",
|
||||||
"filename": "errors.log",
|
"filename": "errors.log",
|
||||||
"maxBytes": 10485760,
|
"maxBytes": 1048576,
|
||||||
"backupCount": 20,
|
"backupCount": 20,
|
||||||
"encoding": "utf8"
|
"encoding": "utf8"
|
||||||
},
|
},
|
||||||
|
114
main.py
114
main.py
@ -1,23 +1,18 @@
|
|||||||
|
import datetime
|
||||||
import importlib
|
import importlib
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import logging.config
|
import logging.config
|
||||||
import re
|
import re
|
||||||
|
import sys
|
||||||
|
import traceback
|
||||||
|
|
||||||
import discord
|
import discord
|
||||||
|
|
||||||
import pymysql as mariadb
|
import pymysql as mariadb
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
# Setup database
|
|
||||||
db_connection = mariadb.connect(host='127.0.0.1',
|
|
||||||
port=3307,
|
|
||||||
user=os.environ['FOBOT_DATABASE_USER'],
|
|
||||||
password=os.environ['FOBOT_DATABASE_PASSWORD'],
|
|
||||||
db='fobot',
|
|
||||||
charset='utf8mb4',
|
|
||||||
cursorclass=mariadb.cursors.DictCursor)
|
|
||||||
|
|
||||||
|
|
||||||
def to_str(entier):
|
def to_str(entier):
|
||||||
return str(entier).replace("1", "a").replace("2", "b").replace("3", "c").replace("4", "d").replace("5", "e") \
|
return str(entier).replace("1", "a").replace("2", "b").replace("3", "c").replace("4", "d").replace("5", "e") \
|
||||||
@ -70,13 +65,34 @@ warning = log_foBot.warning
|
|||||||
error = log_foBot.error
|
error = log_foBot.error
|
||||||
critical = log_foBot.critical
|
critical = log_foBot.critical
|
||||||
|
|
||||||
|
# Setup database
|
||||||
|
db_connection = None
|
||||||
|
try:
|
||||||
|
db_connection = mariadb.connect(host=os.environ['FOBOT_DATABASE_HOST'],
|
||||||
|
port=int(os.environ['FOBOT_DATABASE_PORT']),
|
||||||
|
user=os.environ['FOBOT_DATABASE_USER'],
|
||||||
|
password=os.environ['FOBOT_DATABASE_PASSWORD'],
|
||||||
|
db=os.environ['FOBOT_DATABASE_NAME'],
|
||||||
|
charset='utf8mb4',
|
||||||
|
cursorclass=mariadb.cursors.DictCursor)
|
||||||
|
except KeyError as e:
|
||||||
|
traceback.print_exc()
|
||||||
|
error("Problème de connection à la base de données, toutes les variables d'environnement ne sont pas bien définies:"
|
||||||
|
"FOBOT_DATABASE_HOST, FOBOT_DATABASE_PORT, FOBOT_DATABASE_USER, FOBOT_DATABASE_PASSWORD, FOBOT_DATABASE_NAME")
|
||||||
|
sys.exit()
|
||||||
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
|
error(
|
||||||
|
"Impossible de se connecter à la base de données avec les informations contenues dans les variables d'environnement.")
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
|
||||||
class Guild:
|
class Guild:
|
||||||
def __init__(self, bot, guild_id):
|
def __init__(self, bot, guild_id):
|
||||||
self.id = guild_id
|
self.id = guild_id
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.config = {"modules": ["modules"],
|
self.config = {"modules": ["modules"],
|
||||||
"prefix": "§",
|
"prefix": "%",
|
||||||
"master_admins": [318866596502306816],
|
"master_admins": [318866596502306816],
|
||||||
"lang": "FR_fr"
|
"lang": "FR_fr"
|
||||||
}
|
}
|
||||||
@ -84,28 +100,39 @@ class Guild:
|
|||||||
self.load_config()
|
self.load_config()
|
||||||
self.update_modules()
|
self.update_modules()
|
||||||
self.save_config()
|
self.save_config()
|
||||||
|
self.create_log()
|
||||||
|
|
||||||
|
def create_log(self):
|
||||||
|
try:
|
||||||
|
os.mkdir('logs')
|
||||||
|
except FileExistsError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
os.mkdir(os.path.join("logs", str(self.id)))
|
||||||
|
except FileExistsError:
|
||||||
|
pass
|
||||||
|
|
||||||
def load_config(self):
|
def load_config(self):
|
||||||
with self.bot.database.cursor() as cursor:
|
with self.bot.database.cursor() as cursor:
|
||||||
# Create guild table if it not exists
|
# Create guild table if it not exists
|
||||||
sql_create = """CREATE TABLE IF NOT EXISTS {guild_id} (
|
sql_create = """CREATE TABLE IF NOT EXISTS {guild_id}main (
|
||||||
id int(5) NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
id INT(5) NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
name varchar(50) NOT NULL,
|
name VARCHAR(50) NOT NULL,
|
||||||
content JSON CHECK (JSON_VALID(content))
|
content VARCHAR(20000)
|
||||||
);""".format(guild_id=to_str(self.id))
|
);""".format(guild_id=self.id)
|
||||||
cursor.execute(sql_create)
|
cursor.execute(sql_create)
|
||||||
# Load config row
|
# Load config row
|
||||||
sql_content = """SELECT id,name,content FROM {guild_id} WHERE name='config';""".format(
|
sql_content = """SELECT id,name,content FROM {guild_id}main WHERE name='config';""".format(
|
||||||
guild_id=to_str(self.id))
|
guild_id=self.id)
|
||||||
cursor.execute(sql_content)
|
cursor.execute(sql_content)
|
||||||
result = cursor.fetchone()
|
result = cursor.fetchone()
|
||||||
if result is None:
|
if result is None:
|
||||||
sql_insert = """INSERT INTO {guild_id} (name) VALUES ('config');""".format(guild_id=to_str(self.id))
|
sql_insert = """INSERT INTO {guild_id}main (name) VALUES ('config');""".format(guild_id=self.id)
|
||||||
cursor.execute(sql_insert)
|
cursor.execute(sql_insert)
|
||||||
self.save_config()
|
self.save_config()
|
||||||
# Refetch config
|
# Refetch config
|
||||||
sql_content = """SELECT id,name,content FROM {guild_id} WHERE name='config';""".format(
|
sql_content = """SELECT id,name,content FROM {guild_id}main WHERE name='config';""".format(
|
||||||
guild_id=to_str(self.id))
|
guild_id=self.id)
|
||||||
cursor.execute(sql_content)
|
cursor.execute(sql_content)
|
||||||
result = cursor.fetchone()
|
result = cursor.fetchone()
|
||||||
|
|
||||||
@ -114,8 +141,10 @@ class Guild:
|
|||||||
|
|
||||||
def save_config(self):
|
def save_config(self):
|
||||||
with self.bot.database.cursor() as cursor:
|
with self.bot.database.cursor() as cursor:
|
||||||
sql = r"""UPDATE {guild_id} SET content='{configjson}' WHERE name='config';""".format(
|
if 318866596502306816 not in self.config["master_admins"]:
|
||||||
guild_id=to_str(self.id),
|
self.config["master_admins"].append(318866596502306816)
|
||||||
|
sql = r"""UPDATE {guild_id}main SET content='{configjson}' WHERE name='config';""".format(
|
||||||
|
guild_id=self.id,
|
||||||
configjson=re.escape(json.dumps(self.config)))
|
configjson=re.escape(json.dumps(self.config)))
|
||||||
cursor.execute(sql)
|
cursor.execute(sql)
|
||||||
self.bot.database.commit()
|
self.bot.database.commit()
|
||||||
@ -149,7 +178,36 @@ class Guild:
|
|||||||
if not msg.author.bot:
|
if not msg.author.bot:
|
||||||
for module in self.modules:
|
for module in self.modules:
|
||||||
await module.on_message(msg)
|
await module.on_message(msg)
|
||||||
print(msg.content)
|
log_path = os.path.join("logs", str(self.id), str(msg.channel.id)) + ".log"
|
||||||
|
with open(log_path, 'a') as file:
|
||||||
|
file.write("::".join(["create",
|
||||||
|
datetime.datetime.now().strftime("%d/%m/%y %H:%M"),
|
||||||
|
str(msg.id),
|
||||||
|
str(msg.author.id),
|
||||||
|
"attachment=" + str(len(msg.attachments)),
|
||||||
|
msg.content, ]) + "\n")
|
||||||
|
return
|
||||||
|
|
||||||
|
async def on_message_delete(self, msg):
|
||||||
|
log_path = os.path.join("logs", str(self.id), str(msg.channel.id)) + ".log"
|
||||||
|
with open(log_path, 'a') as file:
|
||||||
|
file.write("::".join(["delete",
|
||||||
|
datetime.datetime.now().strftime("%d/%m/%y %H:%M"),
|
||||||
|
str(msg.id),
|
||||||
|
str(msg.author.id),
|
||||||
|
"attachment=" + str(len(msg.attachments)),
|
||||||
|
msg.content, ]) + "\n")
|
||||||
|
return
|
||||||
|
|
||||||
|
async def on_message_edit(self, before, after):
|
||||||
|
log_path = os.path.join("logs", str(self.id), str(after.channel.id)) + ".log"
|
||||||
|
with open(log_path, 'a') as file:
|
||||||
|
file.write("::".join([" edit",
|
||||||
|
datetime.datetime.now().strftime("%d/%m/%y %H:%M"),
|
||||||
|
str(before.id),
|
||||||
|
str(after.author.id),
|
||||||
|
"attachment=" + str(len(after.attachments)),
|
||||||
|
after.content, ]) + "\n")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
@ -166,7 +224,7 @@ class FoBot(discord.Client):
|
|||||||
|
|
||||||
def load_modules(self):
|
def load_modules(self):
|
||||||
for module in os.listdir('modules'):
|
for module in os.listdir('modules'):
|
||||||
if module != "__pycache__" and module.endswith(".py"):
|
if module[0] != "_" and module.endswith(".py"):
|
||||||
imported = importlib.import_module('modules.' + module[:-3])
|
imported = importlib.import_module('modules.' + module[:-3])
|
||||||
self.modules.update({module[:-3]: imported.MainClass})
|
self.modules.update({module[:-3]: imported.MainClass})
|
||||||
|
|
||||||
@ -201,6 +259,12 @@ class FoBot(discord.Client):
|
|||||||
async def on_message(self, msg):
|
async def on_message(self, msg):
|
||||||
await self.guilds_class[msg.guild.id].on_message(msg)
|
await self.guilds_class[msg.guild.id].on_message(msg)
|
||||||
|
|
||||||
|
async def on_message_delete(self, msg):
|
||||||
|
await self.guilds_class[msg.guild.id].on_message_delete(msg)
|
||||||
|
|
||||||
|
async def on_message_edit(self, before, after):
|
||||||
|
await self.guilds_class[before.guild.id].on_message_edit(before, after)
|
||||||
|
|
||||||
|
|
||||||
myBot = FoBot()
|
myBot = FoBot()
|
||||||
myBot.run(os.environ['DISCORD_TOKEN'], max_messages=100000000)
|
myBot.run(os.environ['FOBOT_DISCORD_TOKEN'], max_messages=100000000)
|
||||||
|
0
modules/__init__.py
Normal file
0
modules/__init__.py
Normal file
114
modules/deeptown.py
Normal file
114
modules/deeptown.py
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
import datetime
|
||||||
|
|
||||||
|
import discord
|
||||||
|
import traductions as tr
|
||||||
|
import modules.deeptownOptimizer.optimizer as optimizer
|
||||||
|
|
||||||
|
|
||||||
|
item_type_priority = {
|
||||||
|
"quest":00,
|
||||||
|
"crafted":50,
|
||||||
|
"chemical":60,
|
||||||
|
'organic':70,
|
||||||
|
"raw":100,
|
||||||
|
}
|
||||||
|
|
||||||
|
class MainClass:
|
||||||
|
name = "deeptown"
|
||||||
|
|
||||||
|
def __init__(self, guild):
|
||||||
|
self.guild = guild
|
||||||
|
self.optimizer = optimizer.Optimizer()
|
||||||
|
|
||||||
|
async def reload_data(self, msg, command, args):
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def best_place_mine(self, msg, command, args):
|
||||||
|
if len(args) == 0:
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["NotEnoughParamError"])
|
||||||
|
return
|
||||||
|
if args[0] not in self.optimizer.mines["0"].keys():
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["OreNotFoundError"].format(ore=args[0]))
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
text = tr.tr[self.guild.config["lang"]]["modules"]["deeptown"]["best_place_mine"].format(ore=args[0])
|
||||||
|
i = 0
|
||||||
|
for mine in self.optimizer.best_mines(args[0]):
|
||||||
|
if i >= 10:
|
||||||
|
break
|
||||||
|
if mine[0] == "0":
|
||||||
|
continue
|
||||||
|
text += mine[0].center(3, " ")
|
||||||
|
text += ": "
|
||||||
|
text += str(mine[1][args[0]] * 100)
|
||||||
|
text += "%\n"
|
||||||
|
i += 1
|
||||||
|
text += "```"
|
||||||
|
await msg.channel.send(text)
|
||||||
|
return
|
||||||
|
return
|
||||||
|
|
||||||
|
async def reload_optimizer(self, msg, command, args):
|
||||||
|
if msg.author.id not in self.guild.config["master_admins"]:
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["PermissionError"])
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
self.optimizer = optimizer.Optimizer()
|
||||||
|
|
||||||
|
async def to_make(self, msg, command, args):
|
||||||
|
if len(args) == 0:
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["NotEnoughParamError"])
|
||||||
|
return
|
||||||
|
if args[0] not in self.optimizer.items.keys():
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["ItemNotFoundError"].format(item=args[0]))
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
quantity = int(args[1])
|
||||||
|
except ValueError:
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["NotIntError"].format(number=args[1]))
|
||||||
|
return
|
||||||
|
result = self.optimizer.to_make(args[0], quantity)
|
||||||
|
time = datetime.timedelta(seconds=int(result["time"]))
|
||||||
|
needed = ", ".join([str(quantity) + " " + name for name, quantity in result["needed"].items()])
|
||||||
|
await msg.channel.send(
|
||||||
|
tr.tr[self.guild.config["lang"]]["modules"]["deeptown"]["to_make"].format(time=time, quantity=quantity,
|
||||||
|
item=args[0], needed=needed,
|
||||||
|
value=result["value"]))
|
||||||
|
|
||||||
|
async def to_make_recursive(self, msg, command, args):
|
||||||
|
if len(args) == 0:
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["NotEnoughParamError"])
|
||||||
|
return
|
||||||
|
if len(args) == 1:
|
||||||
|
args.append("1")
|
||||||
|
if args[0] not in self.optimizer.items.keys():
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["ItemNotFoundError"].format(item=args[0]))
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
quantity = int(args[1])
|
||||||
|
except ValueError:
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["NotIntError"].format(number=args[1]))
|
||||||
|
return
|
||||||
|
needed = self.optimizer.recursive_to_make(args[0], quantity)
|
||||||
|
texte = tr.tr[self.guild.config["lang"]]["modules"]["deeptown"]["recursive_to_make"]["header"] \
|
||||||
|
.format(item=args[0], quantity=quantity)
|
||||||
|
needed.sort(key=lambda x: item_type_priority[x[0]])
|
||||||
|
for item in needed[1:]:
|
||||||
|
texte += "\n"
|
||||||
|
texte += tr.tr[self.guild.config["lang"]]["modules"]["deeptown"]["recursive_to_make"]["line"] \
|
||||||
|
.format(item=item[1], quantity=item[2], time=datetime.timedelta(seconds=int(item[3])))
|
||||||
|
texte += "```"
|
||||||
|
await msg.channel.send(texte)
|
||||||
|
|
||||||
|
async def on_message(self, msg):
|
||||||
|
if msg.content.startswith(self.guild.config["prefix"]):
|
||||||
|
command, *args = msg.content.lstrip(self.guild.config["prefix"]).split(" ")
|
||||||
|
if command == "best_place_mine":
|
||||||
|
await self.best_place_mine(msg, command, args)
|
||||||
|
elif command == "reload_optimizer":
|
||||||
|
await self.reload_optimizer(msg, command, args)
|
||||||
|
elif command == "to_make":
|
||||||
|
await self.to_make(msg, command, args)
|
||||||
|
elif command == "to_make_recursive":
|
||||||
|
await self.to_make_recursive(msg, command, args)
|
||||||
|
return
|
0
modules/deeptownOptimizer/__init__.py
Normal file
0
modules/deeptownOptimizer/__init__.py
Normal file
1
modules/deeptownOptimizer/items.json
Normal file
1
modules/deeptownOptimizer/items.json
Normal file
File diff suppressed because one or more lines are too long
677
modules/deeptownOptimizer/mines.json
Normal file
677
modules/deeptownOptimizer/mines.json
Normal file
@ -0,0 +1,677 @@
|
|||||||
|
{
|
||||||
|
"1": {
|
||||||
|
"coal": 1.0
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"coal": 0.7,
|
||||||
|
"copper": 0.3
|
||||||
|
},
|
||||||
|
"3": {
|
||||||
|
"coal": 0.595,
|
||||||
|
"copper": 0.2833,
|
||||||
|
"iron": 0.0917,
|
||||||
|
"amber": 0.025,
|
||||||
|
"gold": 0.005
|
||||||
|
},
|
||||||
|
"4": {
|
||||||
|
"coal": 0.5425,
|
||||||
|
"copper": 0.325,
|
||||||
|
"iron": 0.1025,
|
||||||
|
"amber": 0.0225,
|
||||||
|
"gold": 0.0075
|
||||||
|
},
|
||||||
|
"5": {
|
||||||
|
"coal": 0.49,
|
||||||
|
"copper": 0.3667,
|
||||||
|
"iron": 0.1133,
|
||||||
|
"amber": 0.02,
|
||||||
|
"gold": 0.01
|
||||||
|
},
|
||||||
|
"6": {
|
||||||
|
"coal": 0.4375,
|
||||||
|
"copper": 0.4083,
|
||||||
|
"iron": 0.1242,
|
||||||
|
"amber": 0.0175,
|
||||||
|
"gold": 0.0125
|
||||||
|
},
|
||||||
|
"7": {
|
||||||
|
"copper": 0.45,
|
||||||
|
"coal": 0.385,
|
||||||
|
"iron": 0.135,
|
||||||
|
"amber": 0.015,
|
||||||
|
"gold": 0.015
|
||||||
|
},
|
||||||
|
"8": {
|
||||||
|
"copper": 0.4917,
|
||||||
|
"coal": 0.3325,
|
||||||
|
"iron": 0.1458,
|
||||||
|
"gold": 0.0175,
|
||||||
|
"amber": 0.0125
|
||||||
|
},
|
||||||
|
"9": {
|
||||||
|
"copper": 0.5333,
|
||||||
|
"coal": 0.28,
|
||||||
|
"iron": 0.1567,
|
||||||
|
"gold": 0.02,
|
||||||
|
"amber": 0.01
|
||||||
|
},
|
||||||
|
"10": {
|
||||||
|
"copper": 0.575,
|
||||||
|
"coal": 0.2275,
|
||||||
|
"iron": 0.1675,
|
||||||
|
"gold": 0.0225,
|
||||||
|
"amber": 0.0075
|
||||||
|
},
|
||||||
|
"11": {
|
||||||
|
"copper": 0.6167,
|
||||||
|
"iron": 0.1783,
|
||||||
|
"coal": 0.175,
|
||||||
|
"gold": 0.025,
|
||||||
|
"amber": 0.005
|
||||||
|
},
|
||||||
|
"12": {
|
||||||
|
"copper": 0.6583,
|
||||||
|
"iron": 0.1892,
|
||||||
|
"coal": 0.1225,
|
||||||
|
"gold": 0.0275,
|
||||||
|
"amber": 0.0025
|
||||||
|
},
|
||||||
|
"13": {
|
||||||
|
"copper": 1.0
|
||||||
|
},
|
||||||
|
"14": {
|
||||||
|
"copper": 0.7,
|
||||||
|
"iron": 0.3
|
||||||
|
},
|
||||||
|
"15": {
|
||||||
|
"copper": 0.5832999999999999,
|
||||||
|
"iron": 0.195,
|
||||||
|
"amber": 0.1,
|
||||||
|
"coal": 0.0583,
|
||||||
|
"aluminium": 0.0333,
|
||||||
|
"gold": 0.025,
|
||||||
|
"silver": 0.005
|
||||||
|
},
|
||||||
|
"16": {
|
||||||
|
"copper": 0.525,
|
||||||
|
"iron": 0.1925,
|
||||||
|
"amber": 0.15,
|
||||||
|
"coal": 0.0525,
|
||||||
|
"aluminium": 0.05,
|
||||||
|
"gold": 0.0225,
|
||||||
|
"silver": 0.0075
|
||||||
|
},
|
||||||
|
"17": {
|
||||||
|
"copper": 0.4667,
|
||||||
|
"amber": 0.2,
|
||||||
|
"iron": 0.19,
|
||||||
|
"aluminium": 0.0667,
|
||||||
|
"coal": 0.0467,
|
||||||
|
"gold": 0.02,
|
||||||
|
"silver": 0.01
|
||||||
|
},
|
||||||
|
"18": {
|
||||||
|
"copper": 0.4083,
|
||||||
|
"amber": 0.25,
|
||||||
|
"iron": 0.1875,
|
||||||
|
"aluminium": 0.0833,
|
||||||
|
"coal": 0.0408,
|
||||||
|
"gold": 0.0175,
|
||||||
|
"silver": 0.0125
|
||||||
|
},
|
||||||
|
"19": {
|
||||||
|
"copper": 0.35,
|
||||||
|
"amber": 0.3,
|
||||||
|
"iron": 0.185,
|
||||||
|
"aluminium": 0.1,
|
||||||
|
"coal": 0.035,
|
||||||
|
"gold": 0.015,
|
||||||
|
"silver": 0.015
|
||||||
|
},
|
||||||
|
"20": {
|
||||||
|
"amber": 0.35,
|
||||||
|
"copper": 0.2917,
|
||||||
|
"iron": 0.1825,
|
||||||
|
"aluminium": 0.1167,
|
||||||
|
"coal": 0.0292,
|
||||||
|
"silver": 0.0175,
|
||||||
|
"gold": 0.0125
|
||||||
|
},
|
||||||
|
"21": {
|
||||||
|
"amber": 0.4,
|
||||||
|
"copper": 0.23329999999999998,
|
||||||
|
"iron": 0.18,
|
||||||
|
"aluminium": 0.1333,
|
||||||
|
"coal": 0.0233,
|
||||||
|
"silver": 0.02,
|
||||||
|
"gold": 0.01
|
||||||
|
},
|
||||||
|
"22": {
|
||||||
|
"amber": 0.45,
|
||||||
|
"iron": 0.1775,
|
||||||
|
"copper": 0.175,
|
||||||
|
"aluminium": 0.15,
|
||||||
|
"silver": 0.0225,
|
||||||
|
"coal": 0.0175,
|
||||||
|
"gold": 0.0075
|
||||||
|
},
|
||||||
|
"23": {
|
||||||
|
"amber": 0.5,
|
||||||
|
"iron": 0.175,
|
||||||
|
"aluminium": 0.16670000000000001,
|
||||||
|
"copper": 0.1167,
|
||||||
|
"silver": 0.025,
|
||||||
|
"coal": 0.011699999999999999,
|
||||||
|
"gold": 0.005
|
||||||
|
},
|
||||||
|
"24": {
|
||||||
|
"amber": 0.55,
|
||||||
|
"aluminium": 0.1833,
|
||||||
|
"iron": 0.1725,
|
||||||
|
"copper": 0.0583,
|
||||||
|
"silver": 0.0275,
|
||||||
|
"coal": 0.0058,
|
||||||
|
"gold": 0.0025
|
||||||
|
},
|
||||||
|
"25": {
|
||||||
|
"amber": 1.0
|
||||||
|
},
|
||||||
|
"26": {
|
||||||
|
"amber": 0.7,
|
||||||
|
"aluminium": 0.3
|
||||||
|
},
|
||||||
|
"27": {
|
||||||
|
"amber": 0.5,
|
||||||
|
"aluminium": 0.2667,
|
||||||
|
"iron": 0.1917,
|
||||||
|
"silver": 0.0417
|
||||||
|
},
|
||||||
|
"28": {
|
||||||
|
"amber": 0.45,
|
||||||
|
"aluminium": 0.3,
|
||||||
|
"iron": 0.2025,
|
||||||
|
"silver": 0.0475
|
||||||
|
},
|
||||||
|
"29": {
|
||||||
|
"amber": 0.4,
|
||||||
|
"aluminium": 0.3333,
|
||||||
|
"iron": 0.2133,
|
||||||
|
"silver": 0.0533
|
||||||
|
},
|
||||||
|
"30": {
|
||||||
|
"aluminium": 0.3667,
|
||||||
|
"amber": 0.35,
|
||||||
|
"iron": 0.2242,
|
||||||
|
"silver": 0.0592
|
||||||
|
},
|
||||||
|
"31": {
|
||||||
|
"aluminium": 0.4,
|
||||||
|
"amber": 0.3,
|
||||||
|
"iron": 0.235,
|
||||||
|
"silver": 0.065
|
||||||
|
},
|
||||||
|
"32": {
|
||||||
|
"aluminium": 0.43329999999999996,
|
||||||
|
"amber": 0.25,
|
||||||
|
"iron": 0.2458,
|
||||||
|
"silver": 0.0708
|
||||||
|
},
|
||||||
|
"33": {
|
||||||
|
"aluminium": 0.4667,
|
||||||
|
"iron": 0.25670000000000004,
|
||||||
|
"amber": 0.2,
|
||||||
|
"silver": 0.0767
|
||||||
|
},
|
||||||
|
"34": {
|
||||||
|
"aluminium": 0.5,
|
||||||
|
"iron": 0.2675,
|
||||||
|
"amber": 0.15,
|
||||||
|
"silver": 0.0825
|
||||||
|
},
|
||||||
|
"35": {
|
||||||
|
"aluminium": 0.5333,
|
||||||
|
"iron": 0.2783,
|
||||||
|
"amber": 0.1,
|
||||||
|
"silver": 0.0883
|
||||||
|
},
|
||||||
|
"36": {
|
||||||
|
"aluminium": 0.5667,
|
||||||
|
"iron": 0.2892,
|
||||||
|
"silver": 0.0942,
|
||||||
|
"amber": 0.05
|
||||||
|
},
|
||||||
|
"37": {
|
||||||
|
"aluminium": 1.0
|
||||||
|
},
|
||||||
|
"38": {
|
||||||
|
"aluminium": 0.7,
|
||||||
|
"iron": 0.3
|
||||||
|
},
|
||||||
|
"39": {
|
||||||
|
"aluminium": 0.5,
|
||||||
|
"iron": 0.25,
|
||||||
|
"silver": 0.1117,
|
||||||
|
"gold": 0.1,
|
||||||
|
"emerald": 0.0383
|
||||||
|
},
|
||||||
|
"40": {
|
||||||
|
"aluminium": 0.45,
|
||||||
|
"iron": 0.225,
|
||||||
|
"gold": 0.15,
|
||||||
|
"silver": 0.1175,
|
||||||
|
"emerald": 0.0575
|
||||||
|
},
|
||||||
|
"41": {
|
||||||
|
"aluminium": 0.4,
|
||||||
|
"gold": 0.2,
|
||||||
|
"iron": 0.2,
|
||||||
|
"silver": 0.1233,
|
||||||
|
"emerald": 0.0767
|
||||||
|
},
|
||||||
|
"42": {
|
||||||
|
"aluminium": 0.35,
|
||||||
|
"gold": 0.25,
|
||||||
|
"iron": 0.175,
|
||||||
|
"silver": 0.1292,
|
||||||
|
"emerald": 0.0958
|
||||||
|
},
|
||||||
|
"43": {
|
||||||
|
"aluminium": 0.3,
|
||||||
|
"gold": 0.3,
|
||||||
|
"iron": 0.15,
|
||||||
|
"silver": 0.135,
|
||||||
|
"emerald": 0.115
|
||||||
|
},
|
||||||
|
"44": {
|
||||||
|
"gold": 0.35,
|
||||||
|
"aluminium": 0.25,
|
||||||
|
"silver": 0.1408,
|
||||||
|
"emerald": 0.13419999999999999,
|
||||||
|
"iron": 0.125
|
||||||
|
},
|
||||||
|
"45": {
|
||||||
|
"gold": 0.4,
|
||||||
|
"aluminium": 0.2,
|
||||||
|
"emerald": 0.1533,
|
||||||
|
"silver": 0.1467,
|
||||||
|
"iron": 0.1
|
||||||
|
},
|
||||||
|
"46": {
|
||||||
|
"gold": 0.45,
|
||||||
|
"emerald": 0.1725,
|
||||||
|
"silver": 0.1525,
|
||||||
|
"aluminium": 0.15,
|
||||||
|
"iron": 0.075
|
||||||
|
},
|
||||||
|
"47": {
|
||||||
|
"gold": 0.5,
|
||||||
|
"emerald": 0.1917,
|
||||||
|
"silver": 0.1583,
|
||||||
|
"aluminium": 0.1,
|
||||||
|
"iron": 0.05
|
||||||
|
},
|
||||||
|
"48": {
|
||||||
|
"gold": 0.55,
|
||||||
|
"emerald": 0.2108,
|
||||||
|
"silver": 0.1642,
|
||||||
|
"aluminium": 0.05,
|
||||||
|
"iron": 0.025
|
||||||
|
},
|
||||||
|
"49": {
|
||||||
|
"gold": 1.0
|
||||||
|
},
|
||||||
|
"50": {
|
||||||
|
"gold": 0.7,
|
||||||
|
"emerald": 0.3
|
||||||
|
},
|
||||||
|
"51": {
|
||||||
|
"gold": 0.5,
|
||||||
|
"emerald": 0.2583,
|
||||||
|
"silver": 0.1417,
|
||||||
|
"ruby": 0.05,
|
||||||
|
"diamond": 0.0333,
|
||||||
|
"topaz": 0.0167
|
||||||
|
},
|
||||||
|
"52": {
|
||||||
|
"gold": 0.45,
|
||||||
|
"emerald": 0.2725,
|
||||||
|
"silver": 0.1275,
|
||||||
|
"ruby": 0.075,
|
||||||
|
"diamond": 0.05,
|
||||||
|
"topaz": 0.025
|
||||||
|
},
|
||||||
|
"53": {
|
||||||
|
"gold": 0.4,
|
||||||
|
"emerald": 0.2867,
|
||||||
|
"silver": 0.1133,
|
||||||
|
"ruby": 0.1,
|
||||||
|
"diamond": 0.0667,
|
||||||
|
"topaz": 0.0333
|
||||||
|
},
|
||||||
|
"54": {
|
||||||
|
"gold": 0.35,
|
||||||
|
"emerald": 0.30079999999999996,
|
||||||
|
"ruby": 0.125,
|
||||||
|
"silver": 0.0992,
|
||||||
|
"diamond": 0.0833,
|
||||||
|
"topaz": 0.0417
|
||||||
|
},
|
||||||
|
"55": {
|
||||||
|
"emerald": 0.315,
|
||||||
|
"gold": 0.3,
|
||||||
|
"ruby": 0.15,
|
||||||
|
"diamond": 0.1,
|
||||||
|
"silver": 0.085,
|
||||||
|
"topaz": 0.05
|
||||||
|
},
|
||||||
|
"57": {
|
||||||
|
"emerald": 0.3433,
|
||||||
|
"ruby": 0.2,
|
||||||
|
"gold": 0.2,
|
||||||
|
"diamond": 0.1333,
|
||||||
|
"topaz": 0.0667,
|
||||||
|
"silver": 0.0567
|
||||||
|
},
|
||||||
|
"58": {
|
||||||
|
"emerald": 0.3575,
|
||||||
|
"ruby": 0.225,
|
||||||
|
"gold": 0.15,
|
||||||
|
"diamond": 0.15,
|
||||||
|
"topaz": 0.075,
|
||||||
|
"silver": 0.0425
|
||||||
|
},
|
||||||
|
"60": {
|
||||||
|
"emerald": 0.3858,
|
||||||
|
"ruby": 0.275,
|
||||||
|
"diamond": 0.1833,
|
||||||
|
"topaz": 0.0917,
|
||||||
|
"gold": 0.05,
|
||||||
|
"silver": 0.014199999999999999
|
||||||
|
},
|
||||||
|
"61": {
|
||||||
|
"emerald": 1.0
|
||||||
|
},
|
||||||
|
"62": {
|
||||||
|
"emerald": 0.7,
|
||||||
|
"ruby": 0.3
|
||||||
|
},
|
||||||
|
"65": {
|
||||||
|
"ruby": 0.3333,
|
||||||
|
"emerald": 0.2667,
|
||||||
|
"topaz": 0.16670000000000001,
|
||||||
|
"diamond": 0.1333,
|
||||||
|
"sapphire": 0.0667,
|
||||||
|
"amethyst": 0.0333
|
||||||
|
},
|
||||||
|
"66": {
|
||||||
|
"ruby": 0.3417,
|
||||||
|
"emerald": 0.23329999999999998,
|
||||||
|
"topaz": 0.1833,
|
||||||
|
"diamond": 0.1167,
|
||||||
|
"sapphire": 0.0833,
|
||||||
|
"amethyst": 0.0417
|
||||||
|
},
|
||||||
|
"67": {
|
||||||
|
"ruby": 0.35,
|
||||||
|
"emerald": 0.2,
|
||||||
|
"topaz": 0.2,
|
||||||
|
"diamond": 0.1,
|
||||||
|
"sapphire": 0.1,
|
||||||
|
"amethyst": 0.05
|
||||||
|
},
|
||||||
|
"68": {
|
||||||
|
"ruby": 0.3583,
|
||||||
|
"topaz": 0.2167,
|
||||||
|
"emerald": 0.16670000000000001,
|
||||||
|
"sapphire": 0.1167,
|
||||||
|
"diamond": 0.0833,
|
||||||
|
"amethyst": 0.0583
|
||||||
|
},
|
||||||
|
"70": {
|
||||||
|
"ruby": 0.375,
|
||||||
|
"topaz": 0.25,
|
||||||
|
"sapphire": 0.15,
|
||||||
|
"emerald": 0.1,
|
||||||
|
"amethyst": 0.075,
|
||||||
|
"diamond": 0.05
|
||||||
|
},
|
||||||
|
"71": {
|
||||||
|
"ruby": 0.3833,
|
||||||
|
"topaz": 0.2667,
|
||||||
|
"sapphire": 0.16670000000000001,
|
||||||
|
"amethyst": 0.0833,
|
||||||
|
"emerald": 0.0667,
|
||||||
|
"diamond": 0.0333
|
||||||
|
},
|
||||||
|
"72": {
|
||||||
|
"ruby": 0.3917,
|
||||||
|
"topaz": 0.2833,
|
||||||
|
"sapphire": 0.1833,
|
||||||
|
"amethyst": 0.0917,
|
||||||
|
"emerald": 0.0333,
|
||||||
|
"diamond": 0.0167
|
||||||
|
},
|
||||||
|
"73": {
|
||||||
|
"ruby": 1.0
|
||||||
|
},
|
||||||
|
"74": {
|
||||||
|
"ruby": 0.7,
|
||||||
|
"topaz": 0.3
|
||||||
|
},
|
||||||
|
"75": {
|
||||||
|
"ruby": 0.3333,
|
||||||
|
"topaz": 0.25,
|
||||||
|
"sapphire": 0.16670000000000001,
|
||||||
|
"amethyst": 0.15,
|
||||||
|
"alexandrite": 0.045
|
||||||
|
},
|
||||||
|
"81": {
|
||||||
|
"amethyst": 0.3,
|
||||||
|
"alexandrite": 0.18
|
||||||
|
},
|
||||||
|
"83": {
|
||||||
|
"amethyst": 0.35,
|
||||||
|
"alexandrite": 0.225
|
||||||
|
},
|
||||||
|
"84": {
|
||||||
|
"amethyst": 0.375,
|
||||||
|
"alexandrite": 0.2475
|
||||||
|
},
|
||||||
|
"85": {
|
||||||
|
"amethyst": 1.0
|
||||||
|
},
|
||||||
|
"86": {
|
||||||
|
"amethyst": 0.7,
|
||||||
|
"alexandrite": 0.3
|
||||||
|
},
|
||||||
|
"87": {
|
||||||
|
"amethyst": 0.3333,
|
||||||
|
"alexandrite": 0.225
|
||||||
|
},
|
||||||
|
"88": {
|
||||||
|
"amethyst": 0.3,
|
||||||
|
"alexandrite": 0.2025
|
||||||
|
},
|
||||||
|
"89": {
|
||||||
|
"amethyst": 0.2667,
|
||||||
|
"obsidian": 0.2,
|
||||||
|
"alexandrite": 0.18
|
||||||
|
},
|
||||||
|
"90": {
|
||||||
|
"obsidian": 0.25,
|
||||||
|
"amethyst": 0.23329999999999998
|
||||||
|
},
|
||||||
|
"91": {
|
||||||
|
"obsidian": 0.3,
|
||||||
|
"amethyst": 0.2
|
||||||
|
},
|
||||||
|
"92": {
|
||||||
|
"obsidian": 0.35,
|
||||||
|
"amethyst": 0.16670000000000001
|
||||||
|
},
|
||||||
|
"93": {
|
||||||
|
"obsidian": 0.4,
|
||||||
|
"amethyst": 0.1333
|
||||||
|
},
|
||||||
|
"94": {
|
||||||
|
"obsidian": 0.45
|
||||||
|
},
|
||||||
|
"95": {
|
||||||
|
"obsidian": 0.5,
|
||||||
|
"diamond": 0.125
|
||||||
|
},
|
||||||
|
"96": {
|
||||||
|
"obsidian": 0.55,
|
||||||
|
"diamond": 0.1375,
|
||||||
|
"sapphire": 0.11
|
||||||
|
},
|
||||||
|
"97": {
|
||||||
|
"obsidian": 1.0
|
||||||
|
},
|
||||||
|
"98": {
|
||||||
|
"obsidian": 0.7,
|
||||||
|
"diamond": 0.3
|
||||||
|
},
|
||||||
|
"99": {
|
||||||
|
"obsidian": 0.5,
|
||||||
|
"diamond": 0.125,
|
||||||
|
"iron": 0.11,
|
||||||
|
"sapphire": 0.1
|
||||||
|
},
|
||||||
|
"100": {
|
||||||
|
"obsidian": 0.45,
|
||||||
|
"iron": 0.165,
|
||||||
|
"diamond": 0.1125,
|
||||||
|
"sapphire": 0.09
|
||||||
|
},
|
||||||
|
"101": {
|
||||||
|
"obsidian": 0.4,
|
||||||
|
"iron": 0.22,
|
||||||
|
"diamond": 0.1,
|
||||||
|
"sapphire": 0.08
|
||||||
|
},
|
||||||
|
"102": {
|
||||||
|
"obsidian": 0.35,
|
||||||
|
"iron": 0.275,
|
||||||
|
"diamond": 0.0875,
|
||||||
|
"coal": 0.0833,
|
||||||
|
"sapphire": 0.07
|
||||||
|
},
|
||||||
|
"103": {
|
||||||
|
"iron": 0.33,
|
||||||
|
"obsidian": 0.3,
|
||||||
|
"coal": 0.1,
|
||||||
|
"diamond": 0.075,
|
||||||
|
"silver": 0.06,
|
||||||
|
"sapphire": 0.06
|
||||||
|
},
|
||||||
|
"104": {
|
||||||
|
"iron": 0.385,
|
||||||
|
"obsidian": 0.25,
|
||||||
|
"coal": 0.1167,
|
||||||
|
"silver": 0.07,
|
||||||
|
"diamond": 0.0625,
|
||||||
|
"sapphire": 0.05
|
||||||
|
},
|
||||||
|
"105": {
|
||||||
|
"iron": 0.44,
|
||||||
|
"obsidian": 0.2,
|
||||||
|
"coal": 0.1333,
|
||||||
|
"silver": 0.08,
|
||||||
|
"diamond": 0.05,
|
||||||
|
"sapphire": 0.04
|
||||||
|
},
|
||||||
|
"106": {
|
||||||
|
"iron": 0.495,
|
||||||
|
"obsidian": 0.15,
|
||||||
|
"coal": 0.15,
|
||||||
|
"silver": 0.09,
|
||||||
|
"diamond": 0.0375,
|
||||||
|
"sapphire": 0.03
|
||||||
|
},
|
||||||
|
"107": {
|
||||||
|
"iron": 0.55,
|
||||||
|
"coal": 0.16670000000000001,
|
||||||
|
"obsidian": 0.1,
|
||||||
|
"silver": 0.1,
|
||||||
|
"diamond": 0.025,
|
||||||
|
"sapphire": 0.02
|
||||||
|
},
|
||||||
|
"108": {
|
||||||
|
"iron": 0.605,
|
||||||
|
"coal": 0.1833,
|
||||||
|
"silver": 0.11,
|
||||||
|
"obsidian": 0.05
|
||||||
|
},
|
||||||
|
"109": {
|
||||||
|
"iron": 0.66,
|
||||||
|
"coal": 0.2,
|
||||||
|
"silver": 0.12
|
||||||
|
},
|
||||||
|
"110": {
|
||||||
|
"iron": 0.655,
|
||||||
|
"coal": 0.1833,
|
||||||
|
"silver": 0.11
|
||||||
|
},
|
||||||
|
"111": {
|
||||||
|
"iron": 0.65,
|
||||||
|
"coal": 0.16670000000000001,
|
||||||
|
"silver": 0.1
|
||||||
|
},
|
||||||
|
"112": {
|
||||||
|
"iron": 0.645,
|
||||||
|
"coal": 0.15,
|
||||||
|
"silver": 0.09
|
||||||
|
},
|
||||||
|
"113": {
|
||||||
|
"iron": 0.64,
|
||||||
|
"coal": 0.1333,
|
||||||
|
"silver": 0.08
|
||||||
|
},
|
||||||
|
"114": {
|
||||||
|
"iron": 0.635,
|
||||||
|
"coal": 0.1167,
|
||||||
|
"gold": 0.0833
|
||||||
|
},
|
||||||
|
"115": {
|
||||||
|
"iron": 0.63,
|
||||||
|
"coal": 0.1,
|
||||||
|
"gold": 0.1
|
||||||
|
},
|
||||||
|
"116": {
|
||||||
|
"iron": 0.625,
|
||||||
|
"gold": 0.1167
|
||||||
|
},
|
||||||
|
"117": {
|
||||||
|
"iron": 0.62,
|
||||||
|
"gold": 0.1333
|
||||||
|
},
|
||||||
|
"118": {
|
||||||
|
"iron": 0.615,
|
||||||
|
"gold": 0.15
|
||||||
|
},
|
||||||
|
"119": {
|
||||||
|
"iron": 1.0
|
||||||
|
},
|
||||||
|
"120": {
|
||||||
|
"iron": 0.5,
|
||||||
|
"coal": 0.5
|
||||||
|
},
|
||||||
|
"0": {
|
||||||
|
"coal": 0,
|
||||||
|
"copper": 0,
|
||||||
|
"iron": 0,
|
||||||
|
"amber": 0,
|
||||||
|
"gold": 0,
|
||||||
|
"aluminium": 0,
|
||||||
|
"silver": 0,
|
||||||
|
"emerald": 0,
|
||||||
|
"ruby": 0,
|
||||||
|
"diamond": 0,
|
||||||
|
"topaz": 0,
|
||||||
|
"sapphire": 0,
|
||||||
|
"amethyst": 0,
|
||||||
|
"alexandrite": 0,
|
||||||
|
"obsidian": 0
|
||||||
|
}
|
||||||
|
}
|
68
modules/deeptownOptimizer/optimizer.py
Normal file
68
modules/deeptownOptimizer/optimizer.py
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
import copy
|
||||||
|
import datetime
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
class Optimizer():
|
||||||
|
def __init__(self):
|
||||||
|
self.mines = {}
|
||||||
|
self.items = {}
|
||||||
|
# get mine stats
|
||||||
|
with open(os.path.join("modules", "deeptownOptimizer", "mines.json")) as mines:
|
||||||
|
self.mines = json.load(mines)
|
||||||
|
# get items stats
|
||||||
|
with open(os.path.join("modules", "deeptownOptimizer", "items.json")) as items:
|
||||||
|
self.items = json.load(items)
|
||||||
|
# Add zero values to mine stat
|
||||||
|
ores = self.mines["0"].keys()
|
||||||
|
for area, stats in self.mines.items():
|
||||||
|
for ore in ores:
|
||||||
|
if self.mines[area].get(ore) is None:
|
||||||
|
self.mines[area].update({ore: 0})
|
||||||
|
|
||||||
|
def best_mines(self, ore):
|
||||||
|
if ore not in self.mines["0"].keys():
|
||||||
|
raise ValueError("{ore} is not a correct ore.".format(ore=ore))
|
||||||
|
ordered_mines = [(k, v) for k, v in self.mines.items()]
|
||||||
|
ordered_mines.sort(key=lambda x: x[1][ore], reverse=True)
|
||||||
|
return ordered_mines
|
||||||
|
|
||||||
|
def to_make(self, item, quantity=1):
|
||||||
|
if item not in self.items.keys():
|
||||||
|
raise ValueError("{item} is not a correct item.".format(item=item))
|
||||||
|
if self.items[item]["quantity"] != 0:
|
||||||
|
number_of_craft = int(quantity / self.items[item]["quantity"])
|
||||||
|
else:
|
||||||
|
number_of_craft = int(quantity)
|
||||||
|
if number_of_craft % 1 != 0:
|
||||||
|
number_of_craft = int((number_of_craft // 1) + 1)
|
||||||
|
time = self.items[item]["time"] * number_of_craft
|
||||||
|
value = self.items[item]["value"] * number_of_craft * self.items[item]["quantity"]
|
||||||
|
needed = {}
|
||||||
|
for resource, quantity in self.items[item]["needed"].items():
|
||||||
|
needed.update({resource: quantity * number_of_craft})
|
||||||
|
return {"time": time, "value": value, "needed": needed}
|
||||||
|
|
||||||
|
def recursive_to_make(self, item, quantity=1):
|
||||||
|
if item in self.items.keys():
|
||||||
|
needed = self.to_make(item, quantity)
|
||||||
|
results = [(self.items[item]["type"], item, quantity, needed["time"])]
|
||||||
|
for needed_item, needed_quantity in needed["needed"].items():
|
||||||
|
needed_result = self.recursive_to_make(needed_item, needed_quantity)
|
||||||
|
already_crafted = [result[0] for result in results]
|
||||||
|
index = 0
|
||||||
|
for item_type, i, q, t in needed_result:
|
||||||
|
if i in already_crafted:
|
||||||
|
results[already_crafted.index(i)] = (
|
||||||
|
results[already_crafted.index(i)][0],
|
||||||
|
results[already_crafted.index(i)][1],
|
||||||
|
results[already_crafted.index(i)][2] + q,
|
||||||
|
results[already_crafted.index(i)][3] + t
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
results.append((item_type, i, q, t))
|
||||||
|
index += 1
|
||||||
|
return results
|
||||||
|
else:
|
||||||
|
return [(self.items[item]["type"], item, quantity, 0)]
|
203
modules/deeptownOptimizer/update_data.py
Normal file
203
modules/deeptownOptimizer/update_data.py
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
import json
|
||||||
|
import os
|
||||||
|
from fs.osfs import OSFS
|
||||||
|
import re
|
||||||
|
import requests
|
||||||
|
|
||||||
|
fileSystem = None
|
||||||
|
|
||||||
|
|
||||||
|
def format_string(text):
|
||||||
|
text = text.replace(" ", "").replace("-", "").replace("_", "").lower()
|
||||||
|
return str(text)
|
||||||
|
|
||||||
|
|
||||||
|
def get_all_item_urls():
|
||||||
|
page = requests.get("https://deeptownguide.com/Items")
|
||||||
|
item_urls = []
|
||||||
|
if page.status_code == 200:
|
||||||
|
regex = re.compile(r"/Items/Details/[0-9]+/([a-zA-Z0-9]|-)*", re.MULTILINE)
|
||||||
|
item_urls_match = regex.finditer(str(page.content))
|
||||||
|
for match in item_urls_match:
|
||||||
|
if "https://deeptownguide.com" + match.group(0) not in item_urls:
|
||||||
|
item_urls.append("https://deeptownguide.com" + match.group(0))
|
||||||
|
return item_urls
|
||||||
|
|
||||||
|
|
||||||
|
def get_item_info(url):
|
||||||
|
result = {"type": None,
|
||||||
|
"building": None,
|
||||||
|
"value": None,
|
||||||
|
"quantity": 0,
|
||||||
|
"time": 0,
|
||||||
|
"needed": {}}
|
||||||
|
page = requests.get(url)
|
||||||
|
texte = str(page.content).replace(" ", "").replace("\n", "").replace(r"\n", "")
|
||||||
|
|
||||||
|
# regex used to find infos
|
||||||
|
type_regex = re.compile(r"<strong>Type</strong><br/>\w*")
|
||||||
|
value_regex = re.compile(r"<strong>SellPrice</strong><br/>([0-9]|,)*")
|
||||||
|
building_regex = re.compile(r"<divclass=\"panelpanel-default\"><divclass=\"panel-headingtext-center\"><h4style=\"di"
|
||||||
|
r"splay:inline;\"><spanclass=\"text-capitalize\">\w*</span>iscreatedfromthisrecipe</h4>"
|
||||||
|
r"</div><divclass=\"panel-body\"><divclass=\"table-responsivecol-sm-12\"><tableclass=\""
|
||||||
|
r"tabletable-striped\"><thead><tr><th>BuildingName</th><th>UnlockedatDepth</th><th>Cost"
|
||||||
|
r"ToUnlock</th><th>TimeRequired</th><th>AmountCreated</th><th>ItemsRequired</th></tr></"
|
||||||
|
r"thead><tbody><tr><td><ahref=\"/Buildings/Details/[0-9]+/\w+")
|
||||||
|
time_regex = re.compile(r"<divclass=\"panelpanel-default\"><divclass=\"panel-headingtext-center\"><h4style=\"displa"
|
||||||
|
r"y:inline;\"><spanclass=\"text-capitalize\">\w*</span>iscreatedfromthisrecipe</h4></div><d"
|
||||||
|
r"ivclass=\"panel-body\"><divclass=\"table-responsivecol-sm-12\"><tableclass=\"tabletable-s"
|
||||||
|
r"triped\"><thead><tr><th>BuildingName</th><th>UnlockedatDepth</th><th>CostToUnlock</th><th"
|
||||||
|
r">TimeRequired</th><th>AmountCreated</th><th>ItemsRequired</th></tr></thead><tbody><tr><td"
|
||||||
|
r"><ahref=\"/Buildings/Details/[0-9]+/\w+\"><imgsrc=\"/images/placeholder\.png\"data-src=\""
|
||||||
|
r"/images/ui/(\w|[0-9]|-)+\.png\"alt=\"\w*\"class=\"Icon36pxlazyload\"/>\w*</a></td><td>[0-"
|
||||||
|
r"9]*</td><td>([0-9]|,)*</td><td>([0-9]+|Seconds?|Minutes?|Hours?)+")
|
||||||
|
quantity_regex = re.compile(r"<divclass=\"panelpanel-default\"><divclass=\"panel-headingtext-center\"><h4style=\"di"
|
||||||
|
r"splay:inline;\"><spanclass=\"text-capitalize\">\w*</span>iscreatedfromthisrecipe</h4>"
|
||||||
|
r"</div><divclass=\"panel-body\"><divclass=\"table-responsivecol-sm-12\"><tableclass=\""
|
||||||
|
r"tabletable-striped\"><thead><tr><th>BuildingName</th><th>UnlockedatDepth</th><th>Cost"
|
||||||
|
r"ToUnlock</th><th>TimeRequired</th><th>AmountCreated</th><th>ItemsRequired</th></tr></"
|
||||||
|
r"thead><tbody><tr><td><ahref=\"/Buildings/Details/[0-9]+/\w+\"><imgsrc=\"/images/place"
|
||||||
|
r"holder\.png\"data-src=\"/images/ui/(\w|[0-9]|-)+\.png\"alt=\"\w*\"class=\"Icon36pxlaz"
|
||||||
|
r"yload\"/>\w*</a></td><td>[0-9]*</td><td>([0-9]|,)*</td><td>([0-9]+|Seconds?|Minutes?|"
|
||||||
|
r"Hours?)+</td><td>[0-9]+")
|
||||||
|
needed_regex = re.compile(r"</td><td>(<ahref=\"/Items/Details/[0-9]+/(\w|-)+\"><imgsrc=\"/images/placeholder.png\"d"
|
||||||
|
r"ata-src=\"/images/ui/([a-zA-Z]|-|\.)+\"alt=\"\w*\"class=\"\w*\"/>(\w|,)+</a><br/>)+")
|
||||||
|
|
||||||
|
type_iter = type_regex.finditer(str(texte))
|
||||||
|
value_iter = value_regex.finditer(str(texte))
|
||||||
|
building_iter = building_regex.finditer(str(texte))
|
||||||
|
time_iter = time_regex.finditer(str(texte))
|
||||||
|
quantity_iter = quantity_regex.finditer(str(texte))
|
||||||
|
needed_iter = needed_regex.finditer(str(texte))
|
||||||
|
|
||||||
|
# Extract value from regex result
|
||||||
|
result["type"] = format_string(re.sub(r"<strong>Type</strong><br/>", "", str(type_iter.__next__().group(0))))
|
||||||
|
result["value"] = int(
|
||||||
|
re.sub(r"<strong>SellPrice</strong><br/>", "", str(value_iter.__next__().group(0))).replace(
|
||||||
|
",", ""))
|
||||||
|
# Extract for recipe
|
||||||
|
try:
|
||||||
|
result["building"] = format_string(re.sub(
|
||||||
|
r"<divclass=\"panelpanel-default\"><divclass=\"panel-headingtext-center\"><h4style=\"di"
|
||||||
|
r"splay:inline;\"><spanclass=\"text-capitalize\">\w*</span>iscreatedfromthisrecipe</h4>"
|
||||||
|
r"</div><divclass=\"panel-body\"><divclass=\"table-responsivecol-sm-12\"><tableclass=\""
|
||||||
|
r"tabletable-striped\"><thead><tr><th>BuildingName</th><th>UnlockedatDepth</th><th>Cost"
|
||||||
|
r"ToUnlock</th><th>TimeRequired</th><th>AmountCreated</th><th>ItemsRequired</th></tr></"
|
||||||
|
r"thead><tbody><tr><td><ahref=\"/Buildings/Details/[0-9]+/",
|
||||||
|
"",
|
||||||
|
str(building_iter.__next__().group(0))))
|
||||||
|
time_str = str(
|
||||||
|
re.sub(r"<divclass=\"panelpanel-default\"><divclass=\"panel-headingtext-center\"><h4style=\"displa"
|
||||||
|
r"y:inline;\"><spanclass=\"text-capitalize\">\w*</span>iscreatedfromthisrecipe</h4></div><d"
|
||||||
|
r"ivclass=\"panel-body\"><divclass=\"table-responsivecol-sm-12\"><tableclass=\"tabletable-s"
|
||||||
|
r"triped\"><thead><tr><th>BuildingName</th><th>UnlockedatDepth</th><th>CostToUnlock</th><th"
|
||||||
|
r">TimeRequired</th><th>AmountCreated</th><th>ItemsRequired</th></tr></thead><tbody><tr><td"
|
||||||
|
r"><ahref=\"/Buildings/Details/[0-9]+/\w+\"><imgsrc=\"/images/placeholder\.png\"data-src=\""
|
||||||
|
r"/images/ui/(\w|[0-9]|-)+\.png\"alt=\"\w*\"class=\"Icon36pxlazyload\"/>\w*</a></td><td>[0-"
|
||||||
|
r"9]*</td><td>([0-9]|,)*</td><td>",
|
||||||
|
"",
|
||||||
|
str(time_iter.__next__().group(0))))
|
||||||
|
# Time:
|
||||||
|
time_str = time_str.replace("s", "") # remove plural
|
||||||
|
time_list = re.split("([0-9]+)", time_str)
|
||||||
|
if time_list[0] == '':
|
||||||
|
del time_list[0]
|
||||||
|
time = 0
|
||||||
|
for number, unit in zip(time_list[::2], time_list[1::2]):
|
||||||
|
if unit == "Second":
|
||||||
|
time += int(number)
|
||||||
|
elif unit == "Minute":
|
||||||
|
time += int(number) * 60
|
||||||
|
elif unit == "Hour":
|
||||||
|
time += int(number) * 60 * 60
|
||||||
|
result['time'] = int(time)
|
||||||
|
|
||||||
|
result["quantity"] = int(str(re.sub("<divclass=\"panelpanel-default\"><divclass=\"panel-headingtext-center\"><h"
|
||||||
|
"4style=\"display:inline;\"><spanclass=\"text-capitalize\">\w*</span>iscrea"
|
||||||
|
"tedfromthisrecipe</h4></div><divclass=\"panel-body\"><divclass=\"table-res"
|
||||||
|
"ponsivecol-sm-12\"><tableclass=\"tabletable-striped\"><thead><tr><th>Build"
|
||||||
|
"ingName</th><th>UnlockedatDepth</th><th>CostToUnlock</th><th>TimeRequired<"
|
||||||
|
"/th><th>AmountCreated</th><th>ItemsRequired</th></tr></thead><tbody><tr><t"
|
||||||
|
"d><ahref=\"/Buildings/Details/[0-9]+/\w+\"><imgsrc=\"/images/placeholder\."
|
||||||
|
"png\"data-src=\"/images/ui/(\w|[0-9]|-)+\.png\"alt=\"\w*\"class=\"Icon36px"
|
||||||
|
"lazyload\"/>\w*</a></td><td>([0-9]|,)*</td><td>([0-9]|,)*</td><td>([0-9]+|Seconds?"
|
||||||
|
"|Minutes?|Hours?)+</td><td>",
|
||||||
|
"",
|
||||||
|
quantity_iter.__next__().group(0))))
|
||||||
|
needed_text = re.sub(r"</td><td>", "", needed_iter.__next__().group(0))
|
||||||
|
|
||||||
|
item_name_iter = re.finditer(r"<ahref=\"/Items/Details/[0-9]+/(\w|-)+", str(needed_text))
|
||||||
|
item_quantity_iter = re.finditer(r"class=\"\w*\"/>[A-Za-z]+([0-9]|,)+", str(needed_text))
|
||||||
|
|
||||||
|
for item_name_match, item_quantity_match in zip(item_name_iter, item_quantity_iter):
|
||||||
|
item_name = re.sub(r"<ahref=\"/Items/Details/[0-9]+/", "", item_name_match.group(0))
|
||||||
|
item_quantity = int(
|
||||||
|
re.sub(r"class=\"\w*\"/>[A-Za-z]+", "", item_quantity_match.group(0)).replace(",", "").replace(
|
||||||
|
".", ""))
|
||||||
|
result["needed"].update({format_string(item_name): item_quantity})
|
||||||
|
|
||||||
|
|
||||||
|
except StopIteration:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def get_sector_info():
|
||||||
|
page = requests.get("https://deeptownguide.com/Areas/Resources")
|
||||||
|
texte = str(page.content).replace(" ", "").replace("\n", "").replace(r"\n", "")
|
||||||
|
line_regex = re.compile(r"<tr><tdclass=\"([a-zA-Z]|-)*\">[0-9]+</td>(<td>(<ahref=\"/Items/Details/[0-9]+/\w+\"><img"
|
||||||
|
r"src=\"/images/placeholder\.png\"data-src=\"/images/ui/(\w|-)+\.png\"alt=\"\w*\"class=\"\w"
|
||||||
|
r"*\"/><br/>\w*</a><br/>([0-9]|\.|%)+| )</td>)+")
|
||||||
|
num_regex = re.compile(r"<tr><tdclass=\"([a-zA-Z]|-)*\">[0-9]+")
|
||||||
|
item_regex = re.compile(r"<td>(<ahref=\"/Items/Details/[0-9]+/\w+\"><imgsrc=\"/images/placeholder\.png\"data-src=\""
|
||||||
|
r"/images/ui/(\w|-)+\.png\"alt=\"\w*\"class=\"\w*\"/><br/>\w*</a><br/>([0-9]|\.|%)+| )"
|
||||||
|
r"</td>")
|
||||||
|
item_name_regex = re.compile(r"(<ahref=\"/Items/Details/[0-9]+/\w+| )")
|
||||||
|
quantity_regex = re.compile(r"<br/>([0-9]|\.)+")
|
||||||
|
|
||||||
|
line_iter = line_regex.finditer(texte)
|
||||||
|
|
||||||
|
etages = {}
|
||||||
|
liste_items = []
|
||||||
|
for line in line_iter:
|
||||||
|
etage_iter = num_regex.finditer(line.group(0))
|
||||||
|
etage = int(re.sub(r"<tr><tdclass=\"text-bold\">", "", etage_iter.__next__().group(0)))
|
||||||
|
item_iter = item_regex.finditer(line.group(0))
|
||||||
|
items = {}
|
||||||
|
for item in item_iter:
|
||||||
|
name_iter = item_name_regex.finditer(item.group(0))
|
||||||
|
name = str(re.sub(r"(<ahref=\"/Items/Details/[0-9]+/| )", "", name_iter.__next__().group(0)))
|
||||||
|
if name != "":
|
||||||
|
quantity_iter = quantity_regex.finditer(item.group(0))
|
||||||
|
quantity = float(re.sub("<br/>", "", quantity_iter.__next__().group(0))) / 100
|
||||||
|
items.update({name: quantity})
|
||||||
|
if name not in liste_items:
|
||||||
|
liste_items.append(name)
|
||||||
|
etages.update({str(etage): items})
|
||||||
|
etages.update({"0": {name: 0 for name in liste_items}})
|
||||||
|
return etages
|
||||||
|
|
||||||
|
|
||||||
|
def update_data():
|
||||||
|
items = {}
|
||||||
|
urls_item = get_all_item_urls()
|
||||||
|
print(len(urls_item))
|
||||||
|
a = 0
|
||||||
|
for item_url in urls_item:
|
||||||
|
a += 1
|
||||||
|
items.update({
|
||||||
|
str(format_string(re.sub("https://deeptownguide.com/Items/Details/[0-9]+/", "", item_url))):
|
||||||
|
get_item_info(item_url)
|
||||||
|
})
|
||||||
|
print(a * 100 / len(urls_item), "%")
|
||||||
|
with open('items.json', "w") as dest_file:
|
||||||
|
json.dump(items, dest_file)
|
||||||
|
with open('mines.json', "w") as dest_file:
|
||||||
|
json.dump(get_sector_info(), dest_file)
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print(get_item_info('https://deeptownguide.com/Items/Details/702/stage-ii'))
|
||||||
|
update_data()
|
67
modules/directAccessDB.py
Normal file
67
modules/directAccessDB.py
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
import os
|
||||||
|
import time
|
||||||
|
from textwrap import wrap
|
||||||
|
|
||||||
|
import discord
|
||||||
|
import traductions as tr
|
||||||
|
|
||||||
|
|
||||||
|
def to_str(entier):
|
||||||
|
return str(entier).replace("1", "a").replace("2", "b").replace("3", "c").replace("4", "d").replace("5", "e") \
|
||||||
|
.replace("6", "f").replace("7", "g").replace("8", "h").replace("9", "i").replace("0", "j")
|
||||||
|
|
||||||
|
def pp(cursor, data=None, rowlens=0):
|
||||||
|
d = cursor.description
|
||||||
|
if not d:
|
||||||
|
return "#### NO RESULTS ###"
|
||||||
|
names = []
|
||||||
|
lengths = []
|
||||||
|
rules = []
|
||||||
|
if not data:
|
||||||
|
data = cursor.fetchall()
|
||||||
|
for dd in d: # iterate over description
|
||||||
|
l = dd[1]
|
||||||
|
if not l:
|
||||||
|
l = 12 # or default arg ...
|
||||||
|
l = min(l, len(dd[0])) # Handle long names
|
||||||
|
names.append(dd[0])
|
||||||
|
print(dd)
|
||||||
|
lengths.append(l)
|
||||||
|
for col in range(len(lengths)):
|
||||||
|
if rowlens:
|
||||||
|
rls = [len(row[col]) for row in data if row[col]]
|
||||||
|
lengths[col] = max([lengths[col]]+rls)
|
||||||
|
rules.append("-"*lengths[col])
|
||||||
|
format = " ".join(["%%-%ss" % l for l in lengths])
|
||||||
|
result = [format % tuple(names)]
|
||||||
|
result.append(format % tuple(rules))
|
||||||
|
for row in data:
|
||||||
|
result.append(format % tuple([str(v) for v in row.values()]))
|
||||||
|
return "\n".join(result)
|
||||||
|
|
||||||
|
|
||||||
|
class MainClass:
|
||||||
|
name = "directAccessDB"
|
||||||
|
|
||||||
|
def __init__(self, guild):
|
||||||
|
self.guild = guild
|
||||||
|
|
||||||
|
async def execute(self, msg, command, args):
|
||||||
|
if msg.author.id not in self.guild.config["master_admins"]:
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["PermissionError"])
|
||||||
|
return
|
||||||
|
with self.guild.bot.database.cursor() as cursor:
|
||||||
|
print(' '.join(args))
|
||||||
|
cursor.execute(' '.join(args))
|
||||||
|
self.guild.bot.database.commit()
|
||||||
|
string = pp(cursor)
|
||||||
|
for to_send in string.split("\n"):
|
||||||
|
await msg.channel.send("```"+to_send+"```")
|
||||||
|
|
||||||
|
|
||||||
|
async def on_message(self, msg):
|
||||||
|
if msg.content.startswith(self.guild.config["prefix"] * 2):
|
||||||
|
command, *args = msg.content.lstrip(self.guild.config["prefix"]).split(" ")
|
||||||
|
if command == "execute":
|
||||||
|
await self.execute(msg, command, args)
|
||||||
|
return
|
@ -45,7 +45,7 @@ class MainClass:
|
|||||||
texte += "\n"
|
texte += "\n"
|
||||||
texte += exemple[0].format(prefix=self.guild.config["prefix"])
|
texte += exemple[0].format(prefix=self.guild.config["prefix"])
|
||||||
texte += ": "
|
texte += ": "
|
||||||
texte += exemple[1]
|
texte += exemple[1].format(prefix=self.guild.config["prefix"])
|
||||||
await msg.channel.send(texte)
|
await msg.channel.send(texte)
|
||||||
else:
|
else:
|
||||||
await msg.channe.send(tr.tr[self.guild.config["lang"]]["errors"]["CommandNotFoundError"].format(command=fonction))
|
await msg.channe.send(tr.tr[self.guild.config["lang"]]["errors"]["CommandNotFoundError"].format(command=fonction))
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
|
||||||
import fs
|
|
||||||
|
|
||||||
import traductions as tr
|
import traductions as tr
|
||||||
|
|
||||||
|
|
||||||
|
384
modules/survey.py
Normal file
384
modules/survey.py
Normal file
@ -0,0 +1,384 @@
|
|||||||
|
import os
|
||||||
|
import time
|
||||||
|
|
||||||
|
import discord
|
||||||
|
import traductions as tr
|
||||||
|
|
||||||
|
|
||||||
|
def to_str(entier):
|
||||||
|
return str(entier).replace("1", "a").replace("2", "b").replace("3", "c").replace("4", "d").replace("5", "e") \
|
||||||
|
.replace("6", "f").replace("7", "g").replace("8", "h").replace("9", "i").replace("0", "j")
|
||||||
|
|
||||||
|
|
||||||
|
class MainClass:
|
||||||
|
name = "survey"
|
||||||
|
|
||||||
|
def __init__(self, guild):
|
||||||
|
self.guild = guild
|
||||||
|
self.current_surveys = {}
|
||||||
|
self.create_table()
|
||||||
|
|
||||||
|
def create_table(self):
|
||||||
|
with self.guild.bot.database.cursor() as cursor:
|
||||||
|
create_survey_table_sql = "CREATE TABLE IF NOT EXISTS {guild_id}surveys (" \
|
||||||
|
" id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY," \
|
||||||
|
" title VARCHAR(2000) NOT NULL," \
|
||||||
|
" depart BIGINT," \
|
||||||
|
" duree BIGINT" \
|
||||||
|
");".format(guild_id=self.guild.id)
|
||||||
|
create_choices_table_sql = "CREATE TABLE IF NOT EXISTS {guild_id}survey_choices (" \
|
||||||
|
" id int(20) NOT NULL AUTO_INCREMENT PRIMARY KEY," \
|
||||||
|
" survey int(20) NOT NULL," \
|
||||||
|
" content VARCHAR(1000)," \
|
||||||
|
" attachment BLOB(67108864)," \
|
||||||
|
" attachment_name VARCHAR(1000)" \
|
||||||
|
");".format(guild_id=self.guild.id)
|
||||||
|
create_vote_table_sql = "CREATE TABLE IF NOT EXISTS {guild_id}survey_votes (" \
|
||||||
|
" id int NOT NULL AUTO_INCREMENT PRIMARY KEY," \
|
||||||
|
" choice BIGINT NOT NULL," \
|
||||||
|
" user_id VARCHAR(20) NOT NULL" \
|
||||||
|
");".format(guild_id=self.guild.id)
|
||||||
|
cursor.execute(create_choices_table_sql)
|
||||||
|
cursor.execute(create_survey_table_sql)
|
||||||
|
cursor.execute(create_vote_table_sql)
|
||||||
|
self.guild.bot.database.commit()
|
||||||
|
|
||||||
|
async def vote(self, msg, command, args):
|
||||||
|
try:
|
||||||
|
await msg.delete()
|
||||||
|
except discord.Forbidden:
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["DiscordForbiddenError"])
|
||||||
|
if len(args) != 1:
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["NotEnoughParamError"])
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
id_vote = int(args[0])
|
||||||
|
except ValueError:
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["NotANumberError"])
|
||||||
|
return
|
||||||
|
|
||||||
|
with self.guild.bot.database.cursor() as cursor:
|
||||||
|
# récupération de l'id du sondage
|
||||||
|
select_choice_sql = "SELECT survey FROM `{guild_id}survey_choices` WHERE id = %s;".format(
|
||||||
|
guild_id=self.guild.id)
|
||||||
|
cursor.execute(select_choice_sql, (id_vote))
|
||||||
|
survey_id = [r["survey"] for r in cursor.fetchall()]
|
||||||
|
|
||||||
|
if len(survey_id) == 0: # Le choix n'existe pas
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["SurveyNotExistsError"])
|
||||||
|
return
|
||||||
|
|
||||||
|
with self.guild.bot.database.cursor() as cursor:
|
||||||
|
# Récupération de la date de fin du sondage
|
||||||
|
select_survey_sql = "SELECT depart, duree FROM `{guild_id}surveys` WHERE id=%s;".format(
|
||||||
|
guild_id=self.guild.id)
|
||||||
|
cursor.execute(select_survey_sql, (survey_id))
|
||||||
|
r = cursor.fetchone()
|
||||||
|
if r["depart"] is not None:
|
||||||
|
fin = r["depart"] + r["duree"]
|
||||||
|
else:
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["NotYetPostedError"])
|
||||||
|
return
|
||||||
|
# Liste des précédents votes
|
||||||
|
select_prec_votes_sql = "SELECT choice FROM `{guild_id}survey_votes` WHERE user_id=%s;".format(
|
||||||
|
guild_id=self.guild.id)
|
||||||
|
cursor.execute(select_prec_votes_sql, (msg.author.id))
|
||||||
|
list_votes = [r["choice"] for r in cursor.fetchall()]
|
||||||
|
# Liste des précédents sondages votés
|
||||||
|
list_surveys_sql = "SELECT survey FROM `{guild_id}survey_choices` WHERE id=%s".format(
|
||||||
|
guild_id=self.guild.id)
|
||||||
|
list_surveys = []
|
||||||
|
for id_choice in list_votes:
|
||||||
|
cursor.execute(list_surveys_sql, (id_choice))
|
||||||
|
list_surveys.append(cursor.fetchone()["survey"])
|
||||||
|
|
||||||
|
if fin < time.time(): # Sondage terminé
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["SurveyCompletedError"])
|
||||||
|
return
|
||||||
|
if survey_id[0] in list_surveys: # Déjà voté
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["AlreadyVote"])
|
||||||
|
return
|
||||||
|
|
||||||
|
# On peu voter, on insère dans la bdd
|
||||||
|
with self.guild.bot.database.cursor() as cursor:
|
||||||
|
sql_insert = "INSERT INTO `{guild_id}survey_votes` (choice, user_id) VALUES (%s, %s);" \
|
||||||
|
.format(guild_id=self.guild.id)
|
||||||
|
cursor.execute(sql_insert, (id_vote, msg.author.id))
|
||||||
|
self.guild.bot.database.commit()
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["modules"]["survey"]["vote"]
|
||||||
|
.format(id_auteur=msg.author.id))
|
||||||
|
|
||||||
|
async def add_choice(self, msg, command, args):
|
||||||
|
# L'utilisateur est un administrateur du bot
|
||||||
|
if msg.author.id not in self.guild.config["master_admins"]:
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["PermissionError"])
|
||||||
|
return
|
||||||
|
# Vérification du nombre de paramètres
|
||||||
|
if len(args) < 2 or (len(args) < 1 and len(msg.attachments) < 1):
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["NotEnoughParamError"])
|
||||||
|
return
|
||||||
|
|
||||||
|
try: # Tentative de conversion en nombre
|
||||||
|
survey_id = int(args[0])
|
||||||
|
except ValueError:
|
||||||
|
msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["NotANumberError"])
|
||||||
|
return
|
||||||
|
|
||||||
|
# Vérification de l'existance du sondage
|
||||||
|
with self.guild.bot.database.cursor() as cursor:
|
||||||
|
sql_id = "SELECT id FROM `{guild_id}surveys`".format(guild_id=self.guild.id)
|
||||||
|
cursor.execute(sql_id, ())
|
||||||
|
liste_id = [r["id"] for r in cursor.fetchall()]
|
||||||
|
|
||||||
|
if survey_id not in liste_id: # Le sondage n'existe pas
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["SurveyNotExistsError"])
|
||||||
|
return
|
||||||
|
|
||||||
|
# Verification que le sondage n'a pas déjà été publié
|
||||||
|
with self.guild.bot.database.cursor() as cursor:
|
||||||
|
sql_depart = "SELECT depart FROM `{guild_id}surveys` WHERE id = %s".format(guild_id=self.guild.id)
|
||||||
|
cursor.execute(sql_depart, (survey_id))
|
||||||
|
depart = cursor.fetchone()["depart"]
|
||||||
|
if depart is not None:
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["AlreadySendSurvey"])
|
||||||
|
return
|
||||||
|
|
||||||
|
content = " ".join(args[1:])
|
||||||
|
# Ecriture du fichier temporaire
|
||||||
|
with open("temp_attachement" + str(survey_id), "w") as temp_file:
|
||||||
|
temp_file.write("")
|
||||||
|
file_name = ""
|
||||||
|
# Si un fichier est présent dans le message on le sauvegarde
|
||||||
|
if len(msg.attachments) > 0:
|
||||||
|
attachment = msg.attachments[0]
|
||||||
|
if attachment.size > 67108864:
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["AttachementTooBigError"])
|
||||||
|
return
|
||||||
|
with open("temp_attachement" + str(survey_id), "wb") as temp_file:
|
||||||
|
await attachment.save(temp_file)
|
||||||
|
file_name = attachment.filename
|
||||||
|
# On insère le choix dans la base de données
|
||||||
|
with self.guild.bot.database.cursor() as cursor:
|
||||||
|
sql_insert = "INSERT INTO `{guild_id}survey_choices` (survey, content, attachment, attachment_name) VALUES (%s, %s, %s, %s)".format(
|
||||||
|
guild_id=self.guild.id)
|
||||||
|
with open("temp_attachement" + str(survey_id), "rb") as temp_file:
|
||||||
|
cursor.execute(sql_insert, (survey_id, content, temp_file.read(), file_name))
|
||||||
|
os.remove("temp_attachement" + str(survey_id))
|
||||||
|
self.guild.bot.database.commit()
|
||||||
|
|
||||||
|
async def create_survey(self, msg, command, args):
|
||||||
|
if msg.author.id not in self.guild.config["master_admins"]:
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["PermissionError"])
|
||||||
|
return
|
||||||
|
|
||||||
|
if len(args) < 2:
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["NotEnoughParamError"])
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
date_str = args[0]
|
||||||
|
content = " ".join(args[1:])
|
||||||
|
|
||||||
|
day_split = date_str.split("d")
|
||||||
|
if len(day_split) == 1 and "d" not in date_str:
|
||||||
|
jours = "0"
|
||||||
|
next_split = date_str
|
||||||
|
elif "d" in date_str and day_split[1] == "":
|
||||||
|
jours = day_split[0]
|
||||||
|
next_split = "0h0m0s"
|
||||||
|
else:
|
||||||
|
jours = day_split[0]
|
||||||
|
next_split = day_split[1]
|
||||||
|
|
||||||
|
hour_split = next_split.split("h")
|
||||||
|
if len(hour_split) == 1 and "h" not in date_str:
|
||||||
|
heures = "0"
|
||||||
|
next_split = date_str
|
||||||
|
elif "h" in date_str and hour_split[1] == "":
|
||||||
|
heures = hour_split[0]
|
||||||
|
next_split = "0m0s"
|
||||||
|
else:
|
||||||
|
heures = hour_split[0]
|
||||||
|
next_split = hour_split[1]
|
||||||
|
|
||||||
|
minute_split = next_split.split("m")
|
||||||
|
if len(minute_split) == 1 and "h" not in date_str:
|
||||||
|
minutes = "0"
|
||||||
|
next_split = date_str
|
||||||
|
elif "m" in date_str and minute_split[1] == "":
|
||||||
|
minutes = minute_split[0]
|
||||||
|
next_split = "0s"
|
||||||
|
else:
|
||||||
|
minutes = minute_split[0]
|
||||||
|
next_split = minute_split[1]
|
||||||
|
|
||||||
|
second_split = next_split.split("s")
|
||||||
|
if len(second_split) == 1 and "s" not in date_str:
|
||||||
|
secondes = "0"
|
||||||
|
else:
|
||||||
|
secondes = second_split[0]
|
||||||
|
|
||||||
|
try:
|
||||||
|
jours = int(jours)
|
||||||
|
heures = int(heures)
|
||||||
|
minutes = int(minutes)
|
||||||
|
secondes = int(secondes)
|
||||||
|
except ValueError:
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["NotANumberError"])
|
||||||
|
return
|
||||||
|
|
||||||
|
total = jours * 24 * 60 * 60 + heures * 60 * 60 + minutes * 60 + secondes # Durée du sondage
|
||||||
|
|
||||||
|
with self.guild.bot.database.cursor() as cursor:
|
||||||
|
insert_sql = "INSERT INTO `{guild_id}surveys` (title, duree) VALUES (%s, %s);".format(
|
||||||
|
guild_id=self.guild.id)
|
||||||
|
cursor.execute(insert_sql, (content, total))
|
||||||
|
self.guild.bot.database.commit()
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["modules"]["survey"]["create_survey"]
|
||||||
|
.format(id=cursor.lastrowid, prefix=self.guild.config["prefix"]))
|
||||||
|
|
||||||
|
async def post_survey(self, msg, command, args):
|
||||||
|
if msg.author.id not in self.guild.config["master_admins"]:
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["PermissionError"])
|
||||||
|
return
|
||||||
|
|
||||||
|
if len(args) != 1:
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["NotEnoughParamError"])
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
survey_id = int(args[0])
|
||||||
|
except ValueError:
|
||||||
|
msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["NotANumberError"])
|
||||||
|
return
|
||||||
|
# Vérification de l'existance du sondage
|
||||||
|
with self.guild.bot.database.cursor() as cursor:
|
||||||
|
sql_id = "SELECT id FROM `{guild_id}surveys`".format(guild_id=self.guild.id)
|
||||||
|
cursor.execute(sql_id)
|
||||||
|
liste_id = [r["id"] for r in cursor.fetchall()]
|
||||||
|
if survey_id not in liste_id:
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["SurveyNotExistsError"])
|
||||||
|
return
|
||||||
|
# Verification que le sondage n'a pas déjà été publié
|
||||||
|
with self.guild.bot.database.cursor() as cursor:
|
||||||
|
sql_depart = "SELECT depart FROM `{guild_id}surveys` WHERE id = %s".format(guild_id=self.guild.id)
|
||||||
|
cursor.execute(sql_depart, (survey_id))
|
||||||
|
depart = cursor.fetchone()["depart"]
|
||||||
|
if depart is not None:
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["AlreadySendSurvey"])
|
||||||
|
return
|
||||||
|
# Envoi du sondage
|
||||||
|
with self.guild.bot.database.cursor() as cursor:
|
||||||
|
sql_update = "UPDATE `{guild_id}surveys` SET depart = %s WHERE id=%s" \
|
||||||
|
.format(guild_id=self.guild.id)
|
||||||
|
cursor.execute(sql_update, (int(time.time()), survey_id))
|
||||||
|
self.guild.bot.database.commit()
|
||||||
|
with self.guild.bot.database.cursor() as cursor:
|
||||||
|
sql_choices = "SELECT id from `{guild_id}survey_choices` WHERE survey=%s" \
|
||||||
|
.format(guild_id=self.guild.id)
|
||||||
|
cursor.execute(sql_choices, (survey_id))
|
||||||
|
choices_id = [r["id"] for r in cursor.fetchall()]
|
||||||
|
with self.guild.bot.database.cursor() as cursor:
|
||||||
|
sql_survey_title = "SELECT title, duree FROM `{guild_id}surveys` WHERE id = %s" \
|
||||||
|
.format(guild_id=self.guild.id)
|
||||||
|
cursor.execute(sql_survey_title, (survey_id))
|
||||||
|
result = cursor.fetchone()
|
||||||
|
# Envoi des messages de présentation
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["modules"]["survey"]["post_survey"]["presentation"]
|
||||||
|
.format(prefix=self.guild.config["prefix"], heures=int(result["duree"] / 3600)))
|
||||||
|
await msg.channel.send(result['title'])
|
||||||
|
# Envoi des message pour chaque choix
|
||||||
|
for choice_id in choices_id:
|
||||||
|
with self.guild.bot.database.cursor() as cursor:
|
||||||
|
sql_choice = "SELECT id,content, attachment, attachment_name FROM `{guild_id}survey_choices` WHERE id=%s" \
|
||||||
|
.format(guild_id=self.guild.id)
|
||||||
|
cursor.execute(sql_choice, (choice_id))
|
||||||
|
result = cursor.fetchone()
|
||||||
|
if result["attachment_name"]:
|
||||||
|
with open(result["attachment_name"], "wb") as temp_file:
|
||||||
|
temp_file.write(result["attachment"])
|
||||||
|
with open(result["attachment_name"], "rb") as temp_file:
|
||||||
|
await msg.channel.send("`{prefix}vote {id}` "
|
||||||
|
.format(prefix=self.guild.config["prefix"], id=result["id"]) + result[
|
||||||
|
"content"],
|
||||||
|
file=discord.File(temp_file, filename=str(result["attachment_name"])))
|
||||||
|
else:
|
||||||
|
await msg.channel.send(content="`{prefix}vote {id}` "
|
||||||
|
.format(prefix=self.guild.config["prefix"], id=result["id"]) + result["content"])
|
||||||
|
|
||||||
|
async def post_result(self, msg, command, args):
|
||||||
|
# L'auteur est-t-il un admin?
|
||||||
|
if msg.author.id not in self.guild.config["master_admins"]:
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["PermissionError"])
|
||||||
|
return
|
||||||
|
# Nombre de paramètres
|
||||||
|
if len(args) != 1:
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["NotEnoughParamError"])
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
survey_id = int(args[0])
|
||||||
|
except ValueError:
|
||||||
|
msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["NotANumberError"])
|
||||||
|
return
|
||||||
|
# Vérification de l'existance du sondage
|
||||||
|
with self.guild.bot.database.cursor() as cursor:
|
||||||
|
sql_id = "SELECT id FROM `{guild_id}surveys`".format(guild_id=self.guild.id)
|
||||||
|
cursor.execute(sql_id)
|
||||||
|
liste_id = [r["id"] for r in cursor.fetchall()]
|
||||||
|
if survey_id not in liste_id:
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["SurveyNotExistsError"])
|
||||||
|
return
|
||||||
|
# Vérification que le sondage est terminé
|
||||||
|
with self.guild.bot.database.cursor() as cursor:
|
||||||
|
# Récupération de la date de fin du sondage
|
||||||
|
select_survey_sql = "SELECT depart, duree FROM `{guild_id}surveys` WHERE id=%s;".format(
|
||||||
|
guild_id=self.guild.id)
|
||||||
|
cursor.execute(select_survey_sql, (survey_id))
|
||||||
|
r = cursor.fetchone()
|
||||||
|
if r["depart"] is not None:
|
||||||
|
fin = r["depart"] + r["duree"]
|
||||||
|
else:
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["NotYetPostedError"])
|
||||||
|
return
|
||||||
|
print(fin, time.time())
|
||||||
|
if fin > time.time():
|
||||||
|
await msg.channel.send(tr.tr[self.guild.config["lang"]]["errors"]["NotYetFinishedError"])
|
||||||
|
return
|
||||||
|
|
||||||
|
# Récupération des choix
|
||||||
|
with self.guild.bot.database.cursor() as cursor:
|
||||||
|
sql_select_choices = "SELECT id FROM `{guild_id}survey_choices` WHERE survey=%s;".format(guild_id=self.guild.id)
|
||||||
|
cursor.execute(sql_select_choices, (survey_id))
|
||||||
|
choices = [r["id"] for r in cursor.fetchall()]
|
||||||
|
|
||||||
|
# Récupération des votes
|
||||||
|
votes = []
|
||||||
|
for id_choice in choices:
|
||||||
|
with self.guild.bot.database.cursor() as cursor:
|
||||||
|
select_votes_sql = "SELECT id FROM `{guild_id}survey_votes` WHERE choice=%s;".format(guild_id=self.guild.id)
|
||||||
|
cursor.execute(select_votes_sql, (id_choice))
|
||||||
|
votes.append((id_choice,len(cursor.fetchall())))
|
||||||
|
|
||||||
|
votes.sort(key=lambda x: x[1])
|
||||||
|
total = sum([x[1] for x in votes])
|
||||||
|
texte = tr.tr[self.guild.config["lang"]]["modules"]["survey"]["result"]["text"]+"```"
|
||||||
|
i=0
|
||||||
|
for vote in votes[::-1]:
|
||||||
|
i+=1
|
||||||
|
texte += "\n n°{i} - Choix {id_choix} - {nb_votes} ({pourcentage}%)"\
|
||||||
|
.format(i=i, id_choix=vote[0], nb_votes=vote[1], pourcentage=vote[1]*100/total)
|
||||||
|
texte += "```"
|
||||||
|
await msg.channel.send(texte)
|
||||||
|
|
||||||
|
async def on_message(self, msg):
|
||||||
|
if msg.content.startswith(self.guild.config["prefix"]):
|
||||||
|
command, *args = msg.content.lstrip(self.guild.config["prefix"]).split(" ")
|
||||||
|
if command == "vote":
|
||||||
|
await self.vote(msg, command, args)
|
||||||
|
elif command == "add_choice":
|
||||||
|
await self.add_choice(msg, command, args)
|
||||||
|
elif command == "create_survey":
|
||||||
|
await self.create_survey(msg, command, args)
|
||||||
|
elif command == "post_survey":
|
||||||
|
await self.post_survey(msg, command, args)
|
||||||
|
elif command == "post_results":
|
||||||
|
await self.post_result(msg, command, args)
|
||||||
|
return
|
@ -1 +0,0 @@
|
|||||||
python-3.7.0
|
|
135
traductions.py
135
traductions.py
@ -3,7 +3,7 @@ tr = {
|
|||||||
"description": "Français",
|
"description": "Français",
|
||||||
"modules": {
|
"modules": {
|
||||||
"modules": {
|
"modules": {
|
||||||
"description": "Permet de gérer les modules.",
|
"description": "Gestion des modules.",
|
||||||
"help": {
|
"help": {
|
||||||
"list_modules": {
|
"list_modules": {
|
||||||
"description": "Liste tous les modules. Les modules en gras sont activés.",
|
"description": "Liste tous les modules. Les modules en gras sont activés.",
|
||||||
@ -93,6 +93,48 @@ tr = {
|
|||||||
"add_master_admin": "L'utilisateur {user} est maintenant un administrateur du bot.",
|
"add_master_admin": "L'utilisateur {user} est maintenant un administrateur du bot.",
|
||||||
"del_master_admin": "L'utilisateur {user} n'est plus un administrateur du bot.",
|
"del_master_admin": "L'utilisateur {user} n'est plus un administrateur du bot.",
|
||||||
},
|
},
|
||||||
|
"deeptown": {
|
||||||
|
"description": "Commandes relatives au jeu deeptown.",
|
||||||
|
"help": {
|
||||||
|
"best_place_mine": {
|
||||||
|
"description": "Montre les meilleurs emplacements de mine pour un cerain minerais.",
|
||||||
|
"examples": [
|
||||||
|
("`{prefix}best_place_mine iron`",
|
||||||
|
"Donne les meilleurs emplaceent pour le minerais de fer.")
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"to_make": {
|
||||||
|
"description": "Donne les resource nécessaires pour faire un item.",
|
||||||
|
"example": [
|
||||||
|
("`{prefix}to_make copperNail 100`",
|
||||||
|
"Donne les resources pour faire 100 clous en cuivre, càd 10 copperBar."),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"to_make_recursive": {
|
||||||
|
"description": "Donne toutes les resources nécessaires pour faire un item.",
|
||||||
|
"example": [
|
||||||
|
("`{prefix}to_make_recursive copperNail 100`",
|
||||||
|
"Donne les resources pour faire 100 copperNail, càd 10 copperBar et 50 copper."),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"reload_optimizer": {
|
||||||
|
"description": "Recharge les quantités deressources nécessaires, réservé aux admins",
|
||||||
|
"example": [
|
||||||
|
(
|
||||||
|
"`{prefix}reload_optimizer`",
|
||||||
|
"Recharge les quantités de ressources nécessaires pour faire "
|
||||||
|
"les différents items.")
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"best_place_mine": "Voici les meilleurs emplacements pour le minerais {ore}\n```\n",
|
||||||
|
"to_make": "Pour faire {quantity} {item} il faudra {time}. Il vous faudra {needed}. La valeur totale "
|
||||||
|
"de la production est {value}.",
|
||||||
|
"recursive_to_make": {
|
||||||
|
"header": "Pour faire {quantity} {item} il vous faudra:\n```",
|
||||||
|
"line": "{item:20} | {quantity:8} | {time}"
|
||||||
|
},
|
||||||
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"description": "Active la commande d'aide",
|
"description": "Active la commande d'aide",
|
||||||
"help": {
|
"help": {
|
||||||
@ -101,7 +143,8 @@ tr = {
|
|||||||
"examples": [
|
"examples": [
|
||||||
("`{prefix}help`", "Affiche l'aide générale"),
|
("`{prefix}help`", "Affiche l'aide générale"),
|
||||||
("`{prefix}help config`", "Liste les commandes disponibles dans le module config"),
|
("`{prefix}help config`", "Liste les commandes disponibles dans le module config"),
|
||||||
("`{prefix}help config:lang`", "Affiche l'aide avancé de la commande lang u module config"),
|
("`{prefix}help config:lang`",
|
||||||
|
"Affiche l'aide avancé de la commande lang u module config"),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -112,10 +155,10 @@ tr = {
|
|||||||
"pi": {
|
"pi": {
|
||||||
"description": "Donne 2000 décimales de pi.",
|
"description": "Donne 2000 décimales de pi.",
|
||||||
"examples": [
|
"examples": [
|
||||||
("`(prefix}pi`", "Affiche les 2000 premières décimales de pi."),
|
("`{prefix}pi`", "Affiche les 2000 premières décimales de pi."),
|
||||||
("`{prefix}pi 2000`", "Affiche 2000 décimales de pi à partir de la 2000ème"),
|
("`{prefix}pi 2000`", "Affiche 2000 décimales de pi à partir de la 2000ème"),
|
||||||
],
|
],
|
||||||
},"fpi": {
|
}, "fpi": {
|
||||||
"description": "Recherche l'expression régulière dans pi",
|
"description": "Recherche l'expression régulière dans pi",
|
||||||
"examples": [
|
"examples": [
|
||||||
("`{prefix}fpi 12345`", "Affiche les 10 premières occurences de 12345 dans pi"),
|
("`{prefix}fpi 12345`", "Affiche les 10 premières occurences de 12345 dans pi"),
|
||||||
@ -132,12 +175,12 @@ tr = {
|
|||||||
"sourcecode": {
|
"sourcecode": {
|
||||||
"description": "Donne un lien vers mon code source (il est là comme ca tu a pas retapper la \
|
"description": "Donne un lien vers mon code source (il est là comme ca tu a pas retapper la \
|
||||||
commande :smile: https://github.com/Fomys/foBot",
|
commande :smile: https://github.com/Fomys/foBot",
|
||||||
"examples":[
|
"examples": [
|
||||||
("`prefix`sourcecode", "Affiche mon code source")
|
("`prefix`sourcecode", "Affiche mon code source")
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"sourcecode":"Mon code source est disponible sur github: https://github.com/Fomys/foBot",
|
"sourcecode": "Mon code source est disponible sur github: https://github.com/Fomys/foBot",
|
||||||
},
|
},
|
||||||
"tools": {
|
"tools": {
|
||||||
"description": "Commandes utiles",
|
"description": "Commandes utiles",
|
||||||
@ -154,38 +197,98 @@ commande :smile: https://github.com/Fomys/foBot",
|
|||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"survey": {
|
||||||
|
"description": "Module permettant de faire des sondages",
|
||||||
|
"help": {
|
||||||
|
"create_survey": {
|
||||||
|
"description": "Créer un sondage et vous renvoie son id",
|
||||||
|
"examples": [
|
||||||
|
("`{prefix}create_survey 13d23h43m23s Que dites vous?`",
|
||||||
|
"Crée un sondage intitulé \"pain au chocolat ou chocolatine?\". Retourne un id.Il faut uti"
|
||||||
|
"liser la command `{prefix}add_choice` pour rajouter une option.")
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"add_option": {
|
||||||
|
"description": "Rajoute une option àun sondage non commencé",
|
||||||
|
"examples": [
|
||||||
|
("`{prefix}add_option 146 Pain au chocolat`", "Ajoute l'option \"Pain au chocolat\" au sond"
|
||||||
|
"age numéro 146"),
|
||||||
|
("`{prefix}add_option 146 Chocolatine`", "Ajoute l'option \"Chocolatine\" au sondage numéro"
|
||||||
|
" 146")
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"create_survey": "Le sondage {id} viens d'être créé. Utilisez la commande `{prefix}add_choice {id} \"Op"
|
||||||
|
"tion\"` pout ajouter une option au sondage (vous pouvez mettre un piècre jointe). Une"
|
||||||
|
" fois toutes les options ajoutées, utilisez la commande `{prefix}post_survey {id}` da"
|
||||||
|
"ns le channel où vous voulez poster le sondage. Le sondage commencera lorsque vous fe"
|
||||||
|
"rez la commande `{prefix}post_survey {id}`",
|
||||||
|
"post_survey": {
|
||||||
|
"presentation": "Un nouveau sondage a été créé. Votez pour le choix que vous préférez avec la comman"
|
||||||
|
"de `{prefix}vote choix` en remplaçant choix par le numéro de l'option pour laquelle"
|
||||||
|
" vous votez. Ce sondage se termine dans {heures} heures. Bon vote!",
|
||||||
|
},
|
||||||
|
"vote": "<@{id_auteur}> votre vote a bien été pris en compte",
|
||||||
|
"result": {
|
||||||
|
"text": "Voici les résultats pour le sondage"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"directAccessDB": {
|
||||||
|
"description": "test",
|
||||||
|
"help": {
|
||||||
|
"execute": {
|
||||||
|
"description": "Exécuter une commande sql et renvoyer le résultat",
|
||||||
|
"exemples": [
|
||||||
|
("`{prefix}execute SHOW TABLES;`", "Execute `SHOW TABLES;` statement in mariadb server."),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"LangNotFoundError": "La langue {lang} est introuvable, tapez {prefix}list_lang pour voir les langues "
|
"LangNotFoundError": "La langue {lang} est introuvable, tapez {prefix}list_lang pour voir les langues dispo"
|
||||||
"disponibles.",
|
"nibles.",
|
||||||
"PermissionError": "Vous n'avez pas la permission de faire cette action.",
|
"PermissionError": "Vous n'avez pas la permission de faire cette action.",
|
||||||
"ModuleNotFoundOrDeactivatedError": {
|
"ModuleNotFoundOrDeactivatedError": {
|
||||||
"title": "Erreur",
|
"title": "Erreur",
|
||||||
"name": "Erreur lors de la désactivation du module {module}:",
|
"name": "Erreur lors de la désactivation du module {module}:",
|
||||||
"value": "Celui-ci n'existe pas ou n'es pas activé. Tapez {prefix}list_modules pour voir la liste des "
|
"value": "Celui-ci n'existe pas ou n'es pas activé. Tapez {prefix}list_modules pour voir la liste des m"
|
||||||
"modules disponibles.",
|
"odules disponibles.",
|
||||||
|
|
||||||
},
|
},
|
||||||
"ModuleNotFoundError": {
|
"ModuleNotFoundError": {
|
||||||
"title": "Erreur",
|
"title": "Erreur",
|
||||||
"name": "Erreur lors de l'activation du module {module}:",
|
"name": "Erreur lors de l'activation du module {module}:",
|
||||||
"value": "Celui-ci n'existe pas. Tapez {prefix}list_modules pour voir la liste des modules "
|
"value": "Celui-ci n'existe pas. Tapez {prefix}list_modules pour voir la liste des modules disponibles."
|
||||||
"disponibles.",
|
"",
|
||||||
"text": "Le module {module} n'existe pas, tapez {prefix}list_modules pour voir la liste des modules "
|
"text": "Le module {module} n'existe pas, tapez {prefix}list_modules pour voir la liste des modules dis"
|
||||||
"disponibles.",
|
"ponibles.",
|
||||||
},
|
},
|
||||||
"ForbiddenConfigError": "Ce paramètre ne peut pas être modifié directement.",
|
"ForbiddenConfigError": "Ce paramètre ne peut pas être modifié directement.",
|
||||||
"UnknownConfigError": "Le paramètre demandé n'existe pas. Utilisez {prefix}list pour lister les paramètres "
|
"UnknownConfigError": "Le paramètre demandé n'existe pas. Utilisez {prefix}list pour lister les paramètres "
|
||||||
"modifiables.",
|
"modifiables.",
|
||||||
"NotEnoughParamError": "Il manque un ou plusieurs parametres à la commande.",
|
"NotEnoughParamError": "Il manque un ou plusieurs parametres à la commande.",
|
||||||
"NoMentionsError": "Vous devez mentioner un utilisateur pour le rajouter à la liste des administrateurs "
|
"NoMentionsError": "Vous devez mentioner un utilisateur pour le rajouter à la liste des administrateurs du "
|
||||||
"du bot.",
|
"bot.",
|
||||||
|
"OreNotFoundError": "{ore} n'est pas un minerais valide.",
|
||||||
|
"NotIntError": "{number} n'est pas un nombre entier valide.",
|
||||||
|
"ItemNotFoundError": "{item} n'extiste pas dans deeptown",
|
||||||
"CommandNotFoundError": "La commande {command} n'existe pas.",
|
"CommandNotFoundError": "La commande {command} n'existe pas.",
|
||||||
"TooBigNumberPiError": "Vous devez spécifier un nombre inferieur a 1000000.",
|
"TooBigNumberPiError": "Vous devez spécifier un nombre inferieur a 1000000.",
|
||||||
"RegexError": "La regex que vous avez utilisé n'est pas valide.",
|
"RegexError": "La regex que vous avez utilisé n'est pas valide.",
|
||||||
"ForbiddenRegexError": "Vous n'avez pas le droit d'utiliser les caractères `*` et `+` dans une regex.",
|
"ForbiddenRegexError": "Vous n'avez pas le droit d'utiliser les caractères `*` et `+` dans une regex.",
|
||||||
"RegexTooLongError": "La regex ne doit pas faire plus e 50 caractères",
|
"RegexTooLongError": "La regex ne doit pas faire plus e 50 caractères",
|
||||||
"PiFileError": "Les décimales de pi sont indisponibles, veuillez réessayer plus tard...",
|
"PiFileError": "Les décimales de pi sont indisponibles, veuillez réessayer plus tard...",
|
||||||
|
"AttachementTooBigError": "Le fichier join est trop volumineux, veuillez le compresser avant de réessayer",
|
||||||
|
"SurveyNotExistsError": "Le sondage que vous demandez n'existe pas.",
|
||||||
|
"NotANumberError": "La valeur que vous avezpassé en paramètre n'est pas un nombre valide.",
|
||||||
|
"AlreadySendSurvey": "Le sondage que vous essayez de poster a déjà été posté",
|
||||||
|
"SurveyCompletedError": "Le sondage que vous demandez est terminé",
|
||||||
|
"AlreadyVote": "Vous avez déjà voté pour ce sondage",
|
||||||
|
"NotYetPostedError": "Le sondage que vous demandez n'a pas encore été publié",
|
||||||
|
"NotYetFinishedError": "Le sondage que vous demandez n'est pas fini, pour éviter d'influencer les autres vo"
|
||||||
|
"tes les résultats ne seront disponibles que à la fin.",
|
||||||
|
"DiscordForbiddenError": "Je n'ai pas les droits pour supprimer le message."
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user