Compare commits
528 commits
Author | SHA1 | Date | |
---|---|---|---|
Milka64 | 6b9e153de1 | ||
Milka64 | 6504c286da | ||
Milka64 | 8cca3c1990 | ||
Milka64 | b7d3546cea | ||
Milka64 | 6f2460eaef | ||
Milka64 | 3cdec52d81 | ||
Milka64 | 9a4e9b3735 | ||
Milka64 | 2fadbe74c0 | ||
Milka64 | 2d8518e169 | ||
Milka64 | 26a30c9af8 | ||
Milka64 | d33eb077a7 | ||
Milka64 | daa3c7aa0d | ||
Milka64 | f2b6638616 | ||
Milka64 | d913af4378 | ||
Milka64 | 2d893dbda2 | ||
Milka64 | a6a7eb07bc | ||
Milka64 | 012feae29c | ||
Milka64 | c3e590fd2c | ||
Milka64 | 8e654da976 | ||
Milka64 | 5dd913d1ca | ||
Milka64 | e8fef9801e | ||
Milka64 | ff98d6b453 | ||
Milka64 | a046a4d55f | ||
Milka64 | 82c5c6501c | ||
Milka64 | ccde0ff81d | ||
Milka64 | 30e89ba49c | ||
Milka64 | 55d4045a2e | ||
Milka64 | d2291738bb | ||
Milka64 | d77d390efe | ||
Milka64 | c47df4b78c | ||
Milka64 | 5792a88911 | ||
Milka64 | a9cc9e20c0 | ||
112760299f | |||
1f52550d29 | |||
1f9fe5dfd1 | |||
0c9aeece81 | |||
d1f7d91485 | |||
Milka64 | 84dd36208f | ||
Milka64 | 239bbe259e | ||
Milka64 | 34b1c075b6 | ||
Milka64 | dc0ab7d0d7 | ||
5bc0329c22 | |||
cb007a7126 | |||
fbba7aae52 | |||
e4a3e88511 | |||
8349448540 | |||
bbbb4bd21b | |||
1611683036 | |||
186eccff93 | |||
d9925249ad | |||
3742c4bd5a | |||
c5d3835c57 | |||
f5703709d1 | |||
a6437ee322 | |||
Milka64 | 5207baf83f | ||
Milka64 | b719019dbd | ||
Milka64 | abb7f34d9f | ||
7031a76b06 | |||
7ab8aa21b9 | |||
705ba32565 | |||
43508edc66 | |||
4999c52437 | |||
e790569a27 | |||
ef24e2a2bf | |||
e391b138e5 | |||
1861f39450 | |||
de994a3592 | |||
3aea250608 | |||
a8cc570aa4 | |||
21c7969b2a | |||
bbdd26a24c | |||
0f830d8c18 | |||
Milka64 | 310c4288a4 | ||
Milka64 | f74d152d81 | ||
Milka64 | da70ab9d8c | ||
812c5139a2 | |||
84b09f4217 | |||
68525eeafd | |||
f127c9ed75 | |||
ebae4dabbd | |||
84637f4f32 | |||
91b758faa9 | |||
3beea52ed9 | |||
29de2a539a | |||
283a3919f0 | |||
502911be81 | |||
Milka64 | 0bbe882e77 | ||
Milka64 | 1dd31a4a81 | ||
ba5e20d415 | |||
39adda86e2 | |||
c4cbaaf9b8 | |||
0e714be66f | |||
237baf0a1e | |||
33be6d59f4 | |||
ef4ebf1c35 | |||
ec84a18e76 | |||
6b3e0a0b4f | |||
9fd12991b6 | |||
0995303080 | |||
fc29b8931b | |||
d97895feaf | |||
a670726056 | |||
8a8db57257 | |||
Milka64 | 68ef3d2ea1 | ||
aa0274ba22 | |||
36b1445994 | |||
0903b7a1c7 | |||
a6790533d1 | |||
6c507593f5 | |||
ef1ff4e23c | |||
c861d2b854 | |||
69bce93eb6 | |||
cabbc221d1 | |||
bec13c53b5 | |||
be29a2942c | |||
60697c80c7 | |||
f955b71230 | |||
648e3dcc57 | |||
7434bb9592 | |||
e7de70d262 | |||
b99f913681 | |||
300b138fe2 | |||
Milka64 | 518687059f | ||
Milka64 | 8efd8d2354 | ||
98bf031cd6 | |||
175c5f7bd5 | |||
Milka64 | 1db3b11f2f | ||
c30d54e359 | |||
63cecd91ce | |||
3a83ef09ae | |||
d204cf827e | |||
3dd11392f6 | |||
2d4e5cc36c | |||
164e092d80 | |||
77c6d11fa6 | |||
51a0be5129 | |||
12bc08ea52 | |||
63bc49e6a3 | |||
71eb1f7ee8 | |||
097afb9f86 | |||
91fef22ba0 | |||
b4176e3b4d | |||
b4e201e177 | |||
a4b7d1e77a | |||
b34992cb86 | |||
d431a0a904 | |||
f1a702930b | |||
477e765316 | |||
ae285863d1 | |||
8b7e1bb688 | |||
95b458200c | |||
f5462da4b4 | |||
053a725c4c | |||
0352ea290e | |||
0d397e06a4 | |||
2585d99183 | |||
f8668604cf | |||
02cbc28dc1 | |||
f8c58fe7ac | |||
0f2acfdabf | |||
b8c18e5a07 | |||
7fd4d9dc5f | |||
5ed705a41c | |||
595d2f9a19 | |||
a13887de58 | |||
f238171ca1 | |||
033c187396 | |||
75b32ef3fb | |||
23e6896be6 | |||
aedc82876c | |||
f1a79ffa8f | |||
f68a9f621f | |||
140f390660 | |||
f5c063a1a8 | |||
4727e7416b | |||
cd30d66d72 | |||
52b11452c2 | |||
f6e2efb0ca | |||
7ecbd57571 | |||
96bf856059 | |||
ed125f7230 | |||
a403422e10 | |||
0422668097 | |||
64d3234cab | |||
88fb5444e9 | |||
e46ea1f626 | |||
991849e907 | |||
ce052ec525 | |||
11ff420595 | |||
4c664a2343 | |||
ca4913d145 | |||
3d690379f7 | |||
ba4d1cf115 | |||
cb4ed715b3 | |||
e84bde3fca | |||
228723a1a4 | |||
f9c51f2009 | |||
5793432802 | |||
4307084384 | |||
c2a9e3302b | |||
08bfb3c744 | |||
09fe02357b | |||
12d6b3c23f | |||
797b36391d | |||
8083e0a41f | |||
63c3bc353d | |||
1db9e9685f | |||
a4a85e929f | |||
98b6f66a90 | |||
038808fb3c | |||
d739699c24 | |||
a2937192be | |||
7d3ffe2fdf | |||
2b2849e39a | |||
6987c5fc4f | |||
6cf150b3b0 | |||
968f7df735 | |||
dc89a557f4 | |||
9107823739 | |||
f80d1a3252 | |||
21d236edb7 | |||
6898bdb204 | |||
66fd7a1184 | |||
77ccc042b4 | |||
b214d69827 | |||
50675bfbee | |||
734606304d | |||
f6380de580 | |||
2f591a82e5 | |||
98f4ae45ab | |||
931ae99f4c | |||
cc2bc6a287 | |||
0fbcf24898 | |||
3cfa6ec653 | |||
8881f7074c | |||
e438e187d2 | |||
d03d94b0f2 | |||
3196180bfa | |||
dfae58a67e | |||
36441c2d9e | |||
c75bc4a5dc | |||
ede212f879 | |||
2f7c4eb8a2 | |||
4035bf390f | |||
21d235f0ac | |||
0ea18049d9 | |||
3cece8b5f9 | |||
0a139ec1d1 | |||
36f514b856 | |||
d89024d32f | |||
1804f6d1e2 | |||
5a45012175 | |||
b5c00d5504 | |||
53d7c61841 | |||
3a5285b089 | |||
6ed96d49ab | |||
da46fb88f1 | |||
57a0247c8e | |||
e1898ca4d8 | |||
4d45a06cb7 | |||
0cb2a6b355 | |||
bf2c0fd7b4 | |||
7d54de95a4 | |||
f316d08c0e | |||
83837c62da | |||
a240302e70 | |||
386c70f803 | |||
682de524c1 | |||
6f1a214eef | |||
a7f43332af | |||
90a2443900 | |||
aa01f1d89c | |||
35a310294a | |||
86ec7fa983 | |||
c935afd059 | |||
d6aeafb410 | |||
35aaac9baf | |||
8252930ee4 | |||
1ba79e3172 | |||
a598e7dfaa | |||
c357efd459 | |||
3836b06f5c | |||
5c0a0d39ab | |||
698924476e | |||
25f3eb749f | |||
bfd2ab4088 | |||
ba072051a1 | |||
f85ef2b7e4 | |||
81fa20ee12 | |||
0a0a83b90e | |||
58e8287348 | |||
f0f182560f | |||
9f4106a5b5 | |||
848ad22eed | |||
79f4f81ff8 | |||
009e6d91cd | |||
f4d94e29c8 | |||
a68434b138 | |||
7daf52b9f7 | |||
c0be47a4e2 | |||
c93b333b57 | |||
07f814c7d7 | |||
08df771274 | |||
b5ead5e8fc | |||
1e067a4544 | |||
2a44a47405 | |||
d1e029747f | |||
2ffd0aacad | |||
1bf65a8124 | |||
6979bdebae | |||
014fbb35ee | |||
f0985e4752 | |||
679515ca84 | |||
fcfc1c8b9b | |||
40e0f7be96 | |||
a769760ed9 | |||
dbc8cffa5c | |||
0706c0f77e | |||
add5094090 | |||
1eb1af14aa | |||
fe649d530b | |||
d1af880652 | |||
8094a7a65b | |||
e0ace12372 | |||
8d036b897a | |||
e816df9298 | |||
3fc08ff4e3 | |||
0b06fd7297 | |||
bf93366dd7 | |||
ac02277a98 | |||
28ce692692 | |||
71efb092f1 | |||
e541aa9b3e | |||
415b610f6a | |||
3ff7c86431 | |||
d3bed5b996 | |||
fb6b265d06 | |||
1bc5f97f79 | |||
49c5960a9c | |||
6352556f9e | |||
f9e36be6a6 | |||
8ac8a390aa | |||
6aa7ed372d | |||
089818e48c | |||
2598511bf5 | |||
d454a1f685 | |||
e106184a48 | |||
ff767d2cc3 | |||
2fb6165913 | |||
ba7ed1ab89 | |||
cb648cab52 | |||
3b3925f669 | |||
df0db59646 | |||
d12222f9c9 | |||
8c6764cf9a | |||
92de407337 | |||
c84043189f | |||
632f489d50 | |||
bb39c529a8 | |||
915f3b8382 | |||
a22346cc5d | |||
94b1c589e2 | |||
88c551c88d | |||
8e3a7c06f0 | |||
995b95f54b | |||
1001eb86f9 | |||
7f3c97d237 | |||
312def0cf7 | |||
11c9ac1937 | |||
425955c4db | |||
bd633427d8 | |||
f705a23112 | |||
c662c314a5 | |||
e7e5c104cd | |||
85c3143e37 | |||
fb795c757c | |||
d7219ab754 | |||
519bf41847 | |||
e616ea0853 | |||
9b4107b1c7 | |||
fcb4f40f1b | |||
520f6368d3 | |||
08318c93d6 | |||
e9f4bda3d8 | |||
cebff905c9 | |||
c2afae9696 | |||
ffc4a7f849 | |||
1b6ffbc083 | |||
d20f65b353 | |||
28407c9b18 | |||
f5d4a83b9b | |||
43ca514388 | |||
d91c994ecb | |||
4db2526863 | |||
ea1657f5eb | |||
5292c21497 | |||
961d2c89c3 | |||
99ea7ed459 | |||
327054ab2d | |||
439e8fec14 | |||
51743bc786 | |||
8807aeec95 | |||
72dbc404a9 | |||
9681bb6067 | |||
0f997c8168 | |||
4d404baedc | |||
31be129a9e | |||
2d81b2f81a | |||
6ebeabaef0 | |||
d302775b13 | |||
2f5461f01f | |||
b27a9b00a7 | |||
957708785f | |||
33d44c2395 | |||
111b96c5db | |||
80321e8128 | |||
e654378e7a | |||
f016e6b5bd | |||
7f981b8c67 | |||
68093c7abe | |||
c552943a41 | |||
713c694d03 | |||
b7474bbf17 | |||
5eed8bab06 | |||
770792a5bd | |||
4c8d6245ad | |||
7036843b8c | |||
baf37a4b25 | |||
c922bb6256 | |||
cef7424174 | |||
287b1e6202 | |||
15691b7463 | |||
5b181863e6 | |||
37a29e0133 | |||
7f843aa379 | |||
6838780e7d | |||
6d9cda6669 | |||
0d7a7aa849 | |||
3f1d2b3cea | |||
e20a843e49 | |||
230791a638 | |||
16c500d598 | |||
24278dd390 | |||
a97259338d | |||
4b155b3594 | |||
07e2ac607e | |||
901119008f | |||
9fef8aa56c | |||
28391d3998 | |||
97c5b43b69 | |||
87f1f7af00 | |||
3c64624d0d | |||
1a2a4bd9da | |||
e560682d99 | |||
c947c1057d | |||
8e0023be1d | |||
0f40126348 | |||
91dab5b70e | |||
f7f080bd38 | |||
106e726e42 | |||
70c9a3a108 | |||
3bbf56a96f | |||
e48327c3c8 | |||
6b7ac6e50b | |||
1ad3a1ce45 | |||
eca5e00068 | |||
965833e19e | |||
da26150fe2 | |||
cbfd7cd59c | |||
8f658d9afd | |||
194a0e2a68 | |||
e3701f4e14 | |||
0f6329098a | |||
5733998f88 | |||
83860bf3e6 | |||
f3a978081c | |||
fa31518100 | |||
82d9e00d3b | |||
e410034883 | |||
0e07e3acc0 | |||
a99b6e4bbe | |||
28a0b053a9 | |||
1a625d257e | |||
647153a9f1 | |||
c3bb2d64b7 | |||
3ac51ab6db | |||
21b7680bfc | |||
3e2aa4e8af | |||
524ebc72a3 | |||
f984bab3c6 | |||
74c7509522 | |||
ddad8fd7d8 | |||
c10a91e9da | |||
afe379120c | |||
03abb9bbc1 | |||
00ba80e3a0 | |||
53f71619ad | |||
42475498d9 | |||
ebbe1f6b3f | |||
5aa727ac9a | |||
5fba6d66ef | |||
0e0249fc32 | |||
8dcd30836f | |||
b7b4e225b8 | |||
fab2cefdc0 | |||
011d363aca | |||
a3cd80ba8e | |||
506de7133e | |||
d506b9d13f | |||
509b6a6a42 | |||
34d063dfeb | |||
0d80ccd86a | |||
d0289764c2 | |||
3e274d6367 | |||
f060572e80 | |||
f9dab8dfaf | |||
a7a14b215d | |||
c29a569f65 | |||
152c8b922c | |||
1ac4822e66 | |||
b59a0af357 | |||
d3c371dd15 | |||
22d74f2805 | |||
74129fb754 | |||
3fc3baacd1 | |||
48378696a3 | |||
077056cd1b | |||
3a919b81eb |
2
.gitignore
vendored
|
@ -76,7 +76,7 @@ docs/make.bat
|
||||||
dev.cfg
|
dev.cfg
|
||||||
prod.cfg
|
prod.cfg
|
||||||
exploit_overrides.cfg
|
exploit_overrides.cfg
|
||||||
buildout.cfg
|
#buildout.cfg
|
||||||
config.ini
|
config.ini
|
||||||
mr-dev/*
|
mr-dev/*
|
||||||
.mr.developer.cfg
|
.mr.developer.cfg
|
||||||
|
|
29
.gitlab-ci.yml
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
stages:
|
||||||
|
- login
|
||||||
|
- build
|
||||||
|
- push
|
||||||
|
- deploy
|
||||||
|
|
||||||
|
variables:
|
||||||
|
GL_TOKEN: $GL_TOKEN
|
||||||
|
VERSION: '0.2.18'
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
stage: deploy
|
||||||
|
script : sudo docker-compose --env-file /data/docker/compose-files/others.env -f /data/docker/compose-files/others.yml up -d
|
||||||
|
|
||||||
|
build:
|
||||||
|
stage: build
|
||||||
|
script:
|
||||||
|
- sudo docker build -t hub.0w.tf/milka64/kabot:$VERSION .
|
||||||
|
- sudo docker build -t hub.0w.tf/milka64/kabot:latest .
|
||||||
|
|
||||||
|
push:
|
||||||
|
stage: push
|
||||||
|
script:
|
||||||
|
- sudo docker push hub.0w.tf/milka64/kabot:$VERSION
|
||||||
|
- sudo docker push hub.0w.tf/milka64/kabot:latest
|
||||||
|
|
||||||
|
login:
|
||||||
|
stage: login
|
||||||
|
script: sudo docker login -u milka64 -p $GL_TOKEN hub.0w.tf
|
12
Dockerfile
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
FROM python:3.11
|
||||||
|
|
||||||
|
WORKDIR /usr/src/kabot
|
||||||
|
ENV CONFIG_FILE=/data/config.ini
|
||||||
|
COPY kabot ./
|
||||||
|
COPY config.ini.sample /data/config.ini
|
||||||
|
COPY entrypoint.sh /
|
||||||
|
RUN apt update && apt install -y ffmpeg
|
||||||
|
RUN apt clean
|
||||||
|
RUN pip install --no-cache-dir /usr/src/kabot/
|
||||||
|
|
||||||
|
CMD [ "/entrypoint.sh" ]
|
34
README.rst
|
@ -10,7 +10,7 @@ Prerquire :
|
||||||
|
|
||||||
pip3 install zc.buildout
|
pip3 install zc.buildout
|
||||||
|
|
||||||
clone this repositori, then :
|
clone this repository, then :
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
|
@ -22,4 +22,34 @@ Utilisation
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
./bin/kabot
|
./bin/kabot -c config.ini
|
||||||
|
|
||||||
|
Configuration
|
||||||
|
-------------
|
||||||
|
|
||||||
|
.. code-block:: ini
|
||||||
|
|
||||||
|
[DEFAULT]
|
||||||
|
|
||||||
|
audio_path = /tmp/
|
||||||
|
voice_channel = channel_name
|
||||||
|
text_channel = channel_name
|
||||||
|
|
||||||
|
[discord]
|
||||||
|
token = <discord_token>
|
||||||
|
|
||||||
|
[gitlab]
|
||||||
|
url = https://gitlab.example.com/
|
||||||
|
token = <GITLAB_TOKEN>
|
||||||
|
|
||||||
|
[giphy]
|
||||||
|
token = <GIPHY_TOKEN>
|
||||||
|
|
||||||
|
|
||||||
|
Docker
|
||||||
|
------
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
docker build -t kabot .
|
||||||
|
docker run -v /pa/to/your/data:/data kabot:latest
|
||||||
|
|
|
@ -1,210 +0,0 @@
|
||||||
##############################################################################
|
|
||||||
#
|
|
||||||
# Copyright (c) 2006 Zope Foundation and Contributors.
|
|
||||||
# All Rights Reserved.
|
|
||||||
#
|
|
||||||
# This software is subject to the provisions of the Zope Public License,
|
|
||||||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
|
|
||||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
|
|
||||||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
|
|
||||||
# FOR A PARTICULAR PURPOSE.
|
|
||||||
#
|
|
||||||
##############################################################################
|
|
||||||
"""Bootstrap a buildout-based project
|
|
||||||
|
|
||||||
Simply run this script in a directory containing a buildout.cfg.
|
|
||||||
The script accepts buildout command-line options, so you can
|
|
||||||
use the -c option to specify an alternate configuration file.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import os
|
|
||||||
import shutil
|
|
||||||
import sys
|
|
||||||
import tempfile
|
|
||||||
|
|
||||||
from optparse import OptionParser
|
|
||||||
|
|
||||||
__version__ = '2015-07-01'
|
|
||||||
# See zc.buildout's changelog if this version is up to date.
|
|
||||||
|
|
||||||
tmpeggs = tempfile.mkdtemp(prefix='bootstrap-')
|
|
||||||
|
|
||||||
usage = '''\
|
|
||||||
[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
|
|
||||||
|
|
||||||
Bootstraps a buildout-based project.
|
|
||||||
|
|
||||||
Simply run this script in a directory containing a buildout.cfg, using the
|
|
||||||
Python that you want bin/buildout to use.
|
|
||||||
|
|
||||||
Note that by using --find-links to point to local resources, you can keep
|
|
||||||
this script from going over the network.
|
|
||||||
'''
|
|
||||||
|
|
||||||
parser = OptionParser(usage=usage)
|
|
||||||
parser.add_option("--version",
|
|
||||||
action="store_true", default=False,
|
|
||||||
help=("Return bootstrap.py version."))
|
|
||||||
parser.add_option("-t", "--accept-buildout-test-releases",
|
|
||||||
dest='accept_buildout_test_releases',
|
|
||||||
action="store_true", default=False,
|
|
||||||
help=("Normally, if you do not specify a --version, the "
|
|
||||||
"bootstrap script and buildout gets the newest "
|
|
||||||
"*final* versions of zc.buildout and its recipes and "
|
|
||||||
"extensions for you. If you use this flag, "
|
|
||||||
"bootstrap and buildout will get the newest releases "
|
|
||||||
"even if they are alphas or betas."))
|
|
||||||
parser.add_option("-c", "--config-file",
|
|
||||||
help=("Specify the path to the buildout configuration "
|
|
||||||
"file to be used."))
|
|
||||||
parser.add_option("-f", "--find-links",
|
|
||||||
help=("Specify a URL to search for buildout releases"))
|
|
||||||
parser.add_option("--allow-site-packages",
|
|
||||||
action="store_true", default=False,
|
|
||||||
help=("Let bootstrap.py use existing site packages"))
|
|
||||||
parser.add_option("--buildout-version",
|
|
||||||
help="Use a specific zc.buildout version")
|
|
||||||
parser.add_option("--setuptools-version",
|
|
||||||
help="Use a specific setuptools version")
|
|
||||||
parser.add_option("--setuptools-to-dir",
|
|
||||||
help=("Allow for re-use of existing directory of "
|
|
||||||
"setuptools versions"))
|
|
||||||
|
|
||||||
options, args = parser.parse_args()
|
|
||||||
if options.version:
|
|
||||||
print("bootstrap.py version %s" % __version__)
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
|
|
||||||
######################################################################
|
|
||||||
# load/install setuptools
|
|
||||||
|
|
||||||
try:
|
|
||||||
from urllib.request import urlopen
|
|
||||||
except ImportError:
|
|
||||||
from urllib2 import urlopen
|
|
||||||
|
|
||||||
ez = {}
|
|
||||||
if os.path.exists('ez_setup.py'):
|
|
||||||
exec(open('ez_setup.py').read(), ez)
|
|
||||||
else:
|
|
||||||
exec(urlopen('https://bootstrap.pypa.io/ez_setup.py').read(), ez)
|
|
||||||
|
|
||||||
if not options.allow_site_packages:
|
|
||||||
# ez_setup imports site, which adds site packages
|
|
||||||
# this will remove them from the path to ensure that incompatible versions
|
|
||||||
# of setuptools are not in the path
|
|
||||||
import site
|
|
||||||
# inside a virtualenv, there is no 'getsitepackages'.
|
|
||||||
# We can't remove these reliably
|
|
||||||
if hasattr(site, 'getsitepackages'):
|
|
||||||
for sitepackage_path in site.getsitepackages():
|
|
||||||
# Strip all site-packages directories from sys.path that
|
|
||||||
# are not sys.prefix; this is because on Windows
|
|
||||||
# sys.prefix is a site-package directory.
|
|
||||||
if sitepackage_path != sys.prefix:
|
|
||||||
sys.path[:] = [x for x in sys.path
|
|
||||||
if sitepackage_path not in x]
|
|
||||||
|
|
||||||
setup_args = dict(to_dir=tmpeggs, download_delay=0)
|
|
||||||
|
|
||||||
if options.setuptools_version is not None:
|
|
||||||
setup_args['version'] = options.setuptools_version
|
|
||||||
if options.setuptools_to_dir is not None:
|
|
||||||
setup_args['to_dir'] = options.setuptools_to_dir
|
|
||||||
|
|
||||||
ez['use_setuptools'](**setup_args)
|
|
||||||
import setuptools
|
|
||||||
import pkg_resources
|
|
||||||
|
|
||||||
# This does not (always?) update the default working set. We will
|
|
||||||
# do it.
|
|
||||||
for path in sys.path:
|
|
||||||
if path not in pkg_resources.working_set.entries:
|
|
||||||
pkg_resources.working_set.add_entry(path)
|
|
||||||
|
|
||||||
######################################################################
|
|
||||||
# Install buildout
|
|
||||||
|
|
||||||
ws = pkg_resources.working_set
|
|
||||||
|
|
||||||
setuptools_path = ws.find(
|
|
||||||
pkg_resources.Requirement.parse('setuptools')).location
|
|
||||||
|
|
||||||
# Fix sys.path here as easy_install.pth added before PYTHONPATH
|
|
||||||
cmd = [sys.executable, '-c',
|
|
||||||
'import sys; sys.path[0:0] = [%r]; ' % setuptools_path +
|
|
||||||
'from setuptools.command.easy_install import main; main()',
|
|
||||||
'-mZqNxd', tmpeggs]
|
|
||||||
|
|
||||||
find_links = os.environ.get(
|
|
||||||
'bootstrap-testing-find-links',
|
|
||||||
options.find_links or
|
|
||||||
('http://downloads.buildout.org/'
|
|
||||||
if options.accept_buildout_test_releases else None)
|
|
||||||
)
|
|
||||||
if find_links:
|
|
||||||
cmd.extend(['-f', find_links])
|
|
||||||
|
|
||||||
requirement = 'zc.buildout'
|
|
||||||
version = options.buildout_version
|
|
||||||
if version is None and not options.accept_buildout_test_releases:
|
|
||||||
# Figure out the most recent final version of zc.buildout.
|
|
||||||
import setuptools.package_index
|
|
||||||
_final_parts = '*final-', '*final'
|
|
||||||
|
|
||||||
def _final_version(parsed_version):
|
|
||||||
try:
|
|
||||||
return not parsed_version.is_prerelease
|
|
||||||
except AttributeError:
|
|
||||||
# Older setuptools
|
|
||||||
for part in parsed_version:
|
|
||||||
if (part[:1] == '*') and (part not in _final_parts):
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
index = setuptools.package_index.PackageIndex(
|
|
||||||
search_path=[setuptools_path])
|
|
||||||
if find_links:
|
|
||||||
index.add_find_links((find_links,))
|
|
||||||
req = pkg_resources.Requirement.parse(requirement)
|
|
||||||
if index.obtain(req) is not None:
|
|
||||||
best = []
|
|
||||||
bestv = None
|
|
||||||
for dist in index[req.project_name]:
|
|
||||||
distv = dist.parsed_version
|
|
||||||
if _final_version(distv):
|
|
||||||
if bestv is None or distv > bestv:
|
|
||||||
best = [dist]
|
|
||||||
bestv = distv
|
|
||||||
elif distv == bestv:
|
|
||||||
best.append(dist)
|
|
||||||
if best:
|
|
||||||
best.sort()
|
|
||||||
version = best[-1].version
|
|
||||||
if version:
|
|
||||||
requirement = '=='.join((requirement, version))
|
|
||||||
cmd.append(requirement)
|
|
||||||
|
|
||||||
import subprocess
|
|
||||||
if subprocess.call(cmd) != 0:
|
|
||||||
raise Exception(
|
|
||||||
"Failed to execute command:\n%s" % repr(cmd)[1:-1])
|
|
||||||
|
|
||||||
######################################################################
|
|
||||||
# Import and run buildout
|
|
||||||
|
|
||||||
ws.add_entry(tmpeggs)
|
|
||||||
ws.require(requirement)
|
|
||||||
import zc.buildout.buildout
|
|
||||||
|
|
||||||
if not [a for a in args if '=' not in a]:
|
|
||||||
args.append('bootstrap')
|
|
||||||
|
|
||||||
# if -c was provided, we push it back into args for buildout' main function
|
|
||||||
if options.config_file is not None:
|
|
||||||
args[0:0] = ['-c', options.config_file]
|
|
||||||
|
|
||||||
zc.buildout.buildout.main(args)
|
|
||||||
shutil.rmtree(tmpeggs)
|
|
16
config.ini.sample
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
[DEFAULT]
|
||||||
|
|
||||||
|
logs = /var/log/kabot.log
|
||||||
|
audio_path = /tmp/
|
||||||
|
voice_channel = channel_name
|
||||||
|
text_channel = channel_name
|
||||||
|
|
||||||
|
[discord]
|
||||||
|
token = <discord_token>
|
||||||
|
|
||||||
|
[gitlab]
|
||||||
|
url = https://gitlab.example.com/
|
||||||
|
token = <GITLAB_TOKEN>
|
||||||
|
|
||||||
|
[giphy]
|
||||||
|
token = <GIPHY_TOKEN>
|
3
entrypoint.sh
Executable file
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
kabot -c $CONFIG_FILE
|
15
kabot/.github/ISSUE_TEMPLATE.md
vendored
|
@ -1,15 +0,0 @@
|
||||||
* Kabot version:
|
|
||||||
* Python version:
|
|
||||||
* Operating System:
|
|
||||||
|
|
||||||
### Description
|
|
||||||
|
|
||||||
Describe what you were trying to get done.
|
|
||||||
Tell us what happened, what went wrong, and what you expected to happen.
|
|
||||||
|
|
||||||
### What I Did
|
|
||||||
|
|
||||||
```
|
|
||||||
Paste the command(s) you ran and the output.
|
|
||||||
If there was a crash, please include the traceback here.
|
|
||||||
```
|
|
|
@ -3,6 +3,7 @@ include CONTRIBUTING.rst
|
||||||
include HISTORY.rst
|
include HISTORY.rst
|
||||||
include LICENSE
|
include LICENSE
|
||||||
include README.rst
|
include README.rst
|
||||||
|
include kabot/utils/ressources/*
|
||||||
|
|
||||||
recursive-include tests *
|
recursive-include tests *
|
||||||
recursive-exclude * __pycache__
|
recursive-exclude * __pycache__
|
||||||
|
|
|
@ -1,88 +0,0 @@
|
||||||
.PHONY: clean clean-test clean-pyc clean-build docs help
|
|
||||||
.DEFAULT_GOAL := help
|
|
||||||
|
|
||||||
define BROWSER_PYSCRIPT
|
|
||||||
import os, webbrowser, sys
|
|
||||||
|
|
||||||
try:
|
|
||||||
from urllib import pathname2url
|
|
||||||
except:
|
|
||||||
from urllib.request import pathname2url
|
|
||||||
|
|
||||||
webbrowser.open("file://" + pathname2url(os.path.abspath(sys.argv[1])))
|
|
||||||
endef
|
|
||||||
export BROWSER_PYSCRIPT
|
|
||||||
|
|
||||||
define PRINT_HELP_PYSCRIPT
|
|
||||||
import re, sys
|
|
||||||
|
|
||||||
for line in sys.stdin:
|
|
||||||
match = re.match(r'^([a-zA-Z_-]+):.*?## (.*)$$', line)
|
|
||||||
if match:
|
|
||||||
target, help = match.groups()
|
|
||||||
print("%-20s %s" % (target, help))
|
|
||||||
endef
|
|
||||||
export PRINT_HELP_PYSCRIPT
|
|
||||||
|
|
||||||
BROWSER := python -c "$$BROWSER_PYSCRIPT"
|
|
||||||
|
|
||||||
help:
|
|
||||||
@python -c "$$PRINT_HELP_PYSCRIPT" < $(MAKEFILE_LIST)
|
|
||||||
|
|
||||||
clean: clean-build clean-pyc clean-test ## remove all build, test, coverage and Python artifacts
|
|
||||||
|
|
||||||
clean-build: ## remove build artifacts
|
|
||||||
rm -fr build/
|
|
||||||
rm -fr dist/
|
|
||||||
rm -fr .eggs/
|
|
||||||
find . -name '*.egg-info' -exec rm -fr {} +
|
|
||||||
find . -name '*.egg' -exec rm -f {} +
|
|
||||||
|
|
||||||
clean-pyc: ## remove Python file artifacts
|
|
||||||
find . -name '*.pyc' -exec rm -f {} +
|
|
||||||
find . -name '*.pyo' -exec rm -f {} +
|
|
||||||
find . -name '*~' -exec rm -f {} +
|
|
||||||
find . -name '__pycache__' -exec rm -fr {} +
|
|
||||||
|
|
||||||
clean-test: ## remove test and coverage artifacts
|
|
||||||
rm -fr .tox/
|
|
||||||
rm -f .coverage
|
|
||||||
rm -fr htmlcov/
|
|
||||||
rm -fr .pytest_cache
|
|
||||||
|
|
||||||
lint: ## check style with flake8
|
|
||||||
flake8 kabot tests
|
|
||||||
|
|
||||||
test: ## run tests quickly with the default Python
|
|
||||||
python setup.py test
|
|
||||||
|
|
||||||
test-all: ## run tests on every Python version with tox
|
|
||||||
tox
|
|
||||||
|
|
||||||
coverage: ## check code coverage quickly with the default Python
|
|
||||||
coverage run --source kabot setup.py test
|
|
||||||
coverage report -m
|
|
||||||
coverage html
|
|
||||||
$(BROWSER) htmlcov/index.html
|
|
||||||
|
|
||||||
docs: ## generate Sphinx HTML documentation, including API docs
|
|
||||||
rm -f docs/kabot.rst
|
|
||||||
rm -f docs/modules.rst
|
|
||||||
sphinx-apidoc -o docs/ kabot
|
|
||||||
$(MAKE) -C docs clean
|
|
||||||
$(MAKE) -C docs html
|
|
||||||
$(BROWSER) docs/_build/html/index.html
|
|
||||||
|
|
||||||
servedocs: docs ## compile the docs watching for changes
|
|
||||||
watchmedo shell-command -p '*.rst' -c '$(MAKE) -C docs html' -R -D .
|
|
||||||
|
|
||||||
release: dist ## package and upload a release
|
|
||||||
twine upload dist/*
|
|
||||||
|
|
||||||
dist: clean ## builds source and wheel package
|
|
||||||
python setup.py sdist
|
|
||||||
python setup.py bdist_wheel
|
|
||||||
ls -l dist
|
|
||||||
|
|
||||||
install: clean ## install the package to the active Python's site-packages
|
|
||||||
python setup.py install
|
|
|
@ -1,6 +1,8 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
"""Top-level package for Kabot."""
|
"""
|
||||||
|
Top-level package for Kabot.
|
||||||
|
"""
|
||||||
|
|
||||||
__author__ = """Michaël Ricart"""
|
__author__ = """Michaël Ricart"""
|
||||||
__email__ = 'michael.ricart@0w.tf'
|
__email__ = 'michael.ricart@0w.tf'
|
||||||
|
|
|
@ -1,106 +1,101 @@
|
||||||
# -*- coding: utf-8 -*-
|
# This example requires the 'message_content' privileged intent to function.
|
||||||
|
|
||||||
"""Main module."""
|
import asyncio
|
||||||
import random
|
|
||||||
|
|
||||||
import discord
|
import discord
|
||||||
|
import yt_dlp as youtube_dl
|
||||||
|
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
from kabot.utils.audio import *
|
||||||
import os
|
from kabot.utils.texte import *
|
||||||
import requests
|
|
||||||
|
|
||||||
class Mybot(commands.Cog):
|
|
||||||
def __init__(self, bot):
|
|
||||||
self.bot = bot
|
|
||||||
|
|
||||||
@commands.command()
|
|
||||||
async def join(self, ctx):
|
|
||||||
channel = [x for x in self.bot.get_all_channels() if x.name == "Général"][0]
|
|
||||||
await channel.connect()
|
|
||||||
|
|
||||||
@commands.command()
|
|
||||||
async def disconnect(self, ctx):
|
|
||||||
await ctx.guild.voice_client.disconnect()
|
|
||||||
|
|
||||||
@commands.command()
|
|
||||||
async def benjamin(self, ctx):
|
|
||||||
source = discord.PCMVolumeTransformer(discord.FFmpegPCMAudio("/tmp/Benjamin_Prejent.mp3"))
|
|
||||||
ctx.voice_client.play(source, after=lambda e: print('Player error: %s' % e) if e else None)
|
|
||||||
await ctx.send('Now playing')
|
|
||||||
|
|
||||||
@commands.command(help='check if bot always online')
|
|
||||||
async def ping(self, message):
|
|
||||||
await message.channel.send('pong')
|
|
||||||
|
|
||||||
@commands.command(help="optionnal args : [livre] [character]")
|
|
||||||
async def kaamelott(self, ctx, *args):
|
|
||||||
response = None
|
|
||||||
if not args:
|
|
||||||
url = 'https://kaamelott.chaudie.re/api/random'
|
|
||||||
else:
|
|
||||||
args = list(args)
|
|
||||||
if args[0].isdigit():
|
|
||||||
livre = int(args[0])
|
|
||||||
args.pop(0)
|
|
||||||
elif args[-1].isdigit():
|
|
||||||
livre = int(args[-1])
|
|
||||||
args.pop(-1)
|
|
||||||
else:
|
|
||||||
livre = None
|
|
||||||
if args:
|
|
||||||
perso = ' '.join(args)
|
|
||||||
if perso and livre:
|
|
||||||
url = 'https://kaamelott.chaudie.re/api/random/livre/%s/personnage/%s' % (livre,perso)
|
|
||||||
elif perso:
|
|
||||||
url = 'https://kaamelott.chaudie.re/api/random/personnage/%s' % perso
|
|
||||||
else:
|
|
||||||
url = 'https://kaamelott.chaudie.re/api/random/livre/%s' % livre
|
|
||||||
try:
|
|
||||||
citation = requests.get(url).json()['citation']
|
|
||||||
response = "%s :\n```\n%s\n```" % (citation['infos']['personnage'], citation['citation'])
|
|
||||||
except:
|
|
||||||
response = "Unknow error, try: !kaamelott [livre] [character]"
|
|
||||||
await ctx.send(response)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
token = "NjI3MTM3NDY1MDA5ODMxOTQ2.XY4Raw.pw8sAen3bNR5aYsoTChQOudM0L8"
|
|
||||||
bot = commands.Bot(command_prefix='!')
|
|
||||||
|
|
||||||
@bot.event
|
intents = discord.Intents.all()
|
||||||
async def on_message(message):
|
intents.message_content = True
|
||||||
print(message.content)
|
|
||||||
if message.author == bot.user:
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
if bot.user in message.mentions \
|
|
||||||
and len(message.mentions) < 3 \
|
|
||||||
and len(message.content.splitlines()) == 1:
|
|
||||||
path = '/tmp/%s.log' % message.channel
|
|
||||||
with open(path, 'r') as f :
|
|
||||||
lines = f.read().splitlines()
|
|
||||||
if not message.content in lines:
|
|
||||||
with open(path, 'a') as f :
|
|
||||||
f.write(message.content + '\n')
|
|
||||||
response = random.choice(lines).replace(str(bot.user.id), str(message.author.id))
|
|
||||||
await message.channel.send(response)
|
|
||||||
await bot.process_commands(message)
|
|
||||||
|
|
||||||
@bot.event
|
|
||||||
async def on_voice_state_update(member,before,after):
|
|
||||||
if "BFlow" in member.name:
|
|
||||||
if before.channel is None and after.channel:
|
|
||||||
for channel in bot.get_all_channels():
|
|
||||||
if channel.name == "général":
|
|
||||||
current_chan = channel
|
|
||||||
ctx = bot.get_context(current_chan.last_message)
|
|
||||||
benjamin = bot.get_command('benjamin')
|
|
||||||
await benjamin.invoke(ctx)
|
|
||||||
|
|
||||||
bot.add_cog(Mybot(bot))
|
bot = commands.Bot(
|
||||||
bot.run(token)
|
command_prefix="!",
|
||||||
|
description='''A ROULEEEEETTES !!
|
||||||
|
HOULA... J'l'ai un peu trop gueulé ça, non ?
|
||||||
|
A roulettes.''',
|
||||||
|
intents=intents,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@bot.event
|
||||||
|
async def on_ready():
|
||||||
|
print(f'Logged in as {bot.user} (ID: {bot.user.id})')
|
||||||
|
print('------')
|
||||||
|
|
||||||
|
|
||||||
|
async def main():
|
||||||
|
## création de l'objet logger
|
||||||
|
logger = logging.getLogger()
|
||||||
|
## definition du log level
|
||||||
|
logger.setLevel(logging.INFO)
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument(
|
||||||
|
"-c",
|
||||||
|
"--config",
|
||||||
|
help="config file",
|
||||||
|
default="config.ini"
|
||||||
|
)
|
||||||
|
args = parser.parse_args()
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
if not os.path.exists(args.config):
|
||||||
|
logger.critical('config file not found')
|
||||||
|
exit(1)
|
||||||
|
config.read(args.config)
|
||||||
|
|
||||||
|
log_file = config['DEFAULT']['logs']
|
||||||
|
## definition du fichier de log (chemin, level, etc ...)
|
||||||
|
formatter = logging.Formatter('%(asctime)s :: %(levelname)s :: %(message)s')
|
||||||
|
file_handler = RotatingFileHandler(log_file, 'a', 1000000, 1)
|
||||||
|
file_handler.setLevel(logging.INFO)
|
||||||
|
file_handler.setFormatter(formatter)
|
||||||
|
logger.addHandler(file_handler)
|
||||||
|
|
||||||
|
if "nickname" in config['DEFAULT']:
|
||||||
|
nickname = config['DEFAULT']['nickname']
|
||||||
|
else:
|
||||||
|
nickname = None
|
||||||
|
if "voice_channel" in config['DEFAULT']:
|
||||||
|
voice_channel = config['DEFAULT']['voice_channel']
|
||||||
|
else:
|
||||||
|
voice_channel = None
|
||||||
|
if "text_channel" in config['DEFAULT']:
|
||||||
|
text_channel = config['DEFAULT']['text_channel']
|
||||||
|
else:
|
||||||
|
text_channel = None
|
||||||
|
audio_path = config['DEFAULT']['audio_path']
|
||||||
|
token = config['discord']['token']
|
||||||
|
gl_url = config['gitlab']['url']
|
||||||
|
gl_token = config['gitlab']['token']
|
||||||
|
gif_token = config['giphy']['token']
|
||||||
|
async with bot:
|
||||||
|
await bot.add_cog(
|
||||||
|
Audio(
|
||||||
|
bot,
|
||||||
|
voice_chan=voice_channel,
|
||||||
|
text_chan=text_channel,
|
||||||
|
audio_path=audio_path,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
await bot.add_cog(
|
||||||
|
Texte(
|
||||||
|
bot,
|
||||||
|
gif_token=gif_token,
|
||||||
|
gl_token=gl_token,
|
||||||
|
gl_url=gl_url,
|
||||||
|
text_chan=text_channel,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
await bot.start(token)
|
||||||
|
|
||||||
|
def run():
|
||||||
|
asyncio.run(main())
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
run()
|
||||||
|
|
||||||
|
|
1
kabot/kabot/utils/__init__.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
##
|
317
kabot/kabot/utils/audio.py
Normal file
|
@ -0,0 +1,317 @@
|
||||||
|
# This example requires the 'message_content' privileged intent to function.
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
|
||||||
|
import discord
|
||||||
|
import yt_dlp as youtube_dl
|
||||||
|
|
||||||
|
import random
|
||||||
|
import os
|
||||||
|
from discord.ext import commands, tasks
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
# Suppress noise about console usage from errors
|
||||||
|
youtube_dl.utils.bug_reports_message = lambda: ''
|
||||||
|
|
||||||
|
|
||||||
|
ytdl_format_options = {
|
||||||
|
'format': 'bestaudio/mp3',
|
||||||
|
'outtmpl': '/tmp/discord_%(title)s-%(id)s.%(ext)s',
|
||||||
|
'postprocessors': [{
|
||||||
|
'key': 'FFmpegExtractAudio',
|
||||||
|
'preferredcodec': 'mp3',
|
||||||
|
'preferredquality': '192',
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
|
ffmpeg_options = {
|
||||||
|
'options': '-vn',
|
||||||
|
}
|
||||||
|
|
||||||
|
ytdl = youtube_dl.YoutubeDL(ytdl_format_options)
|
||||||
|
|
||||||
|
|
||||||
|
class YTDLSource(discord.PCMVolumeTransformer):
|
||||||
|
def __init__(self, source, *, data, volume=0.5):
|
||||||
|
super().__init__(source, volume)
|
||||||
|
|
||||||
|
self.data = data
|
||||||
|
|
||||||
|
self.title = data.get('title')
|
||||||
|
self.url = data.get('url')
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def from_url(cls, url, *, loop=None, stream=False):
|
||||||
|
loop = loop or asyncio.get_event_loop()
|
||||||
|
data = await loop.run_in_executor(None, lambda: ytdl.extract_info(url, download=not stream))
|
||||||
|
|
||||||
|
if 'entries' in data:
|
||||||
|
# take first item from a playlist
|
||||||
|
data = data['entries'][0]
|
||||||
|
|
||||||
|
filename = data['url'] if stream else ytdl.prepare_filename(data)
|
||||||
|
extension = filename.split('.')[-1]
|
||||||
|
filename = filename.replace(extension, 'mp3')
|
||||||
|
return cls(discord.FFmpegPCMAudio(filename, **ffmpeg_options), data=data)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def from_file(cls, audio_file, ctx, *, loop=None, stream=False):
|
||||||
|
source = discord.PCMVolumeTransformer(discord.FFmpegPCMAudio(audio_file,**ffmpeg_options))
|
||||||
|
ctx.voice_client.play(source, after=lambda e: print('Player error: %s' % e) if e else None)
|
||||||
|
|
||||||
|
|
||||||
|
class Audio(commands.Cog, name="Commandes Audio"):
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
bot,
|
||||||
|
audio_path=None,
|
||||||
|
voice_chan=None,
|
||||||
|
text_chan=None):
|
||||||
|
self.bot = bot
|
||||||
|
self.sounds = []
|
||||||
|
self.voice_chan = voice_chan
|
||||||
|
self.text_chan = text_chan
|
||||||
|
self.audio_path = audio_path
|
||||||
|
self.sounds_history = []
|
||||||
|
|
||||||
|
@commands.Cog.listener()
|
||||||
|
async def on_voice_state_update(self, member, before, after):
|
||||||
|
if before.channel is None and after.channel:
|
||||||
|
for channel in self.bot.get_all_channels():
|
||||||
|
if channel.name == self.text_chan:
|
||||||
|
current_chan = channel
|
||||||
|
async for msg in current_chan.history(limit=1):
|
||||||
|
last_message = msg
|
||||||
|
ctx = await self.bot.get_context(last_message)
|
||||||
|
ctx.message.author = member
|
||||||
|
#welcome = bot.get_command('welcome')
|
||||||
|
await asyncio.sleep(2)
|
||||||
|
await self.welcome(ctx, member.display_name)
|
||||||
|
|
||||||
|
@commands.Cog.listener()
|
||||||
|
async def on_ready(self):
|
||||||
|
self.play_next.start()
|
||||||
|
self.pipelette.start()
|
||||||
|
if self.voice_chan:
|
||||||
|
await self.join(self.voice_chan)
|
||||||
|
#await self.welcome(None, 'kabot')
|
||||||
|
|
||||||
|
@commands.command(help="Toi tu fermes ta gueule! Tu la fermes définitivement")
|
||||||
|
async def mute(self, ctx, member: discord.Member=None, mute_time = 10):
|
||||||
|
if member.voice.mute:
|
||||||
|
async with ctx.channel.typing():
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
await ctx.channel.send("Tu ne vas pas m'avoir si facilement")
|
||||||
|
return
|
||||||
|
if not member:
|
||||||
|
async with ctx.channel.typing():
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
await ctx.channel.send("Qui veux-tu mute?")
|
||||||
|
return
|
||||||
|
if mute_time > 60:
|
||||||
|
async with ctx.channel.typing():
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
await ctx.channel.send("Doucement sur le temps!")
|
||||||
|
return
|
||||||
|
member = ctx.message.mentions[0]
|
||||||
|
await member.edit(mute=True)
|
||||||
|
async with ctx.channel.typing():
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
await ctx.send("Tu sors %s!" % member.mention)
|
||||||
|
await asyncio.sleep(mute_time)
|
||||||
|
await member.edit(mute=False)
|
||||||
|
async with ctx.channel.typing():
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
await ctx.channel.send("Tu peux reparler %s!" % member.mention)
|
||||||
|
|
||||||
|
@commands.command(help="Appuie sur la detente PUSSY!")
|
||||||
|
async def roulette(self, ctx):
|
||||||
|
mute_time = 60
|
||||||
|
member = ctx.message.author
|
||||||
|
if not member.voice:
|
||||||
|
async with ctx.typing():
|
||||||
|
await ctx.channel.send("You're not in voice channel")
|
||||||
|
return
|
||||||
|
barillet = [False, False, True, False, False]
|
||||||
|
bullet = random.choice(barillet)
|
||||||
|
await self.joke(ctx, "spinning_and_closed.mp3")
|
||||||
|
if bullet == True:
|
||||||
|
await self.joke(ctx, "omawa_shindeiru.mp3")
|
||||||
|
await asyncio.sleep(2)
|
||||||
|
await member.edit(mute=True)
|
||||||
|
async with ctx.typing():
|
||||||
|
await asyncio.sleep(3)
|
||||||
|
await ctx.channel.send("Perdu, tu es mute pendant 60 secondes!")
|
||||||
|
else:
|
||||||
|
await self.joke(ctx, "hammer_and_dry.mp3")
|
||||||
|
async with ctx.typing():
|
||||||
|
await asyncio.sleep(3)
|
||||||
|
await ctx.channel.send("Gagné, tu ne seras pas mute!")
|
||||||
|
return
|
||||||
|
await asyncio.sleep(mute_time)
|
||||||
|
await member.edit(mute=False)
|
||||||
|
async with ctx.typing():
|
||||||
|
await asyncio.sleep(0.5)
|
||||||
|
await ctx.channel.send("Tu peux reparler %s!" % member.mention)
|
||||||
|
|
||||||
|
@tasks.loop(seconds=300)
|
||||||
|
async def pipelette(self):
|
||||||
|
for channel in self.bot.get_all_channels():
|
||||||
|
if channel.name == self.voice_chan and\
|
||||||
|
len(channel.members) > 1 and\
|
||||||
|
random.choice([True,True,True]):
|
||||||
|
for chan in self.bot.get_all_channels():
|
||||||
|
if chan.name == self.text_chan:
|
||||||
|
current_chan = chan
|
||||||
|
await asyncio.sleep(random.choice(range(305)))
|
||||||
|
async for msg in current_chan.history(limit=1):
|
||||||
|
last_message = msg
|
||||||
|
ctx = await self.bot.get_context(last_message)
|
||||||
|
ctx.message.content = ""
|
||||||
|
await self.joke(ctx)
|
||||||
|
|
||||||
|
@tasks.loop(seconds=1)
|
||||||
|
async def play_next(self):
|
||||||
|
connected_voice = [chan for chan in self.bot.voice_clients if chan.is_connected()]
|
||||||
|
if connected_voice:
|
||||||
|
if not [chan for chan in connected_voice if chan.is_playing()]:
|
||||||
|
if self.sounds:
|
||||||
|
audio_type, audio_file, ctx = self.sounds[0]
|
||||||
|
if 'url' in audio_type:
|
||||||
|
player = await YTDLSource.from_url(audio_file, loop=self.bot.loop)
|
||||||
|
ctx.voice_client.play(player, after=lambda e: print(f'Player error: {e}') if e else None)
|
||||||
|
elif 'file' in audio_type:
|
||||||
|
player = await YTDLSource.from_file(audio_file, ctx)
|
||||||
|
last_audio = self.sounds.pop(0)
|
||||||
|
self.sounds_history.reverse()
|
||||||
|
self.sounds_history.append(last_audio)
|
||||||
|
self.sounds_history.reverse()
|
||||||
|
if len(self.sounds_history) > 5:
|
||||||
|
self.sounds_history = self.sounds_history[:5]
|
||||||
|
|
||||||
|
@commands.command(help='Troll commands', hidden=True)
|
||||||
|
async def okre(self, ctx):
|
||||||
|
await self.joke(ctx, "tu_dois_tout_donner.mp3")
|
||||||
|
|
||||||
|
@commands.command(help='Clear sound queue')
|
||||||
|
async def clear(self, ctx):
|
||||||
|
self.sounds = []
|
||||||
|
|
||||||
|
@commands.command()
|
||||||
|
async def welcome(self, ctx, user=None):
|
||||||
|
"""Joue le son d'accueil de l'utilisateur"""
|
||||||
|
if not user:
|
||||||
|
user = ctx.message.author.name
|
||||||
|
try:
|
||||||
|
audio_file = random.choice([f for f in os.listdir(self.audio_path + '%s/' % user) if f.endswith('.mp3')])
|
||||||
|
audio_file = self.audio_path + '/%s/' % user + audio_file
|
||||||
|
except:
|
||||||
|
audio_file = random.choice([f for f in Path(self.audio_path + '/').glob('**/*.mp3')])
|
||||||
|
self.sounds.append(('file', audio_file, ctx))
|
||||||
|
|
||||||
|
@commands.command()
|
||||||
|
async def repeat(self, ctx):
|
||||||
|
"""Rejouer le dernier son joué"""
|
||||||
|
user = ctx.message.author.name
|
||||||
|
source = self.sounds_history[0]
|
||||||
|
self.sounds.append(source)
|
||||||
|
|
||||||
|
@commands.command(help="detail du dernier son joué")
|
||||||
|
async def last(self, ctx, number = 1):
|
||||||
|
number = int(number)
|
||||||
|
for sound in self.sounds_history[0:number]:
|
||||||
|
await ctx.channel.send("```"+str(sound[1])+"```")
|
||||||
|
|
||||||
|
@commands.command()
|
||||||
|
async def join(self, chan_name: discord.VoiceChannel):
|
||||||
|
"""Joins a voice channel"""
|
||||||
|
|
||||||
|
#if ctx.voice_client is not None:
|
||||||
|
# return await ctx.voice_client.move_to(channel)
|
||||||
|
channel = [x for x in self.bot.get_all_channels() if x.name == chan_name][0]
|
||||||
|
return await channel.connect()
|
||||||
|
|
||||||
|
await channel.connect()
|
||||||
|
|
||||||
|
@commands.command()
|
||||||
|
async def play(self, ctx, *, url):
|
||||||
|
"""Plays from a url (almost anything youtube_dl supports)"""
|
||||||
|
self.sounds.append(('url',url,ctx))
|
||||||
|
|
||||||
|
@commands.command()
|
||||||
|
async def stream(self, ctx, *, url):
|
||||||
|
"""Streams from a url (same as yt, but doesn't predownload)"""
|
||||||
|
|
||||||
|
async with ctx.typing():
|
||||||
|
player = await YTDLSource.from_url(url, loop=self.bot.loop, stream=True)
|
||||||
|
ctx.voice_client.play(player, after=lambda e: print(f'Player error: {e}') if e else None)
|
||||||
|
|
||||||
|
await ctx.send(f'Now playing: {player.title}')
|
||||||
|
|
||||||
|
@commands.command()
|
||||||
|
async def stop(self, ctx):
|
||||||
|
"""Stoppe la lecture en cours"""
|
||||||
|
await ctx.voice_client.stop()
|
||||||
|
|
||||||
|
@commands.command()
|
||||||
|
async def volume(self, ctx, volume: int):
|
||||||
|
"""Changes the player's volume"""
|
||||||
|
|
||||||
|
if ctx.voice_client is None:
|
||||||
|
return await ctx.send("Not connected to a voice channel.")
|
||||||
|
|
||||||
|
ctx.voice_client.source.volume = volume / 100
|
||||||
|
await ctx.send(f"Changed volume to {volume}%")
|
||||||
|
|
||||||
|
@commands.command()
|
||||||
|
async def leave(self, ctx):
|
||||||
|
"""Stops and disconnects the bot from voice"""
|
||||||
|
|
||||||
|
await ctx.voice_client.disconnect()
|
||||||
|
|
||||||
|
@commands.command()
|
||||||
|
async def find(self, ctx, query):
|
||||||
|
"""Cherche un son dans la bibliothèque (5 resultat max)"""
|
||||||
|
query = query.lower()
|
||||||
|
audio_files = [f for f in Path(self.audio_path + '/').glob('**/*.mp3') if query in str(f).lower()]
|
||||||
|
if not audio_files:
|
||||||
|
await ctx.channel.send("%s not found" % query)
|
||||||
|
else:
|
||||||
|
for file in audio_files[:6]:
|
||||||
|
await ctx.channel.send("```"+str(file)+"```")
|
||||||
|
|
||||||
|
@commands.command()
|
||||||
|
async def joke(self, ctx, folder=None):
|
||||||
|
"""Joue un son (aléatoire par défaut)"""
|
||||||
|
try:
|
||||||
|
user = ctx.message.author.name
|
||||||
|
if not folder or not ctx.message.content:
|
||||||
|
audio_file = random.choice([f"{f}" for f in Path(self.audio_path + '/').glob('**/*.mp3')])
|
||||||
|
elif folder:
|
||||||
|
folder = folder.lower()
|
||||||
|
audio_files = [f for f in Path(self.audio_path + '/').glob('**/*.mp3') if folder in str(f).lower()]
|
||||||
|
if not audio_files:
|
||||||
|
await ctx.channel.send("%s not found" % folder)
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
audio_file = random.choice(audio_files)
|
||||||
|
self.sounds.append(('file', audio_file, ctx))
|
||||||
|
except:
|
||||||
|
e = exc_info()[0]
|
||||||
|
await ctx.channel.send("Exception when calling joke: %s\n" % e)
|
||||||
|
|
||||||
|
@play.before_invoke
|
||||||
|
@joke.before_invoke
|
||||||
|
@repeat.before_invoke
|
||||||
|
@stream.before_invoke
|
||||||
|
async def ensure_voice(self, ctx):
|
||||||
|
if ctx.voice_client is None:
|
||||||
|
if ctx.author.voice:
|
||||||
|
await ctx.author.voice.channel.connect()
|
||||||
|
else:
|
||||||
|
await ctx.send("You are not connected to a voice channel.")
|
||||||
|
raise commands.CommandError("Author not connected to a voice channel.")
|
||||||
|
elif ctx.voice_client.is_playing():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
BIN
kabot/kabot/utils/ressources/avatar_bot/404.jpg
Normal file
After Width: | Height: | Size: 7.3 KiB |
BIN
kabot/kabot/utils/ressources/avatar_bot/Bender.jpg
Normal file
After Width: | Height: | Size: 7.7 KiB |
BIN
kabot/kabot/utils/ressources/avatar_bot/Gaspard_et_Balthazar.jpg
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
kabot/kabot/utils/ressources/avatar_bot/Gunther.jpg
Normal file
After Width: | Height: | Size: 6.1 KiB |
BIN
kabot/kabot/utils/ressources/avatar_bot/Kabot.jpg
Normal file
After Width: | Height: | Size: 5.4 KiB |
After Width: | Height: | Size: 8.4 KiB |
BIN
kabot/kabot/utils/ressources/avatar_bot/Zoidberg.jpg
Normal file
After Width: | Height: | Size: 9.3 KiB |
1012
kabot/kabot/utils/ressources/base_kml.xml
Normal file
100
kabot/kabot/utils/ressources/contrepeteries.txt
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
Il faudrait une bonne purge à cette vaisselle!;Il faudrait une bonne verge à cette pucelle!
|
||||||
|
Ma belle-mère admire les rossignols du caroubier. ;Ma belle-mère admire les roubignolles du carossier.
|
||||||
|
Votre père a l'air mutin. ;Votre mère a l'air putain.
|
||||||
|
L'Empereur est arrivé à pied par la Chine.;L'Empereur est arrivé à chier par la pinne.
|
||||||
|
Est-ce un feu de poutre? ;Est-ce un peu de foutre?
|
||||||
|
Mammouth écrase les prix. ;Mammie écrase les prouts.
|
||||||
|
C'est ici qu'on pendit le fuselage de l'aviatrice.;C'est ici qu'on fendit le pucelage de l'aviatrice.
|
||||||
|
Les étudiantes admiraient le factum du recteur. ;Les étudiantes admiraient le rectum du facteur.
|
||||||
|
Les laborieuses populations du Cap.;Les laborieuses copulations du Pape.
|
||||||
|
La cuvette est pleine de bouillon. ;La buvette est pleine de couillons.
|
||||||
|
Le scorpion est malade. ;Le morpion escalade.
|
||||||
|
Quel beau métier: professeur! ;Quel beau fessier: prometteur!
|
||||||
|
Elle est folle de la messe.;Elle est molle de la fesse.
|
||||||
|
Dès qu'on touche à son petit banc, cet enfant boude. ;Des qu'on touche à son petit bout, cet enfant bande.
|
||||||
|
A la vue des Nippons, la Chine se soulève.;A la vue des nichons, la pine se soulève.
|
||||||
|
Glisser dans la piscine. ;Pisser dans la glicine.
|
||||||
|
Taisez-vous en bas! ;Baisez-vous en tas!
|
||||||
|
Ma soeur taille des jupes au Pirée.;Ma soeur taille des pipes aux jurés.
|
||||||
|
Pour bien dîner, il faut être peu. ;Pour bien pinner, il faut être deux.
|
||||||
|
Auberge de Vendée.;Aux verges de bander.
|
||||||
|
Chère collaboratrice, je vous laisse le choix dans la date.;Chère collaboratrice, je vous laisse le doigt dans la chatte.
|
||||||
|
Parachute.;Char à putes.
|
||||||
|
Couper les nouilles au sécateur.;Couper les couilles au sénateur.
|
||||||
|
Empiler les culottes.;Enculer les pilotes.
|
||||||
|
L'assistante brouille l'écoute de l'ingénieur qui a une panne de micro. ;L'assistante broute les couilles de l'ingénieur qui a une pine de maquereau.
|
||||||
|
Un mine de chapeau.;Une pine de chameau.
|
||||||
|
Arriver à Béziers la veille. ;Arriver à baiser la vieille.
|
||||||
|
J'ai des rebords à mes épaulettes. ;J'ai des remords à baiser Paulette.
|
||||||
|
Allons, chérie, essuie ça vite et bien.;Allons, chérie, essuie sa bite et vient.
|
||||||
|
Ces colonnes de gauchistes se branchent devant l'Irak. ;Ces cochonnes de Gaullistes se branlent devant Chirac.
|
||||||
|
La princesse aime la dotation du roi. ;La princesse aime la rotation du doigt.
|
||||||
|
La femme du capitaine à fait mander le marin à bord.;La femme du capitaine à fait bander le marin à mort.
|
||||||
|
À l'Éducation Nationale, on aime bien l'équipe en place. ;A l'Education Nationale, on aime bien les pipes en classe.
|
||||||
|
Escalope sur une salade.;Escalade sur une salope.
|
||||||
|
Le gros entrepreneur pétrit le béton à la tonne. ;Le gros entrepreneur pétrit le têton à la bonne.
|
||||||
|
La jeune paysanne rêve devant un beau vendeur. ;La jeune paysanne rêve devant un veau bandeur.
|
||||||
|
L'archéologue met dans des caisses le produit de ses fouilles. ;L'archéologue met dans des fesses le produit de ses couilles.
|
||||||
|
Cette femme habite les gîtes.;Cette femme agite les bites.
|
||||||
|
Le préfet de Nîmes voudrait plus d'écus pour son Gard. ;Le préfet de Nîmes voudrait plus d'égard pour son cul.
|
||||||
|
Souhaitez-vous, Monsieur, des nouilles encore?;Souhaitez-vous, Monsieur, des couilles en or?
|
||||||
|
Aucun homme n'est jamais assez fort pour ce calcul.;Aucun homme n'éjacule assez fort pour se calmer.
|
||||||
|
J'aime vachement votre frangin.;J'aime franchement votre vagin.
|
||||||
|
Je te verrais bien en curé, avec une calotte. ;Je te verrais bien enculé avec une carotte.
|
||||||
|
La philantropie de l'ouvrier charpentier.;La tripe en folie de l'ouvrier partant chier.
|
||||||
|
Deux carrioles sans mulet.;Deux marrioles s'enculaient.
|
||||||
|
La jeune fille revient de la ferme pleine d'espoir jusqu'au pont du Jura.;La jeune fille revient de la foire pleine de sperme jusqu'au ras du jupon.
|
||||||
|
Alors que les athées se battent, les abbés se taisent.;Alors que les abbés se tâtent, les athés se baisent.
|
||||||
|
Cette jolie fille habite Laval. ;Cette jolie fille avale la bite.
|
||||||
|
L'Afrique est bonne hôtesse quand la canicule nous emballe. ;La trique est bonne aux fesses quand le cannibale nous encule.
|
||||||
|
Ces soupers manquent de pains. ;Ces poupées manquent de seins.
|
||||||
|
Elle fait de délicieuses tripes aux papillotes. ;Elle fait de délicieuses pipes aux patriotes.
|
||||||
|
Madame, il faut secouer les mites de vos habits. ;Madame, il faut secouer les bites de vos amis.
|
||||||
|
Elle avait un chapelet de citrouilles autour du cou. ;Elle avait un chapelet de six couilles autour du trou.
|
||||||
|
Il courait tant de buts divers qu'il en perdait sa belle mine.;Il bourrait tant de culs divers qu'il emmerdait sa belle pine.
|
||||||
|
Devenu riche à force de peiner, l'ouvrier roule sur les pépettes.;SDevenu rêche à force de piner, l'ouvrier pèle sur les roupettes.
|
||||||
|
Un curé précis refuse toujours le tennis. ;Un cul rétrécis refuse toujours le pénis.
|
||||||
|
J'ai du tracas jusqu'au cou! ;J'ai du caca jusqu'au trou!
|
||||||
|
On ne peut pas dîner, si on est pas assez pur.;On ne peut pas piner, si on est pas assez dur.
|
||||||
|
Affaissant subitement son broc, le garçon laitier mouilla les fiches de la dactylo et chuta dans la jatte.;Abaissant subitement son froc, le garçon laitier fouilla les miches de la dactylo et juta dans la chatte.
|
||||||
|
Les nonnes aimeraient faire des chatouilles sur leur pape. ;Les nonnes aimeraient faire des papouilles sur leur chatte.
|
||||||
|
Cette jeune femme a l'art de décaler les sons. ;Cette jeune femme a l'art dessaler les cons.
|
||||||
|
La botaniste admire ce plan qui vient de la Guinée. ;La botaniste admire ce gland qui vient de la piner.
|
||||||
|
L'étudiante en archéologie rêve de tomber sur des fouilles curieuses. ;L'étudiante en archéologie rêve de tomber sur des couilles furieuses.
|
||||||
|
Un hachis parmentier. ;Un amant parti chier.
|
||||||
|
Elle est assise sur la berge du ravin.;Elle est assise sur la verge du rabbin.
|
||||||
|
Quel bonheur pour la princesse que la dotation du roi.;Quel bonheur pour la princesse que la rotation du doigt.
|
||||||
|
Les mutins passaient le berge du grand ravin.;Les putains massaient la verge du grand rabbin.
|
||||||
|
Saisons belles qui passent!;Baisons celles qui passent !
|
||||||
|
Le capitaine redoute les proues qui tuent. ;Le capitaine redoute les trous qui puent.
|
||||||
|
La pratique intensive du tennis en pension donne aux jeunes une mine piteuse.;La pratique intensive du pénis en tension donne aux jeunes une pine miteuse.
|
||||||
|
Il court, il court, le furet.;Il court, il fourre, le curé.
|
||||||
|
C'était une fine appellation.;C'était une pine à fellation.
|
||||||
|
C'est dimanche: un coup de vin.;Un coup de manche: c'est divin.
|
||||||
|
Un petit calcul et on s'en va.;Un petit calva et on s'encule.
|
||||||
|
Le chercheur est fatigué après une belle thèse. ;Le chercheur est fatigué après une telle baise.
|
||||||
|
Les corbeaux aiment le sang qui coule à la curée d'un cerf.;Les corsaires aiment le sang qui coule à la raie d'un beau cul.
|
||||||
|
A l'évêché on peut voir un vieux plan de Gap.;A l'évêché on peut voir un vieux gland de pape
|
||||||
|
Elle est folle de la messe. ;Elle est molle de la fesse.
|
||||||
|
Salut Patrick!;Ca pue la trique!
|
||||||
|
Les luxations répétées provoquent la fêlure.;Les fellations répétées provoquent la luxure.
|
||||||
|
A force de mouiller les fiches, je suis arrivé au fond de la colle.;A force de fouiller les miches, je suis arrivé au con de la folle.
|
||||||
|
A la boutique des Milles Bottes, on solde des tennis de pro.;A la boutique des belles mottes, on solde des pénis de trop.
|
||||||
|
A l'armée, le lieutenant veut défiler et le général m'engueule!;A l'armée, le lieutenant veut dégueuler et le général m'enfile!
|
||||||
|
A l'auberge des Deux Reines, le cuisinier entame une vache marginale.;A l'auberge des Nœuds Raides, le cuisinier entame une marche vaginale.
|
||||||
|
A l'auberge du Congre Debout, j'ai humé des Côtes en fût et j'ai senti des rillettes du cru.;A l'auberge du Bougre de Con, j'ai humé des crottes de cul et j'ai senti des filles en rut.
|
||||||
|
A l'auberge du Congre Debout, j'ai mangé de la tourte aux cailles et je me suis délectée d'une vieille fine sans dépôt.;A l'auberge du Bougre de Con, j'ai mangé de la tarte aux couilles et je me suis délectée d'une vieille pine sans défaut.
|
||||||
|
Faites donc voir votre glu à l'ancienne: cette vielle colle s'enflamme au contact des feux.;Faites donc voir votre gland à Lucienne: cette vielle folle s'enflamme au contact des queues.
|
||||||
|
A l'hôtel du Bon Coucher, j'ai goûté un vieux marc très doux et j'ai apprécié la poire à la fine.;A l'hôtel du Con Bouché, j'ai goûté un vieux dard très mou et j'ai apprécié la foire à la pine.
|
||||||
|
A l'idée de voir la Chine, la jeune fille est envahie d'une étrange pâleur.;A l'idée de voir la pine, la jeune fille est envahie d'une étrange chaleur.
|
||||||
|
A quoi bon me pousser pour que je vous trompe?;A quoi bon me trousser pour que je vous pompe?
|
||||||
|
A vouloir aller plus vite que le son, vous risquez de vous briser la nuque!;A vouloir aller plus vite que le con, vous risquez de vous briser l'anus!
|
||||||
|
A Wimbledon, le juge de touche s'est fait acculer derrière Sanchez.;A Wimbledon, le juge de touche s'est fait enculer derrière sa chaise.
|
||||||
|
Madame, admirez donc l'écaille de ces moules!;Madame, admirez donc les couilles de ces mâles!
|
||||||
|
Adjudant, faites bisser l'appel!;Adjudant, faites pisser la belle!
|
||||||
|
Ah Madame! Si vous saviez ce que votre plante me fait!;Ah Madame! si vous saviez ce que votre fente me plaît!
|
||||||
|
Ah! Ma sœur! Vous avez bêché trois allées?! ;Ah! Ma sœur! Vous avez léché trois abbés?!
|
||||||
|
Aimer le blanc, c'est une histoire de goût.;Aimer le gland, c'est une histoire de bout.
|
||||||
|
Les religieuses se lèvent au couchant et se passent facilement de pain jusqu'aux matines.;Les religieuses se lèchent au couvent et se passent facilement de pine jusqu'au matin.
|
||||||
|
Après de pareils faits, vous pouvez vous permettre.;Après de pareils pets, vous pouvez vous faire mettre.
|
||||||
|
Apprendre à calculer en cent leçons.;Apprendre à s'enculer en caleçon.
|
449
kabot/kabot/utils/texte.py
Normal file
|
@ -0,0 +1,449 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""Main module."""
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import aiocron
|
||||||
|
import asyncio
|
||||||
|
import discord
|
||||||
|
import giphy_client
|
||||||
|
import gitlab
|
||||||
|
import logging
|
||||||
|
import lxml
|
||||||
|
import os
|
||||||
|
import random
|
||||||
|
import requests
|
||||||
|
import configparser
|
||||||
|
import argparse
|
||||||
|
import typing
|
||||||
|
import functools
|
||||||
|
|
||||||
|
from bs4 import BeautifulSoup as bs
|
||||||
|
from discord.ext import tasks, commands
|
||||||
|
from giphy_client.rest import ApiException
|
||||||
|
from logging.handlers import RotatingFileHandler
|
||||||
|
from pathlib import Path
|
||||||
|
from subprocess import *
|
||||||
|
from sys import argv,exit, exc_info
|
||||||
|
|
||||||
|
here = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
|
class Texte(commands.Cog):
|
||||||
|
#class Mybot(discord.Client):
|
||||||
|
#Fonctions necesaires pour Kabot.
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
bot,
|
||||||
|
intents=None,
|
||||||
|
gl_url=None,
|
||||||
|
gl_token=None,
|
||||||
|
gif_token=None,
|
||||||
|
audio_path=None,
|
||||||
|
nickname=None,
|
||||||
|
voice_chan=None,
|
||||||
|
text_chan=None,
|
||||||
|
):
|
||||||
|
self.gl_url = gl_url
|
||||||
|
self.gl_token = gl_token
|
||||||
|
self.gif_token = gif_token
|
||||||
|
self.voice_chan = voice_chan
|
||||||
|
self.text_chan = text_chan
|
||||||
|
self.bot = bot
|
||||||
|
self.nickname = nickname
|
||||||
|
|
||||||
|
@commands.Cog.listener()
|
||||||
|
async def on_ready(self):
|
||||||
|
for channel in self.bot.get_all_channels():
|
||||||
|
if channel.name == self.text_chan:
|
||||||
|
current_chan = channel
|
||||||
|
if self.nickname:
|
||||||
|
await self.bot.user.edit(nick=self.nickname)
|
||||||
|
await current_chan.send('Le troll est dans la place !')
|
||||||
|
|
||||||
|
self.kron.start()
|
||||||
|
|
||||||
|
@commands.Cog.listener()
|
||||||
|
async def on_message(self, message):
|
||||||
|
if message.author == self.bot.user and message.content.startswith('!'):
|
||||||
|
if message.content.startswith('!'):
|
||||||
|
ctx = await self.bot.get_context(message)
|
||||||
|
await self.bot.invoke(ctx)
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
if self.bot.user in message.mentions \
|
||||||
|
and len(message.mentions) < 3 \
|
||||||
|
and len(message.content.splitlines()) == 1:
|
||||||
|
path = '/data/log/%s.log' % message.channel
|
||||||
|
with open(path, 'r') as f:
|
||||||
|
lines = f.read().splitlines()
|
||||||
|
if not message.content in lines:
|
||||||
|
with open(path, 'a') as f:
|
||||||
|
f.write(message.content + '\n')
|
||||||
|
response = random.choice(lines).replace(str(self.bot.user.id), str(message.author.id))
|
||||||
|
async with message.channel.typing():
|
||||||
|
if "http" in response:
|
||||||
|
await asyncio.sleep(len(response) / 8)
|
||||||
|
else:
|
||||||
|
await asyncio.sleep(len(response) / 6)
|
||||||
|
await message.channel.send(response)
|
||||||
|
#await self.bot.process_commands(message)
|
||||||
|
|
||||||
|
@commands.command(help='list des commits')
|
||||||
|
async def commits(self, ctx, number = 5):
|
||||||
|
try:
|
||||||
|
if self.gl_url and self.gl_token:
|
||||||
|
number = int(number)
|
||||||
|
gl = gitlab.Gitlab(self.gl_url, self.gl_token)
|
||||||
|
gl.auth()
|
||||||
|
projects = gl.projects.list(search='Kabot')[0]
|
||||||
|
commits = projects.commits.list(all=True)[:number]
|
||||||
|
for commit in commits:
|
||||||
|
detail = commit.attributes
|
||||||
|
await ctx.channel.send("__" + detail['author_name'] + "__: " + detail['title'] + '\n' + detail['web_url'])
|
||||||
|
else:
|
||||||
|
await ctx.channel.send("-_-")
|
||||||
|
except:
|
||||||
|
await ctx.channel.send("-_-")
|
||||||
|
|
||||||
|
|
||||||
|
@commands.command(help="Interrogation issues \n Args: list, search[mot clé] et add[nom de l'issue]")
|
||||||
|
async def issue(self, ctx, *args):
|
||||||
|
if self.gl_url and self.gl_token:
|
||||||
|
if args:
|
||||||
|
args = list(args)
|
||||||
|
gl = gitlab.Gitlab(self.gl_url, self.gl_token)
|
||||||
|
gl.auth()
|
||||||
|
if args[0] == 'list':
|
||||||
|
projects = gl.projects.list(search='Kabot')[0]
|
||||||
|
issues = projects.issues.list()
|
||||||
|
for issue in issues:
|
||||||
|
if "closed" == issue.state:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
await ctx.channel.send('#' + str(issue.id) + ": " + issue.title + '\n' + issue.web_url)
|
||||||
|
elif args[0] == 'search':
|
||||||
|
query = ''.join(args[1:])
|
||||||
|
project = gl.projects.list(search='Kabot')[0]
|
||||||
|
find_issues = project.search("issues", query)
|
||||||
|
for issue in find_issues:
|
||||||
|
await ctx.channel.send("#" + str(issue['id']) + ": " + issue['title'] + '\n' + issue['web_url'])
|
||||||
|
elif args[0] == 'add':
|
||||||
|
title = ' '.join(args[1:])
|
||||||
|
author = title + ' - By ' + ctx.message.author.name
|
||||||
|
projects = gl.projects.list()
|
||||||
|
for project in projects:
|
||||||
|
if "Kabot" == project.name:
|
||||||
|
issue = project.issues.create({'title': author})
|
||||||
|
logger.info("Issue created : %s" % issue.web_url)
|
||||||
|
else:
|
||||||
|
await ctx.channel.send('unknown command')
|
||||||
|
|
||||||
|
@commands.command(help='count lines numbers in quote file')
|
||||||
|
async def lines(self, ctx):
|
||||||
|
path = '/data/log/%s.log' % ctx.channel
|
||||||
|
with open(path, 'r') as f:
|
||||||
|
lines = f.read().splitlines()
|
||||||
|
nb_lines = len(lines)
|
||||||
|
async with ctx.channel.typing():
|
||||||
|
await asyncio.sleep(0.5)
|
||||||
|
await ctx.channel.send("j'ai %s lignes dans mon stock" % nb_lines)
|
||||||
|
|
||||||
|
@commands.command(help='check if bot always online')
|
||||||
|
async def ping(self, message):
|
||||||
|
await message.channel.send('pong')
|
||||||
|
|
||||||
|
@commands.command(help='Restart Bot')
|
||||||
|
async def restart(self, ctx):
|
||||||
|
cmd = self.bot.get_command('leave')
|
||||||
|
await cmd.invoke(ctx)
|
||||||
|
await self.bot.close()
|
||||||
|
exit()
|
||||||
|
|
||||||
|
@commands.command(help='Update local repo')
|
||||||
|
async def update(self, message):
|
||||||
|
output = Popen('git pull'.split(), stdout=PIPE).communicate()[0]
|
||||||
|
cmd_audio = "git -C %s pull" % self.audio_path
|
||||||
|
output += Popen(cmd_audio.split(), stdout=PIPE).communicate()[0]
|
||||||
|
await message.channel.send(output.decode('utf-8'))
|
||||||
|
|
||||||
|
@commands.command(help="randomsur l'avenir des gens.")
|
||||||
|
async def avenir(self, ctx):
|
||||||
|
list_mot = ("tu seras curé, tu t'occuperas plus spécialement du catéchisme. ",
|
||||||
|
"tu seras animateur de soirées pour les gays pride. ",
|
||||||
|
"tu seras gynecologue dans une maison de retraite.",
|
||||||
|
"tu iras vivre en thaïland à cause de ton job. car tu seras ladyboy dans un bar.",
|
||||||
|
"tu sera DSI chez jacky et Michel",
|
||||||
|
"tu seras arroseur de plante aquatique.")
|
||||||
|
choix = random.choice(list_mot)
|
||||||
|
async with ctx.channel.typing():
|
||||||
|
await asyncio.sleep(len(choix) / 4)
|
||||||
|
await ctx.channel.send(choix)
|
||||||
|
|
||||||
|
@commands.command(help="j'adore la cuisine")
|
||||||
|
async def ciboulette(self, ctx):
|
||||||
|
cmd = self.bot.get_command('gif')
|
||||||
|
ctx.message.content = "!gif ciboulette"
|
||||||
|
await cmd.invoke(ctx)
|
||||||
|
|
||||||
|
|
||||||
|
@commands.command(help='Faire des choix')
|
||||||
|
async def choice(self, ctx, *words):
|
||||||
|
choices = random.choice(words)
|
||||||
|
await ctx.channel.send(choices)
|
||||||
|
|
||||||
|
@commands.command(help="optionnal args : ")
|
||||||
|
async def contrepeterie(self, ctx, *args):
|
||||||
|
response = None
|
||||||
|
path = here + '/ressources/contrepeteries.txt'
|
||||||
|
with open(path) as file:
|
||||||
|
lines = file.read().splitlines()
|
||||||
|
myline = random.choice(lines)
|
||||||
|
question, reponse = myline.split(";")
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = '''Question ! : %s Réponse : ||%s||''' % (question, reponse)
|
||||||
|
except:
|
||||||
|
response = "Unknow error, try: !contrepeterie [mot clef]"
|
||||||
|
await ctx.send(response)
|
||||||
|
|
||||||
|
@commands.command(help='Gif me')
|
||||||
|
async def gif(self, ctx):
|
||||||
|
query = ctx.message.content.replace('!gif ', '')
|
||||||
|
api_instance = giphy_client.DefaultApi()
|
||||||
|
api_key = self.gif_token
|
||||||
|
lang = 'fr'
|
||||||
|
if api_key:
|
||||||
|
try:
|
||||||
|
api_response = api_instance.gifs_search_get(api_key, query, lang=lang, limit=15)
|
||||||
|
api_response.to_dict()['data'][0]
|
||||||
|
get_url = random.choice(api_response.to_dict()['data'])
|
||||||
|
get_url['url']
|
||||||
|
await ctx.channel.send(get_url['url'])
|
||||||
|
except ApiException as e:
|
||||||
|
await ctx.channel.send("Exception when calling DefaultApi->gifs_search_get: %s\n" % e)
|
||||||
|
else:
|
||||||
|
await ctx.channel.send("Exception : No api key found")
|
||||||
|
|
||||||
|
@commands.command(help="optionnal args : [livre] [character]")
|
||||||
|
async def kaamelott(self, ctx, *args):
|
||||||
|
response = None
|
||||||
|
url = 'https://kaamelott.chaudie.re/api/random'
|
||||||
|
if args and ctx.message.content:
|
||||||
|
args = list(args)
|
||||||
|
if args[0].isdigit():
|
||||||
|
livre = int(args[0])
|
||||||
|
args.pop(0)
|
||||||
|
elif args[-1].isdigit():
|
||||||
|
livre = int(args[-1])
|
||||||
|
args.pop(-1)
|
||||||
|
else:
|
||||||
|
livre = None
|
||||||
|
if args:
|
||||||
|
perso = ' '.join(args)
|
||||||
|
if perso and livre:
|
||||||
|
url = 'https://kaamelott.chaudie.re/api/random/livre/%s/personnage/%s' % (livre, perso)
|
||||||
|
elif perso:
|
||||||
|
url = 'https://kaamelott.chaudie.re/api/random/personnage/%s' % perso
|
||||||
|
else:
|
||||||
|
url = 'https://kaamelott.chaudie.re/api/random/livre/%s' % livre
|
||||||
|
try:
|
||||||
|
citation = requests.get(url).json()['citation']
|
||||||
|
response = "%s :\n```\n%s\n```" % (citation['infos']['personnage'], citation['citation'])
|
||||||
|
except:
|
||||||
|
response = "Unknow error, try: !kaamelott [livre] [character]"
|
||||||
|
await ctx.send(response)
|
||||||
|
|
||||||
|
@commands.command(help="Je menotte une cornemuse et je fume Eddy Malou")
|
||||||
|
async def kamoulox(self, ctx):
|
||||||
|
sans_verbe = get_word('nom').text + " " + get_word('complement').get('m') + " et " + get_word('nom').text + " " + get_word('complement').get('m') + "."
|
||||||
|
nom1 = get_word('nom')
|
||||||
|
nom2 = get_word('nom')
|
||||||
|
un1 = "un"
|
||||||
|
un2 = "un"
|
||||||
|
if nom1.get('gender') == 'F':
|
||||||
|
un1 = "une"
|
||||||
|
if nom2.get('gender') == 'F':
|
||||||
|
un2 = "une"
|
||||||
|
phrase1 = get_word('verbe').text + " " + un1 + " " + nom1.text + " " + random.choice([get_word('complement').get('m'), ""])
|
||||||
|
phrase2 = get_word('verbe').text + " " + un2 + " " + nom2.text + " " + random.choice([get_word('complement').get('m'), ""])
|
||||||
|
avec_verbe = phrase1 + " et " + phrase2 + "."
|
||||||
|
piece = random.choice(['pile', 'face'])
|
||||||
|
if piece == "pile":
|
||||||
|
result = sans_verbe
|
||||||
|
elif piece == "face":
|
||||||
|
result = avec_verbe
|
||||||
|
async with ctx.channel.typing():
|
||||||
|
await asyncio.sleep(len(result)/6)
|
||||||
|
await ctx.send(result)
|
||||||
|
|
||||||
|
|
||||||
|
@commands.dm_only()
|
||||||
|
@commands.command(help="Faire dire des choses au bot")
|
||||||
|
async def say(self, ctx, *message):
|
||||||
|
sentence = ' '.join(message)
|
||||||
|
channel = [x for x in self.bot.get_all_channels() if x.name == self.text_chan][0]
|
||||||
|
guild = self.bot.guilds[0]
|
||||||
|
for word in sentence.split():
|
||||||
|
if word.startswith('@'):
|
||||||
|
members = guild.members
|
||||||
|
for member in members:
|
||||||
|
if member.display_name.lower() in word.lower():
|
||||||
|
sentence = sentence.replace(word, member.mention)
|
||||||
|
await channel.send(sentence)
|
||||||
|
|
||||||
|
@commands.command(help='Who the fuck am i?')
|
||||||
|
async def schizo(self, ctx, *names):
|
||||||
|
name = ' '.join(names)
|
||||||
|
list_name = ["Kabot", "Gaspard et Balthazar", "Bender", "Zoidberg", "Gunther", "MissSaugnacEtCambran2022"]
|
||||||
|
try:
|
||||||
|
current_name = self.bot.user.name
|
||||||
|
list_name.remove(current_name)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
if not name:
|
||||||
|
name = random.choice(list_name)
|
||||||
|
lower_names = [x.lower() for x in list_name]
|
||||||
|
if name.lower() in lower_names:
|
||||||
|
if name:
|
||||||
|
correct_name = [x for x in list_name if x.lower() in name.lower()][0]
|
||||||
|
name = correct_name
|
||||||
|
await self.bot.user.edit(username=name)
|
||||||
|
else:
|
||||||
|
name = "404"
|
||||||
|
await self.bot.user.edit(username="Error 404 name not found!")
|
||||||
|
await ctx.channel.send("Liste des noms = %s" % list_name)
|
||||||
|
img = open(here + "/ressources/avatar_bot/%s.jpg" % name, 'rb')
|
||||||
|
await self.bot.user.edit(avatar=img.read())
|
||||||
|
await self.joke(ctx, name)
|
||||||
|
|
||||||
|
@tasks.loop(seconds=3600)
|
||||||
|
async def kron(self):
|
||||||
|
kron_choice = random.choice([self.kaamelott, self.slap, self.kamoulox, self.contrepeterie, self.schizo, None, None, None, None, None, None, None,None,None,None,None,None,None])
|
||||||
|
if kron_choice != None:
|
||||||
|
await asyncio.sleep(random.choice(range(3550)))
|
||||||
|
for channel in self.bot.get_all_channels():
|
||||||
|
if channel.name == self.text_chan:
|
||||||
|
current_chan = channel
|
||||||
|
async for msg in current_chan.history(limit=1):
|
||||||
|
last_message = msg
|
||||||
|
ctx = await self.bot.get_context(last_message)
|
||||||
|
ctx.message.content = ""
|
||||||
|
await kron_choice(ctx)
|
||||||
|
|
||||||
|
@commands.command(help='slap this ass')
|
||||||
|
async def slap(self, ctx, user=None):
|
||||||
|
slap_multiple = [
|
||||||
|
"%s prend un coup de pied au cul",
|
||||||
|
"Descente du coude sur %s",
|
||||||
|
"%s est propulsé par dessus la TROISIEME CORDE!",
|
||||||
|
"Le mec en rose, c'est moi et le mec en jaune c'est %s! https://giphy.com/gifs/gSIz6gGLhguOY",
|
||||||
|
]
|
||||||
|
if not user or not ctx.message.mentions:
|
||||||
|
online_members = []
|
||||||
|
members = ctx.guild.members
|
||||||
|
for member in members:
|
||||||
|
if str(member.status) == "online":
|
||||||
|
online_members.append(member)
|
||||||
|
user = random.choice(online_members)
|
||||||
|
user = user.mention
|
||||||
|
elif ctx.message.mentions:
|
||||||
|
user = ctx.message.mentions[0]
|
||||||
|
user = user.mention
|
||||||
|
if user == self.bot.user.mention:
|
||||||
|
async with ctx.channel.typing():
|
||||||
|
await asyncio.sleep(0.5)
|
||||||
|
await ctx.channel.send("je tribuche par terre et je sais pas comment")
|
||||||
|
else:
|
||||||
|
async with ctx.channel.typing():
|
||||||
|
await asyncio.sleep(len(slap_multiple) / 4)
|
||||||
|
await ctx.channel.send(random.choice(slap_multiple) % user)
|
||||||
|
|
||||||
|
#Commandes pour troll.
|
||||||
|
@commands.command(help='Troll commands', hidden=True)
|
||||||
|
async def jke(self, ctx):
|
||||||
|
await ctx.channel.send(trollpower())
|
||||||
|
|
||||||
|
@commands.command(help='Troll commands', hidden=True)
|
||||||
|
async def joe(self, ctx):
|
||||||
|
await ctx.channel.send(trollpower())
|
||||||
|
|
||||||
|
@commands.command(help='Troll commands', hidden=True)
|
||||||
|
async def jok(self, ctx):
|
||||||
|
await ctx.channel.send(trollpower())
|
||||||
|
|
||||||
|
@commands.command(help='Troll commands', hidden=True)
|
||||||
|
async def joker(self, ctx):
|
||||||
|
await ctx.channel.send(trollpower(too_long=True))
|
||||||
|
|
||||||
|
@commands.command(help='Troll commands', hidden=True)
|
||||||
|
async def oke(self, ctx):
|
||||||
|
await ctx.channel.send(trollpower())
|
||||||
|
|
||||||
|
def trollpower(too_long=None):
|
||||||
|
if too_long:
|
||||||
|
return("Bah alors, on sait plus écrire, je te donne un indice: t'as une lettre en trop! :sweat_drops: :tongue:")
|
||||||
|
return('Bah alors, on sait plus écrire, je te donne un indice: il te manque une lettre! :sweat_drops: :tongue:')
|
||||||
|
|
||||||
|
def get_word(word_type):
|
||||||
|
"""Chercher les mots pour la fonction kamoulox dans le fichier xml"""
|
||||||
|
content = []
|
||||||
|
with open(here + "/ressources/base_kml.xml", "r", encoding="ISO-8859-1") as file:
|
||||||
|
content = file.readlines()
|
||||||
|
content = "".join(content)
|
||||||
|
bs_content = bs(content, 'lxml')
|
||||||
|
if word_type == 'nom':
|
||||||
|
nom = bs_content.resources.nom.find_all('word')
|
||||||
|
result = random.choice(nom)
|
||||||
|
return result
|
||||||
|
elif word_type == 'nom_propre':
|
||||||
|
nom_propre = bs_content.resources.nompropre.find_all('word')
|
||||||
|
result = random.choice(nom_propre)
|
||||||
|
return result
|
||||||
|
elif word_type == 'verbe':
|
||||||
|
verbe = bs_content.resources.verbe.find_all('word')
|
||||||
|
result = random.choice(verbe)
|
||||||
|
return result
|
||||||
|
elif word_type == 'complement':
|
||||||
|
complement = bs_content.resources.complement.find_all('word')
|
||||||
|
result = random.choice(complement)
|
||||||
|
return result
|
||||||
|
elif word_type == 'nom_special':
|
||||||
|
nom_special = bs_content.resources.complement.find_all('word')
|
||||||
|
result = random.choice(nom_special)
|
||||||
|
return result
|
||||||
|
elif word_type == 'prenom':
|
||||||
|
prenom = bs_content.resources.prenom.find_all('word')
|
||||||
|
result = random.choice(prenom)
|
||||||
|
return result
|
||||||
|
elif word_type == 'prescuse':
|
||||||
|
prescuse = bs_content.resources.prescuse.find_all('word')
|
||||||
|
result = random.choice(prescuse)
|
||||||
|
return result
|
||||||
|
elif word_type == 'scuse1':
|
||||||
|
scuse1 = bs_content.resources.scuse1.find_all('word')
|
||||||
|
result = random.choice(scuse1)
|
||||||
|
return result
|
||||||
|
elif word_type == 'scuse2':
|
||||||
|
scuse2 = bs_content.resources.scuse2.find_all('word')
|
||||||
|
result = random.choice(scuse2)
|
||||||
|
return result
|
||||||
|
elif word_type == 'presulte':
|
||||||
|
presulte = bs_content.resources.presulte.find_all('word')
|
||||||
|
result = random.choice(presulte)
|
||||||
|
return result
|
||||||
|
elif word_type == 'sulte':
|
||||||
|
sulte = bs_content.resources.sulte.find_all('word')
|
||||||
|
result = random.choice(sulte)
|
||||||
|
return result
|
||||||
|
elif word_type == 'postsulte':
|
||||||
|
postsulte = bs_content.resources.presulte.find_all('word')
|
||||||
|
result = random.choice(postsulte)
|
||||||
|
return result
|
||||||
|
elif word_type == 'mail':
|
||||||
|
mail = bs_content.resources.mail.find_all('word')
|
||||||
|
result = random.choice(mail)
|
||||||
|
return result
|
||||||
|
else:
|
||||||
|
result = 'Nique bien ta mère!'
|
||||||
|
return result
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
pip==19.2.3
|
|
||||||
bump2version==0.5.11
|
|
||||||
wheel==0.33.6
|
|
||||||
watchdog==0.9.0
|
|
||||||
flake8==3.7.8
|
|
||||||
tox==3.14.0
|
|
||||||
coverage==4.5.4
|
|
||||||
Sphinx==1.8.5
|
|
||||||
twine==1.14.0
|
|
||||||
|
|
|
@ -15,6 +15,12 @@ requirements = [
|
||||||
'discord.py',
|
'discord.py',
|
||||||
'requests',
|
'requests',
|
||||||
'PyNaCl',
|
'PyNaCl',
|
||||||
|
'aiocron',
|
||||||
|
'python-gitlab',
|
||||||
|
'giphy_client',
|
||||||
|
'yt-dlp',
|
||||||
|
'lxml',
|
||||||
|
'BeautifulSoup4',
|
||||||
]
|
]
|
||||||
|
|
||||||
setup_requirements = [ ]
|
setup_requirements = [ ]
|
||||||
|
@ -24,7 +30,7 @@ test_requirements = [ ]
|
||||||
setup(
|
setup(
|
||||||
author="Michaël Ricart",
|
author="Michaël Ricart",
|
||||||
author_email='michael.ricart@0w.tf',
|
author_email='michael.ricart@0w.tf',
|
||||||
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
|
python_requires='>=3.11',
|
||||||
classifiers=[
|
classifiers=[
|
||||||
'Development Status :: 2 - Pre-Alpha',
|
'Development Status :: 2 - Pre-Alpha',
|
||||||
'Intended Audience :: Developers',
|
'Intended Audience :: Developers',
|
||||||
|
@ -40,13 +46,14 @@ setup(
|
||||||
description="kabot for discord",
|
description="kabot for discord",
|
||||||
entry_points={
|
entry_points={
|
||||||
'console_scripts': [
|
'console_scripts': [
|
||||||
'kabot=kabot.kabot:main',
|
'kabot=kabot.kabot:run',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
install_requires=requirements,
|
install_requires=requirements,
|
||||||
license="BSD license",
|
license="BSD license",
|
||||||
long_description=readme + '\n\n' + history,
|
long_description=readme + '\n\n' + history,
|
||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
|
package_data={'ressources': ['kabot/utils/ressources/*']},
|
||||||
keywords='kabot',
|
keywords='kabot',
|
||||||
name='kabot',
|
name='kabot',
|
||||||
packages=find_packages(include=['kabot', 'kabot.*']),
|
packages=find_packages(include=['kabot', 'kabot.*']),
|
||||||
|
@ -54,6 +61,6 @@ setup(
|
||||||
test_suite='tests',
|
test_suite='tests',
|
||||||
tests_require=test_requirements,
|
tests_require=test_requirements,
|
||||||
url='https://github.com/None/kabot',
|
url='https://github.com/None/kabot',
|
||||||
version='0.1.0',
|
version='0.2.18',
|
||||||
zip_safe=False,
|
zip_safe=False,
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
[tox]
|
|
||||||
envlist = py27, py35, py36, py37 flake8
|
|
||||||
|
|
||||||
[travis]
|
|
||||||
python =
|
|
||||||
3.7: py37
|
|
||||||
3.6: py36
|
|
||||||
3.5: py35
|
|
||||||
2.7: py27
|
|
||||||
|
|
||||||
[testenv:flake8]
|
|
||||||
basepython = python
|
|
||||||
deps = flake8
|
|
||||||
commands = flake8 kabot
|
|
||||||
|
|
||||||
[testenv]
|
|
||||||
setenv =
|
|
||||||
PYTHONPATH = {toxinidir}
|
|
||||||
|
|
||||||
commands = python setup.py test
|
|
37
pinned.cfg
|
@ -1,37 +0,0 @@
|
||||||
[versions]
|
|
||||||
Click = 7.0
|
|
||||||
Jinja2 = 2.10.1
|
|
||||||
MarkupSafe = 1.1.1
|
|
||||||
aiohttp = 3.5.4
|
|
||||||
async-timeout = 3.0.1
|
|
||||||
attrs = 19.1.0
|
|
||||||
binaryornot = 0.4.4
|
|
||||||
certifi = 2019.9.11
|
|
||||||
chardet = 3.0.4
|
|
||||||
cookiecutter = 1.6.0
|
|
||||||
future = 0.17.1
|
|
||||||
idna = 2.8
|
|
||||||
jinja2-time = 0.2.0
|
|
||||||
mr.developer = 2.0.0
|
|
||||||
multidict = 4.5.2
|
|
||||||
poyo = 0.5.0
|
|
||||||
requests = 2.22.0
|
|
||||||
urllib3 = 1.25.6
|
|
||||||
websockets = 6.0
|
|
||||||
whichcraft = 0.6.1
|
|
||||||
yarl = 1.3.0
|
|
||||||
zc.buildout = 2.13.2
|
|
||||||
zc.recipe.egg = 2.0.7
|
|
||||||
|
|
||||||
# Required by:
|
|
||||||
# jinja2-time==0.2.0
|
|
||||||
arrow = 0.15.2
|
|
||||||
|
|
||||||
# Required by:
|
|
||||||
# arrow==0.15.2
|
|
||||||
python-dateutil = 2.8.0
|
|
||||||
|
|
||||||
# Required by:
|
|
||||||
# mr.developer==2.0.0
|
|
||||||
six = 1.12.0
|
|
||||||
|
|