2019-12-16 14:21:29 -06:00
#!/usr/bin/python
2020-03-12 21:47:50 -05:00
#General purpose Discord Bot developed by Caleb Fontenot (CCF_100)
#Written in python.
2019-12-16 14:21:29 -06:00
# Toggle me for debugging
debug = 1
2020-02-27 20:07:21 -06:00
# Displays warning message
2020-02-27 22:35:09 -06:00
testing = 1
2019-12-16 14:21:29 -06:00
# Import the libraries we will use
2020-02-27 20:07:21 -06:00
#from mega import Mega
2020-03-12 21:47:50 -05:00
import tracemalloc
2020-03-19 16:08:58 -05:00
#from concurrent.futures import ProcessPoolExecutor
2019-12-16 14:21:29 -06:00
from datetime import datetime
from gtts import gTTS
import discord
2020-03-12 21:47:50 -05:00
from discord . ext import commands
2019-12-16 14:21:29 -06:00
import re
import sys
import random
import os
2020-03-19 16:08:58 -05:00
import asyncio
from threading import Thread
2020-02-27 20:07:21 -06:00
import ffmpeg
#import talkey
2020-08-24 14:22:37 -05:00
prefix = ' mad! '
2020-03-12 21:47:50 -05:00
tracemalloc . start ( )
async def madlibsLoop ( ) :
2020-02-27 22:35:09 -06:00
# In the future we will detect what channel we were summoned in, but for now:
2020-03-12 21:47:50 -05:00
activeChannel = 656233549837631508
2020-02-27 22:35:09 -06:00
#Init tts, and connect voice to channel, reinit connection if broken
2020-02-27 20:07:21 -06:00
voiceChannel = client . get_channel ( 682688245964079127 )
voice = await voiceChannel . connect ( )
if voice . is_connected ( ) == True :
await voice . disconnect ( )
voice = await voiceChannel . connect ( )
# Set bot presence
await client . change_presence ( activity = discord . Game ( name = ' madlibs.py ' ) )
# Introduce yourself
channel = client . get_channel ( 656233549837631508 )
2020-03-12 21:47:50 -05:00
await channel . send ( " **<<madlibsDiscord.py <:python:656239601723113472> - Written by CCF_100>>** " )
2020-02-27 20:07:21 -06:00
await channel . send ( " Initial project started on **July 13, 2019** " )
await channel . send ( " Discord Bot started on **December 16, 2019** " )
# Notify if verbose
if debug == 1 :
await channel . send ( " Debug mode is enabled! Being verbose! " )
# Now on to business!
#Declare vars
storyContentStr = [ ]
storyNameStr = [ ]
# Alright, let's get the data from stories.txt
i = 1
f = open ( ' stories.txt ' , ' r ' )
for line in f . readlines ( ) :
if i % 2 == 0 :
storyContent = line
storyContentStr . append ( storyContent )
else :
storyName = line
storyNameStr . append ( storyName )
i + = 1
f . close ( )
2020-08-24 14:22:37 -05:00
# Load files
async with channel . typing ( ) :
#Count the number of lines in storyName, we use this to determine what story to use
print ( storyName )
IntStoryCount = len ( storyNameStr )
await channel . send ( " Detected " + str ( IntStoryCount ) + " stories " )
# Randomly pick what story we will use
story = random . randint ( 1 , IntStoryCount )
2020-02-27 20:07:21 -06:00
await channel . send ( storyNameStr )
# Print current story title, but remove the brackets first
filteredTitle = re . findall ( r ' <(.*?)> ' , storyNameStr [ story - 1 ] )
# print the first result
await channel . send ( " Current story title is " + ' " ' + str ( filteredTitle [ 0 ] ) + ' " ' + ' \n ' )
2019-12-16 16:19:10 -06:00
# Alright, now onto the tricky part. We need to filter out all of the bracketed words in stories.txt, putting them into a list, replacing them with incremental strings. We also need to count how many there are for later.
2019-12-16 14:21:29 -06:00
# Pull all of the items with the <> brackets
2020-02-27 20:07:21 -06:00
filtered = re . findall ( r ' <(.*?)> ' , storyContentStr [ story - 1 ] )
# We got them!
if debug == 1 :
await channel . send ( str ( filtered ) )
# Now we need to count them
replacedNumber = len ( filtered )
# Run a loop to get the words
replaceList = [ ]
2020-02-27 22:35:09 -06:00
#replaceList =['', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24']
2020-02-27 20:07:21 -06:00
replaceList . append ( " " )
await channel . send ( str ( " Type a noun, verb, adjective, or adverb depending on what it asks you, followed by enter. " ) )
for loopCount in range ( replacedNumber ) :
2020-02-27 22:35:09 -06:00
print ( " Times looped: " + str ( loopCount ) )
2020-02-27 20:07:21 -06:00
#Wait for user to reply
await channel . send ( " Give me a(n) " + " ** " + str ( filtered [ loopCount ] ) + " ** " + " : " )
# Push text to gTTS and save it to a file
tts = gTTS ( text = " Give me a(n) " + str ( filtered [ loopCount ] ) + " : " )
os . system ( " rm badCurrentTTS.mp3 " )
2020-02-27 22:35:09 -06:00
os . system ( " rm currentTTS.wav " )
2020-02-27 20:07:21 -06:00
tts . save ( " badCurrentTTS.mp3 " )
# gTTS is stupid and gives us a file that discord.py doesn't understand, so we have to convert it
(
ffmpeg
. input ( ' badCurrentTTS.mp3 ' )
2020-02-27 22:35:09 -06:00
. output ( ' currentTTS.wav ' , audio_bitrate = 48000 , format = ' wav ' , sample_fmt = ' s16 ' , ac = ' 2 ' )
2020-02-27 20:07:21 -06:00
. run ( )
)
if voice . is_playing ( ) == True :
print ( " Audio is playing! Stopping playback! " + ' \n ' )
voice . stop ( )
print ( " Attempting to play audio " + ' \n ' )
2020-02-27 22:35:09 -06:00
voice . play ( discord . FFmpegPCMAudio ( " currentTTS.wav " ) )
2020-08-24 14:22:37 -05:00
message = await client . wait_for ( ' message ' , check = lambda message : message . channel . id == activeChannel )
2020-03-19 16:08:58 -05:00
# , check=lambda messages: message.author.id == ctx.author.id and ctx.channel.id == message == ctx.message.id, timeout=30.0
2020-03-12 21:47:50 -05:00
replaceVar = message . content
2020-02-27 20:07:21 -06:00
print ( " You gave me: " + replaceVar )
replaceList . append ( replaceVar )
print ( replaceList )
2019-12-16 14:21:29 -06:00
# Run a loop to replace the words
2020-02-27 20:07:21 -06:00
await channel . send ( " Replacing Words... " )
# Split the Story Content into a list
storyContentList = re . split ( r ' <.*?> ' , storyContentStr [ story - 1 ] )
# Count the items in the list
storyContentCount = len ( storyContentList )
x = 0
for loopCount in range ( storyContentCount ) :
#print(storyContentList[loopCount])
storyContentList . insert ( x , replaceList [ loopCount ] )
x = x + 2
x = 0
# Merge lists into a string
generatedStory = " "
generatedStory = generatedStory . join ( storyContentList )
# Determine file name for file output
now = datetime . now ( )
currentDate = now . strftime ( " %d - % m- % Y- % H: % M: % S " )
saveFile = ' saved stories/generatedStory- ' + currentDate
2019-12-16 22:59:05 -06:00
# Send Story to Discord
2020-02-27 20:07:21 -06:00
await channel . send ( generatedStory )
await channel . send ( " Processing TTS, please wait! " )
2020-02-27 22:35:09 -06:00
async with channel . typing ( ) :
tts = gTTS ( text = generatedStory + " This story was generated by CCF_100 ' s MadLibs.py " , lang = ' en ' )
os . system ( " rm badCurrentStory.mp3 " )
tts . save ( " badCurrentStory.mp3 " )
# gTTS is stupid and gives us a file that discord.py doesn't understand, so we have to convert it
(
ffmpeg
. input ( ' badCurrentStory.mp3 ' )
. output ( saveFile + ' .mp3 ' , audio_bitrate = 48000 , format = ' wav ' , sample_fmt = ' s16 ' , ac = ' 2 ' )
. run ( )
)
if voice . is_playing ( ) == True :
print ( " Audio is playing! Stopping playback! " + ' \n ' )
2020-02-27 20:07:21 -06:00
voice . stop ( )
2020-02-27 22:35:09 -06:00
print ( " Attempting to play audio " + ' \n ' )
voice . play ( discord . FFmpegPCMAudio ( saveFile + " .mp3 " ) )
2020-02-27 20:07:21 -06:00
#exit()
#Alright! We're done! Let's save the story to a file
if os . path . exists ( " saved stories " ) :
pass
else :
os . system ( " mkdir \" saved stories \" " )
print ( " Saving story to .txt file " )
await channel . send ( " Saving story to .txt file " )
async with channel . typing ( ) :
file = open ( saveFile + ' .txt ' , ' w+ ' )
line_offset = [ ]
offset = 0
for line in file :
line_offset . append ( offset )
offset + = len ( line )
file . seek ( 0 )
file . write ( filteredTitle [ 0 ] + ' \n ' + ' \n ' )
file . write ( generatedStory )
file . write ( ' \n ' + " Generated by Caleb Fontenot \' s madlibs.py " )
file . close ( )
#Send generated .txt file to Discord
await channel . send ( " Sending .txt file... " )
discordFile = discord . File ( saveFile + ' .txt ' , filename = " generatedStory.txt " )
await channel . send ( file = discordFile )
#Send generated .mp3 file to Discord
mp3File = saveFile + ' .mp3 '
2020-02-27 22:35:09 -06:00
def file_size ( fname ) :
statinfo = os . stat ( fname )
2020-02-27 20:07:21 -06:00
return statinfo . st_size
2020-02-27 22:35:09 -06:00
print ( " MP3 is " + str ( file_size ( mp3File ) ) + " bytes. " )
await channel . send ( " Converted WAV is " + str ( file_size ( mp3File ) ) + " bytes. " )
if int ( file_size ( mp3File ) ) < = int ( 8389999 ) :
2020-02-27 20:07:21 -06:00
# File is over 8 MiB! This will fail if we send the file corrected for transmission via Discord's voice chat. Let's send the original instead.
2020-02-27 22:35:09 -06:00
discordFile = discord . File ( " badCurrentStory.mp3 " , filename = saveFile + ' .mp3 ' )
await channel . send ( file = discordFile )
else :
discordFile = discord . File ( saveFile + ' .wav ' , filename = saveFile + ' .wav ' )
2020-02-27 20:07:21 -06:00
await channel . send ( file = discordFile )
2020-03-12 21:47:50 -05:00
#await client.process_commands(message)
2019-12-16 16:19:10 -06:00
#Setup Discord functions and announce on discord that we are ready
2019-12-16 22:59:05 -06:00
2020-03-12 21:47:50 -05:00
class MyClient ( discord . Client ) :
2020-02-27 20:07:21 -06:00
async def on_ready ( self ) :
2020-08-24 14:22:37 -05:00
global prefix
2020-03-12 21:47:50 -05:00
#print(loop)
2020-02-27 20:07:21 -06:00
print ( ' Logged on as ' , self . user )
channel = client . get_channel ( 656233549837631508 )
2020-03-12 21:47:50 -05:00
await channel . send ( " (Yet to be named) Discord bot, successfully connected! " )
await channel . send ( " Developed by CCF_100 " )
2020-02-27 20:07:21 -06:00
if testing == 1 :
await channel . send ( " This bot is currently being worked on! Please don ' t start a game! " )
2020-03-12 21:47:50 -05:00
await channel . send ( " Run `mad!madlibs` to start madlibs " )
2020-02-27 20:07:21 -06:00
print ( " Ready! " )
2020-03-12 21:47:50 -05:00
2020-02-27 20:07:21 -06:00
async def on_message ( self , message , pass_context = True ) :
2020-03-12 21:47:50 -05:00
if message . content == ' mad!madlibs ' :
2020-03-19 16:08:58 -05:00
print ( " lol " )
2020-03-12 21:47:50 -05:00
channel = client . get_channel ( 656233549837631508 )
await madlibsLoop ( )
2020-02-27 20:07:21 -06:00
await channel . send ( " Done! " )
2020-08-24 14:22:37 -05:00
"""
async def on_message ( self , message , pass_context = True ) :
global prefix
if message . content == prefix + ' cough ' :
voiceChannel = client . get_channel ( 690301271382556823 )
voice = await voiceChannel . connect ( )
if voice . is_connected ( ) == True :
await voice . disconnect ( )
voice = await voiceChannel . connect ( )
voice . play ( discord . FFmpegPCMAudio ( " coughing.wav " ) )
"""
2020-03-12 21:47:50 -05:00
#Turn on message logging
2020-03-19 16:08:58 -05:00
"""
2020-03-11 20:30:19 -05:00
async def on_message ( self , message , pass_context = True ) :
2020-03-12 21:47:50 -05:00
if message . content == ' mad!logMessagesOn ' :
pass
if message . author . id == 294976590658666497 :
channel = client . get_channel ( 656233549837631508 )
await channel . send ( " Logging messages to console. " )
global logMessages
logMessages = True
else :
channel = client . get_channel ( 656233549837631508 )
await channel . send ( " You are not authorized to use this command! Only @CCF_100#1050 may use this command! " )
#Turn off message logging
async def on_message ( self , message , pass_context = True ) :
if message . content == ' mad!logMessagesOff ' :
pass
if message . author . id == 294976590658666497 :
channel = client . get_channel ( 656233549837631508 )
await channel . send ( " Stopping message logging! " )
global logMessages
logMessages = False
else :
channel = client . get_channel ( 656233549837631508 )
await channel . send ( " You are not authorized to use this command! Only @CCF_100#1050 may use this command! " )
2020-03-19 16:08:58 -05:00
"""
2020-03-12 21:47:50 -05:00
#Calls message listening function.
2020-03-19 16:08:58 -05:00
#logMessages = False
#async def messageListening():
#global messageslist, messageAuthorList, logMessages
#print("Now Listening for messages...")
#messagesList= []
#messageAuthorList = []
#print("Loop start!")
#x = 0
#while True:
#async def on_message(message):
#raw_message = await client.wait_for('message')
#if logMessages == True:
#print("Loop Count: "+str(x))
#messagesList.append(raw_message.content)
#messageAuthorList.append(raw_message.author.nick)
#if logMessages == True:
#print("Message from "+messageAuthorList[x]+": "+messagesList[x])
#x += 1
#Start messageListening in a new thread to prevent it from stalling the rest of the script
#def startMessageListening():
#asyncio.set_event_loop(loop)
#loop.run_forever() new_loop = asyncio.new_event_loop()
#t = Thread(target=startMessageListening, args=(new_loop,))
#t.start()
2020-03-11 20:30:19 -05:00
#Disconnect Voice
2020-03-12 21:47:50 -05:00
#await asyncio.sleep(60)
#voiceChannel = client.get_channel(682688245964079127)
#await voice.disconnect()
2019-12-16 16:19:10 -06:00
2020-03-11 20:30:19 -05:00
#Run main loop
2019-12-16 23:22:46 -06:00
# The Discord bot ID isn't stored in this script for security reasons, so we have to go get it
f = open ( ' botID.txt ' , ' r ' )
BotID = f . read ( )
2020-02-27 22:35:09 -06:00
#Cleanup from previous session
#os.system("rm badCurrentTTS.mp3")
#os.system("rm currentTTS.wav")
2019-12-16 16:19:10 -06:00
# Connect Bot To Discord and start running
client = MyClient ( )
2020-10-30 08:36:36 -05:00
client . run ( ' NTU5MTE1MDIwMzY2MjUwMDE1.XlgnkA.Cey5xj-T-j3AcJMOdnYV0ymLESY
' )
2019-12-16 16:19:10 -06:00
exit ( )
# say the tts
#print('\n'+"Processing Text-To-Speech, please wait..."+'\n')
#tts = gTTS(text=generatedStory+"This story was generated by Caleb Fontenot's MadLibs.py", lang='en')
#tts.save("TTS.mp3")
##os.system("play TTS.mp3")
#os.system("mv TTS.mp3 "+"\""+saveFile+".mp3"+"\"")
#Start Discord Bot loop