Compare commits
528 commits
Author | SHA1 | Date | |
---|---|---|---|
6b9e153de1 | |||
6504c286da | |||
8cca3c1990 | |||
b7d3546cea | |||
6f2460eaef | |||
3cdec52d81 | |||
9a4e9b3735 | |||
2fadbe74c0 | |||
2d8518e169 | |||
26a30c9af8 | |||
d33eb077a7 | |||
daa3c7aa0d | |||
f2b6638616 | |||
d913af4378 | |||
2d893dbda2 | |||
a6a7eb07bc | |||
012feae29c | |||
c3e590fd2c | |||
8e654da976 | |||
5dd913d1ca | |||
e8fef9801e | |||
ff98d6b453 | |||
a046a4d55f | |||
82c5c6501c | |||
ccde0ff81d | |||
30e89ba49c | |||
55d4045a2e | |||
d2291738bb | |||
d77d390efe | |||
c47df4b78c | |||
5792a88911 | |||
a9cc9e20c0 | |||
|
112760299f | ||
|
1f52550d29 | ||
|
1f9fe5dfd1 | ||
|
0c9aeece81 | ||
|
d1f7d91485 | ||
84dd36208f | |||
239bbe259e | |||
34b1c075b6 | |||
dc0ab7d0d7 | |||
|
5bc0329c22 | ||
|
cb007a7126 | ||
|
fbba7aae52 | ||
|
e4a3e88511 | ||
|
8349448540 | ||
|
bbbb4bd21b | ||
|
1611683036 | ||
|
186eccff93 | ||
|
d9925249ad | ||
|
3742c4bd5a | ||
|
c5d3835c57 | ||
|
f5703709d1 | ||
|
a6437ee322 | ||
5207baf83f | |||
b719019dbd | |||
abb7f34d9f | |||
|
7031a76b06 | ||
|
7ab8aa21b9 | ||
|
705ba32565 | ||
|
43508edc66 | ||
|
4999c52437 | ||
|
e790569a27 | ||
|
ef24e2a2bf | ||
|
e391b138e5 | ||
|
1861f39450 | ||
|
de994a3592 | ||
|
3aea250608 | ||
|
a8cc570aa4 | ||
|
21c7969b2a | ||
|
bbdd26a24c | ||
|
0f830d8c18 | ||
310c4288a4 | |||
f74d152d81 | |||
da70ab9d8c | |||
|
812c5139a2 | ||
|
84b09f4217 | ||
|
68525eeafd | ||
|
f127c9ed75 | ||
|
ebae4dabbd | ||
|
84637f4f32 | ||
|
91b758faa9 | ||
|
3beea52ed9 | ||
|
29de2a539a | ||
|
283a3919f0 | ||
|
502911be81 | ||
0bbe882e77 | |||
1dd31a4a81 | |||
|
ba5e20d415 | ||
|
39adda86e2 | ||
|
c4cbaaf9b8 | ||
|
0e714be66f | ||
|
237baf0a1e | ||
|
33be6d59f4 | ||
|
ef4ebf1c35 | ||
|
ec84a18e76 | ||
|
6b3e0a0b4f | ||
|
9fd12991b6 | ||
|
0995303080 | ||
|
fc29b8931b | ||
|
d97895feaf | ||
|
a670726056 | ||
|
8a8db57257 | ||
68ef3d2ea1 | |||
|
aa0274ba22 | ||
|
36b1445994 | ||
|
0903b7a1c7 | ||
|
a6790533d1 | ||
|
6c507593f5 | ||
|
ef1ff4e23c | ||
|
c861d2b854 | ||
|
69bce93eb6 | ||
|
cabbc221d1 | ||
|
bec13c53b5 | ||
|
be29a2942c | ||
|
60697c80c7 | ||
|
f955b71230 | ||
|
648e3dcc57 | ||
|
7434bb9592 | ||
|
e7de70d262 | ||
|
b99f913681 | ||
|
300b138fe2 | ||
518687059f | |||
8efd8d2354 | |||
|
98bf031cd6 | ||
|
175c5f7bd5 | ||
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
|
||||
prod.cfg
|
||||
exploit_overrides.cfg
|
||||
buildout.cfg
|
||||
#buildout.cfg
|
||||
config.ini
|
||||
mr-dev/*
|
||||
.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
|
||||
|
||||
clone this repositori, then :
|
||||
clone this repository, then :
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
|
@ -22,4 +22,34 @@ Utilisation
|
|||
|
||||
.. 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 LICENSE
|
||||
include README.rst
|
||||
include kabot/utils/ressources/*
|
||||
|
||||
recursive-include tests *
|
||||
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 -*-
|
||||
|
||||
"""Top-level package for Kabot."""
|
||||
"""
|
||||
Top-level package for Kabot.
|
||||
"""
|
||||
|
||||
__author__ = """Michaël Ricart"""
|
||||
__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 random
|
||||
import asyncio
|
||||
|
||||
import discord
|
||||
import yt_dlp as youtube_dl
|
||||
|
||||
from discord.ext import commands
|
||||
|
||||
import os
|
||||
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)
|
||||
from kabot.utils.audio import *
|
||||
from kabot.utils.texte import *
|
||||
|
||||
|
||||
def main():
|
||||
token = "NjI3MTM3NDY1MDA5ODMxOTQ2.XY4Raw.pw8sAen3bNR5aYsoTChQOudM0L8"
|
||||
bot = commands.Bot(command_prefix='!')
|
||||
|
||||
intents = discord.Intents.all()
|
||||
intents.message_content = True
|
||||
|
||||
bot = commands.Bot(
|
||||
command_prefix="!",
|
||||
description='''A ROULEEEEETTES !!
|
||||
HOULA... J'l'ai un peu trop gueulé ça, non ?
|
||||
A roulettes.''',
|
||||
intents=intents,
|
||||
)
|
||||
|
||||
|
||||
@bot.event
|
||||
async def on_message(message):
|
||||
print(message.content)
|
||||
if message.author == bot.user:
|
||||
return
|
||||
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:
|
||||
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.run(token)
|
||||
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__":
|
||||
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
|
||||
|
||||
|
0
kabot/kabot/utils/ressources/avatar_bot/.gitkeep
Normal file
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',
|
||||
'requests',
|
||||
'PyNaCl',
|
||||
'aiocron',
|
||||
'python-gitlab',
|
||||
'giphy_client',
|
||||
'yt-dlp',
|
||||
'lxml',
|
||||
'BeautifulSoup4',
|
||||
]
|
||||
|
||||
setup_requirements = [ ]
|
||||
|
@ -24,7 +30,7 @@ test_requirements = [ ]
|
|||
setup(
|
||||
author="Michaël Ricart",
|
||||
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=[
|
||||
'Development Status :: 2 - Pre-Alpha',
|
||||
'Intended Audience :: Developers',
|
||||
|
@ -40,13 +46,14 @@ setup(
|
|||
description="kabot for discord",
|
||||
entry_points={
|
||||
'console_scripts': [
|
||||
'kabot=kabot.kabot:main',
|
||||
'kabot=kabot.kabot:run',
|
||||
],
|
||||
},
|
||||
install_requires=requirements,
|
||||
license="BSD license",
|
||||
long_description=readme + '\n\n' + history,
|
||||
include_package_data=True,
|
||||
package_data={'ressources': ['kabot/utils/ressources/*']},
|
||||
keywords='kabot',
|
||||
name='kabot',
|
||||
packages=find_packages(include=['kabot', 'kabot.*']),
|
||||
|
@ -54,6 +61,6 @@ setup(
|
|||
test_suite='tests',
|
||||
tests_require=test_requirements,
|
||||
url='https://github.com/None/kabot',
|
||||
version='0.1.0',
|
||||
version='0.2.18',
|
||||
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
|
||||
|