diff --git a/README.md b/README.md index 0c6a447..188bb0a 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,60 @@ -# presentator - A Discord bot that generates FULL powerpoints about a given subject zhanks to openai's gpt3 +# Presentator + A Discord bot that generates FULL powerpoints about a given subject thanks to openai's gpt3 + +# How to use +## Requirements +- Python 3.8 +- Pip +- A Discord bot token +- An openai api key +- (Optional) An Nvidia GPU (for image generation) + +## Installation +- Clone the repository +- Install the requirements with +`pip install -r requirements.txt` +- Create a file named `key.env` and put your openai api key in it +- Create a file named `token.env` and put your discord bot token in it +- In the main.py file, at the first line, enable or disable the image generation (by default it's disabled) +```python +# Enable or disable image generation +use_images = False +``` + +### Image generation (optional) +- Install [Stable Diffusion UI](https://github.com/cmdr2/stable-diffusion-ui) and switch to the `beta` branch. +- Copy the `./image_gen_api/main.py` file to the `stable-diffusion-ui` folder +- Open the file called `Dev Console.cmd` in the `stable-diffusion-ui` folder and run the following commands: +``` +pip install uvicorn +pip install fastapi +``` + +## Running +- Run the `main.py` file with : +``` +python main.py +``` + +### Image generation (optional) +- Open the file called `Dev Console.cmd` in the `stable-diffusion-ui` folder and run the following commands: +``` +uvicorn main:app --reload +``` + +## Commands +- `/present` : Generates a pdf presentation about the given subject + + Options: + - `subject` : The subject of the presentation + - `language` : The language of the presentation (default: `english`) + - `style` : The style of the presentation (default: `default`) + - `indications` : Some more instructions about how the presentation should be generated (default: `None`) +- `/list` : Lists all of your presentations +- `/get` : Gets a presentation by its id another time + +# How it works +- The bot sends a request to the openai api with the given subject and indications in the marp markdown format +- We extract the images from the markdown and send them to the image generation api +- We generate the pdf and html files from the markdown +- We send the pdf and html files to the user \ No newline at end of file diff --git a/imagesGeneration.py b/code/imagesGeneration.py similarity index 100% rename from imagesGeneration.py rename to code/imagesGeneration.py diff --git a/main.py b/code/main.py similarity index 89% rename from main.py rename to code/main.py index 5446980..79dfb2e 100644 --- a/main.py +++ b/code/main.py @@ -1,3 +1,4 @@ +use_images = True import openai # from openai import api_key import discord @@ -9,16 +10,17 @@ import asyncio import logging import datetime import base64 -import imagesGeneration +if use_images: import imagesGeneration logging.basicConfig(level=logging.INFO) -#we open the -intstructions = '''Here is a presentation with marp. It's not possible to make slides longer than 200 characters. to separate slides, +imageint = "" +if use_images: imageint = "To add an image illustration , use ![bg left:50% 70%](a-description-of-the-image.png) at the beginning of the slide, just after "---"-It's not possible to add technical images but only illustrations. The images are generated by an ai, the name of the file should be a detailed description of the image wanted. For example \" ![bg left:50% 100%](a-man-wearing-a hat-ryding-a-bicicle.png)\" but don't need to show a person necessairly." +intstructions = f'''Here is a presentation with marp. It's not possible to make slides longer than 200 characters. to separate slides, " --- " - then go at the line. To add an image illustration , use ![bg left:50% 70%](a-description-of-the-image.png) at the beginning of the slide, just after "---"-It's not possible to add technical images but only illustrations. The images are generated by an ai, the name of the file should be a detailed description of the image wanted. For example " ![bg left:50% 100%](a-man-wearing-a hat-ryding-a-bicicle.png)" but son't need to show a person necessairly. The presentatio should be for everybody, all technical words and concepts, explained. The presentation is minimum 20 slides long. You can use bulletpoints. Use markdown formatting (titles, etc...). The presentation has also a conclusion.''' + then go at the line. The presentatio should be for everybody, all technical words and concepts, explained. {imageint} The presentation is minimum 20 slides long. You can use bulletpoints. Use markdown formatting (titles, etc...). The presentation has also a conclusion.''' bot = discord.Bot() styles = ["default", "gaia", "uncover", "default-dark", "gaia-dark", "uncover-dark"] @@ -93,7 +95,7 @@ class: for image in image_filenames: f.write(image + "\n") #now we generate the images, if there are any - if len(image_filenames) > 0: + if len(image_filenames) > 0 and use_images: #now we first remove the extension from the image filenames by removing the last 4 characters image_filenames = [image[:-4] for image in image_filenames] print(image_filenames) @@ -103,7 +105,7 @@ class: #now we rename the image to remove the _0 from the end of the filename os.rename(f"{os.getcwd()}\\data\\{uid}\\{b64}{datenow}\\{images}_0.png", f"{os.getcwd()}\\data\\{uid}\\{b64}{datenow}\\{images}.png") #now we whait 10 seconds for discord to resume the websocket connection - await asyncio.sleep(10) + # await asyncio.sleep(10) #we execute the command to convert the markdown file to a pdf and html file and also generate the first slide image cmd = f"marp --pdf --allow-local-files ./data/{uid}/{b64}{datenow}/{subject}.md" os.system(cmd) diff --git a/img_gen_api/main.py b/img_gen_api/main.py new file mode 100644 index 0000000..bb69b60 --- /dev/null +++ b/img_gen_api/main.py @@ -0,0 +1,32 @@ +import sdkit +from sdkit.models import load_model +from sdkit.generate import generate_images +from sdkit.utils import save_images, log +from sdkit.filter import apply_filters +import os +from fastapi import FastAPI +#This is an API on the port 9009 that generates images from a prompt +#The prompt is the text that the model will use to generate the image +#The path is the path where the image will be saved +#The model is a model that generates images from text + +path="" +prompt="" +app = FastAPI() +context = sdkit.Context() +context.model_paths['stable-diffusion'] = '.\\models\\stable-diffusion\\openjourney-v2-unpruned.ckpt' +load_model(context, 'stable-diffusion') +context.model_paths['gfpgan'] = '.\\models\\gfpgan\\GFPGANv1.3.pth' +load_model(context, 'gfpgan') +print("Model loaded") +@app.get("/generate_image") +async def generate(prompt,path): + # set the path to the model file on the disk (.ckpt or .safetensors file) + print(f"Generating image for prompt: {prompt} and path: {path}") + # generate the image + image = generate_images(context, prompt=prompt, seed=42, width=512, height=512) + image_face_fixed = apply_filters(context, 'gfpgan', image) + # save the image + save_images(image_face_fixed, dir_path=path, file_name=prompt, output_format='png') + + log.info("Generated images!") \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..4927ba4 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +openai +py-cord \ No newline at end of file