Shad0ws commited on
Commit
6499b67
·
1 Parent(s): 7a14100

Upload 3 files

Browse files
Files changed (3) hide show
  1. README.md +3 -4
  2. app.py +243 -0
  3. requirements.txt +4 -0
README.md CHANGED
@@ -1,13 +1,12 @@
1
  ---
2
  title: AIGenDeck
3
- emoji: 🦀
4
- colorFrom: purple
5
- colorTo: red
6
  sdk: gradio
7
  sdk_version: 3.36.1
8
  app_file: app.py
9
  pinned: false
10
- license: mit
11
  ---
12
 
13
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
  title: AIGenDeck
3
+ emoji: 💻
4
+ colorFrom: indigo
5
+ colorTo: pink
6
  sdk: gradio
7
  sdk_version: 3.36.1
8
  app_file: app.py
9
  pinned: false
 
10
  ---
11
 
12
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py ADDED
@@ -0,0 +1,243 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from gradio.inputs import File as InputFile
3
+ from gradio.outputs import File as OutputFile
4
+ import base64
5
+ import glob
6
+ import os
7
+ import random
8
+ import re
9
+ import string
10
+ from urllib.parse import urlparse
11
+
12
+ import openai
13
+ from icrawler import ImageDownloader
14
+ from icrawler.builtin import GoogleImageCrawler
15
+ from pptx import Presentation
16
+
17
+
18
+ global unique_image_name
19
+ global gptmodel
20
+ unique_image_name = None
21
+
22
+ unique_image_name = ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for _ in
23
+ range(16))
24
+
25
+ def refresh_unique_image_name():
26
+ global unique_image_name
27
+ unique_image_name = ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits)
28
+ for _ in range(16))
29
+ return
30
+
31
+ class PrefixNameDownloader(ImageDownloader):
32
+
33
+ # def get_filename(self, task, default_ext):
34
+ # filename = super(PrefixNameDownloader, self).get_filename(
35
+ # task, default_ext)
36
+ # refresh_unique_image_name()
37
+ # print(unique_image_name)
38
+ # return 'prefix_' + unique_image_name + filename
39
+
40
+ def get_filename(self, task, default_ext):
41
+ url_path = urlparse(task['file_url'])[2]
42
+ if '.' in url_path:
43
+ extension = url_path.split('.')[-1]
44
+ if extension.lower() not in [
45
+ 'jpg', 'jpeg', 'png', 'bmp', 'tiff', 'gif', 'ppm', 'pgm'
46
+ ]:
47
+ extension = default_ext
48
+ else:
49
+ extension = default_ext
50
+ print(unique_image_name)
51
+ filename = base64.b64encode(url_path.encode()).decode()
52
+ return "p_" + unique_image_name + '{}.{}'.format(filename, extension)
53
+
54
+ def generate_ppt(apikey, topic, slide_length, graph_presence, gptmodelname, templatepptx):
55
+
56
+ gptmodel = gptmodelname
57
+
58
+ root = Presentation(templatepptx.name)
59
+
60
+ openai.api_key = apikey
61
+
62
+ strGrpahics = "no"
63
+
64
+ if graph_presence == "Few":
65
+ strGrpahics = "few"
66
+ if graph_presence == "Many":
67
+ strGrpahics = "many"
68
+
69
+ message = f"""Create an outline for a slideshow presentation on the topic of {topic} which is {slide_length}
70
+ slides long. Make sure it is {slide_length} long.
71
+ Create {strGrpahics} images.
72
+ You are allowed to use the following slide types:
73
+ Title Slide - (Title, Subtitle)
74
+ Content Slide - (Title, Content)
75
+ Image Slide - (Title, Content, Image)
76
+ Thanks Slide - (Title)
77
+ Put this tag before the Title Slide: [L_TS]
78
+ Put this tag before the Content Slide: [L_CS]
79
+ Put this tag before the Image Slide: [L_IS]
80
+ Put this tag before the Thanks Slide: [L_THS]
81
+
82
+ Put this tag before the Title: [TITLE]
83
+ Put this tag after the Title: [/TITLE]
84
+ Put this tag before the Subitle: [SUBTITLE]
85
+ Put this tag after the Subtitle: [/SUBTITLE]
86
+ Put this tag before the Content: [CONTENT]
87
+ Put this tag after the Content: [/CONTENT]
88
+ Put this tag before the Image: [IMAGE]
89
+ Put this tag after the Image: [/IMAGE]
90
+ Put "[SLIDEBREAK]" after each slide
91
+ For example:
92
+ [L_TS]
93
+ [TITLE]Among Us[/TITLE]
94
+ [SLIDEBREAK]
95
+ [L_CS]
96
+ [TITLE]What Is Among Us?[/TITLE]
97
+ [CONTENT]
98
+ 1. Among Us is a popular online multiplayer game developed and published by InnerSloth.
99
+ 2. The game is set in a space-themed setting where players take on the roles of Crewmates and Impostors.
100
+ 3. The objective of Crewmates is to complete tasks and identify the Impostors among them, while the Impostors' goal is to sabotage the spaceship and eliminate the Crewmates without being caught.
101
+ [/CONTENT]
102
+ [SLIDEBREAK]
103
+ Elaborate on the Content, provide as much information as possible.
104
+ REMEMBER TO PLACE a [/CONTENT] at the end of the Content.
105
+ Do not include any special characters (?, !, ., :, ) in the Title.
106
+ Do not include any additional information in your response and stick to the format."""
107
+
108
+ response = openai.ChatCompletion.create(
109
+ model=gptmodel,
110
+ messages=[
111
+ {"role": "user", "content": message}
112
+ ]
113
+ )
114
+
115
+ # """ Ref for slide types:
116
+ # 0 -> title and subtitle
117
+ # 1 -> title and content
118
+ # 2 -> section header
119
+ # 3 -> two content
120
+ # 4 -> Comparison
121
+ # 5 -> Title only
122
+ # 6 -> Blank
123
+ # 7 -> Content with caption
124
+ # 8 -> Pic with caption
125
+ # """
126
+
127
+ def delete_all_slides():
128
+ for i in range(len(root.slides) - 1, -1, -1):
129
+ r_id = root.slides._sldIdLst[i].rId
130
+ root.part.drop_rel(r_id)
131
+ del root.slides._sldIdLst[i]
132
+
133
+ def create_title_slide(title, subtitle):
134
+ layout = root.slide_layouts[0]
135
+ slide = root.slides.add_slide(layout)
136
+ slide.shapes.title.text = title
137
+ slide.placeholders[1].text = subtitle
138
+
139
+ def create_section_header_slide(title):
140
+ layout = root.slide_layouts[2]
141
+ slide = root.slides.add_slide(layout)
142
+ slide.shapes.title.text = title
143
+
144
+ def create_title_and_content_slide(title, content):
145
+ layout = root.slide_layouts[1]
146
+ slide = root.slides.add_slide(layout)
147
+ slide.shapes.title.text = title
148
+ slide.placeholders[1].text = content
149
+
150
+ def create_title_and_content_and_image_slide(title, content, image_query):
151
+ layout = root.slide_layouts[8]
152
+ slide = root.slides.add_slide(layout)
153
+ slide.shapes.title.text = title
154
+ slide.placeholders[2].text = content
155
+ refresh_unique_image_name()
156
+ google_crawler = GoogleImageCrawler(downloader_cls=PrefixNameDownloader, storage={'root_dir': os.getcwd()})
157
+ google_crawler.crawl(keyword=image_query, max_num=1)
158
+ dir_path = os.path.dirname(os.path.realpath(__file__))
159
+ file_name = glob.glob(f"p_{unique_image_name}*")
160
+ print(file_name)
161
+ img_path = os.path.join(dir_path, file_name[0])
162
+ slide.shapes.add_picture(img_path, slide.placeholders[1].left, slide.placeholders[1].top,
163
+ slide.placeholders[1].width, slide.placeholders[1].height)
164
+
165
+ def find_text_in_between_tags(text, start_tag, end_tag):
166
+ start_pos = text.find(start_tag)
167
+ end_pos = text.find(end_tag)
168
+ result = []
169
+ while start_pos > -1 and end_pos > -1:
170
+ text_between_tags = text[start_pos + len(start_tag):end_pos]
171
+ result.append(text_between_tags)
172
+ start_pos = text.find(start_tag, end_pos + len(end_tag))
173
+ end_pos = text.find(end_tag, start_pos)
174
+ res1 = "".join(result)
175
+ res2 = re.sub(r"\[IMAGE\].*?\[/IMAGE\]", '', res1)
176
+ if len(result) > 0:
177
+ return res2
178
+ else:
179
+ return ""
180
+
181
+ def search_for_slide_type(text):
182
+ tags = ["[L_TS]", "[L_CS]", "[L_IS]", "[L_THS]"]
183
+ found_text = next((s for s in tags if s in text), None)
184
+ return found_text
185
+
186
+ def parse_response(reply):
187
+ list_of_slides = reply.split("[SLIDEBREAK]")
188
+ for slide in list_of_slides:
189
+ slide_type = search_for_slide_type(slide)
190
+ if slide_type == "[L_TS]":
191
+ create_title_slide(find_text_in_between_tags(str(slide), "[TITLE]", "[/TITLE]"),
192
+ find_text_in_between_tags(str(slide), "[SUBTITLE]", "[/SUBTITLE]"))
193
+ elif slide_type == "[L_CS]":
194
+ create_title_and_content_slide(
195
+ "".join(find_text_in_between_tags(str(slide), "[TITLE]", "[/TITLE]")),
196
+ "".join(find_text_in_between_tags(str(slide), "[CONTENT]",
197
+ "[/CONTENT]")))
198
+ elif slide_type == "[L_IS]":
199
+ create_title_and_content_and_image_slide("".join(find_text_in_between_tags(str(slide), "[TITLE]",
200
+ "[/TITLE]")),
201
+ "".join(find_text_in_between_tags(str(slide), "[CONTENT]",
202
+ "[/CONTENT]")),
203
+ "".join(find_text_in_between_tags(str(slide), "[IMAGE]",
204
+ "[/IMAGE]")))
205
+ elif slide_type == "[L_THS]":
206
+ create_section_header_slide("".join(find_text_in_between_tags(str(slide), "[TITLE]", "[/TITLE]")))
207
+
208
+ def find_title():
209
+ return root.slides[0].shapes.title.text
210
+
211
+ delete_all_slides()
212
+
213
+ print(response)
214
+
215
+ parse_response(response['choices'][0]['message']['content'])
216
+
217
+ root.save(f"{find_title()}.pptx")
218
+
219
+ print("done")
220
+
221
+ output_pptx = find_title() + ".pptx"
222
+
223
+ return output_pptx
224
+
225
+
226
+ iface = gr.Interface(
227
+ fn=generate_ppt,
228
+ inputs=[
229
+ gr.Textbox(label='OpenAI API Key', type='password'),
230
+ gr.Textbox(label='Topic'),
231
+ gr.Number(label='Number of slides', value=5, minimum=5, maximum=20),
232
+ gr.Radio(['None', 'Few', 'Many'], label='Graphical presence', value='Many'),
233
+ gr.Radio(['gpt-3.5-turbo', 'gpt-4'], label='GPT Model', value='gpt-4'),
234
+ InputFile(label="Upload PPTX template (blank .pptx file)"),
235
+ ],
236
+ outputs=[
237
+ OutputFile(label="Download PPTX")
238
+ ],
239
+ title="AIDeckGen",
240
+ description="Enter your OpenAI API Key, Presentation Topic, Number of slides, Graphical presence and upload a PPTX template to generate a presentation."
241
+ )
242
+
243
+ iface.launch()
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ openai
2
+ icrawler
3
+ python-pptx
4
+ beautifulsoup4