Team Ai
Apppublic

MinzChan/ChatGPT-PPT-Generate-With-Azure-OpenAI-API

sourceHugging Faceupdated 3y agoView on Hugging Face
1likes
app.py260 linesDownload Raw Back to root
1import glob2import os3import random4import re5import string6 7import gradio as gr8 9import openai10from icrawler import ImageDownloader11from icrawler.builtin import GoogleImageCrawler, BingImageCrawler12from uuid import uuid413from pptx import Presentation14 15bad_coding_practice = ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for _ in16                              range(16))17 18 19def refresh_bad_coding_practice():20    global bad_coding_practice21    bad_coding_practice = ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits)22                                  for _ in range(16))23    return24 25 26class PrefixNameDownloader(ImageDownloader):27 28    def get_filename(self, task, default_ext):29        filename = super(PrefixNameDownloader, self).get_filename(30            task, default_ext)31        print(bad_coding_practice)32        return 'prefix_' + bad_coding_practice + filename33 34 35def generate_ppt(file, topic, slide_length, api_type, api_base, api_version, api_key):36    print(file.name)37 38    root = Presentation(file.name)39 40    openai.api_type = api_type41    openai.api_base = api_base42    openai.api_version = api_version43    openai.api_key = api_key44 45    message = f"""46    Create content for a slideshow presentation.47    The content's topic is {topic}. 48    The slideshow is {slide_length} slides long. 49    The content is written in the language of the content I give you above.50    51    52    You are allowed to use the following slide types:53    54    Slide types:55    Title Slide - (Title, Subtitle)56    Content Slide - (Title, Content)57    Image Slide - (Title, Content, Image)58    Thanks Slide - (Title)59    60    Put this tag before the Title Slide: [L_TS]61    Put this tag before the Content Slide: [L_CS]62    Put this tag before the Image Slide: [L_IS]63    Put this tag before the Thanks Slide: [L_THS]64    65    Put "[SLIDEBREAK]" after each slide 66    67    For example:68    [L_TS]69    [TITLE]Mental Health[/TITLE]70    71    [SLIDEBREAK]72    73    [L_CS] 74    [TITLE]Mental Health Definition[/TITLE]75    [CONTENT]76    1. Definition: A person’s condition with regard to their psychological and emotional well-being77    2. Can impact one's physical health78    3. Stigmatized too often.79    [/CONTENT]80    81    [SLIDEBREAK]82    83    Put this tag before the Title: [TITLE]84    Put this tag after the Title: [/TITLE]85    Put this tag before the Subitle: [SUBTITLE]86    Put this tag after the Subtitle: [/SUBTITLE]87    Put this tag before the Content: [CONTENT]88    Put this tag after the Content: [/CONTENT]89    Put this tag before the Image: [IMAGE]90    Put this tag after the Image: [/IMAGE]91    92    Elaborate on the Content, provide as much information as possible.93    You put a [/CONTENT] at the end of the Content.94    Do not reply as if you are talking about the slideshow itself. (ex. "Include pictures here about...")95    Do not include any special characters (?, !, ., :, ) in the Title.96    Do not include any additional information in your response and stick to the format."""97 98    if api_type in ("azure", "azure_ad", "azuread"):99        response = openai.ChatCompletion.create(100            engine="GPT-35-Turbo",101            messages=[102                {"role": "user", "content": message}103            ]104        )105    else:106        response = openai.ChatCompletion.create(107            model="gpt-3.5-turbo",108            messages=[109                {"role": "user", "content": message}110            ]111        )        112 113    # """ Ref for slide types:114    # 0 -> title and subtitle115    # 1 -> title and content116    # 2 -> section header117    # 3 -> two content118    # 4 -> Comparison119    # 5 -> Title only120    # 6 -> Blank121    # 7 -> Content with caption122    # 8 -> Pic with caption123    # """124 125    def delete_all_slides():126        for i in range(len(root.slides) - 1, -1, -1):127            r_id = root.slides._sldIdLst[i].rId128            root.part.drop_rel(r_id)129            del root.slides._sldIdLst[i]130 131    def create_title_slide(title, subtitle):132        layout = root.slide_layouts[0]133        slide = root.slides.add_slide(layout)134        slide.shapes.title.text = title135        slide.placeholders[1].text = subtitle136 137    def create_section_header_slide(title):138        layout = root.slide_layouts[2]139        slide = root.slides.add_slide(layout)140        slide.shapes.title.text = title141 142    def create_title_and_content_slide(title, content):143        layout = root.slide_layouts[1]144        slide = root.slides.add_slide(layout)145        slide.shapes.title.text = title146        slide.placeholders[1].text = content147 148    def create_title_and_content_and_image_slide(title, content, image_query):149        layout = root.slide_layouts[8]150        slide = root.slides.add_slide(layout)151        slide.shapes.title.text = title152        slide.placeholders[2].text = content153        refresh_bad_coding_practice()154        bing_crawler = GoogleImageCrawler(downloader_cls=PrefixNameDownloader, storage={'root_dir': os.getcwd()})155        bing_crawler.crawl(keyword=image_query, max_num=1)156        dir_path = os.path.dirname(os.path.realpath(__file__))157        file_name = glob.glob(f"prefix_{bad_coding_practice}*")158        print(file_name)159        img_path = os.path.join(dir_path, file_name[0])160        slide.shapes.add_picture(img_path, slide.placeholders[1].left, slide.placeholders[1].top,161                                 slide.placeholders[1].width, slide.placeholders[1].height)162 163    def find_text_in_between_tags(text, start_tag, end_tag):164        start_pos = text.find(start_tag)165        end_pos = text.find(end_tag)166        result = []167        while start_pos > -1 and end_pos > -1:168            text_between_tags = text[start_pos + len(start_tag):end_pos]169            result.append(text_between_tags)170            start_pos = text.find(start_tag, end_pos + len(end_tag))171            end_pos = text.find(end_tag, start_pos)172        res1 = "".join(result)173        res2 = re.sub(r"\[IMAGE\].*?\[/IMAGE\]", '', res1)174        if len(result) > 0:175            return res2176        else:177            return ""178 179    def search_for_slide_type(text):180        tags = ["[L_TS]", "[L_CS]", "[L_IS]", "[L_THS]"]181        found_text = next((s for s in tags if s in text), None)182        return found_text183 184    def parse_response(reply):185        list_of_slides = reply.split("[SLIDEBREAK]")186        for slide in list_of_slides:187            slide_type = search_for_slide_type(slide)188            if slide_type == "[L_TS]":189                create_title_slide(find_text_in_between_tags(str(slide), "[TITLE]", "[/TITLE]"),190                                   find_text_in_between_tags(str(slide), "[SUBTITLE]", "[/SUBTITLE]"))191            elif slide_type == "[L_CS]":192                create_title_and_content_slide("".join(find_text_in_between_tags(str(slide), "[TITLE]", "[/TITLE]")),193                                               "".join(find_text_in_between_tags(str(slide), "[CONTENT]",194                                                                                 "[/CONTENT]")))195            elif slide_type == "[L_IS]":196                create_title_and_content_and_image_slide("".join(find_text_in_between_tags(str(slide), "[TITLE]",197                                                                                           "[/TITLE]")),198                                                         "".join(find_text_in_between_tags(str(slide), "[CONTENT]",199                                                                                           "[/CONTENT]")),200                                                         "".join(find_text_in_between_tags(str(slide), "[IMAGE]",201                                                                                           "[/IMAGE]")))202            elif slide_type == "[L_THS]":203                create_section_header_slide("".join(find_text_in_between_tags(str(slide), "[TITLE]", "[/TITLE]")))204 205    def find_title():206        return root.slides[0].shapes.title.text207 208    delete_all_slides()209 210    print(response)211 212    parse_response(response['choices'][0]['message']['content'])213 214    name_ = str(uuid4()).replace('-', '')215 216    root.save(f"./{name_}.pptx")217 218    print("done")219 220    dir_path = "./"221    prefix = "prefix_"222 223    for file_name in os.listdir(dir_path):224        if file_name.startswith(prefix):225            file_path = os.path.join(dir_path, file_name)226            if os.path.isfile(file_path):227                os.remove(file_path)228 229    return f"./{name_}.pptx"230 231 232with gr.Blocks(title="ChatGPT PPT框架生成") as demo:233    gr.Markdown("""<h1><center>ChatGPT PPT框架生成</center></h1>""")234    with gr.Row():235        with gr.Column():236            openai_type = gr.Textbox(label="OpenAI API Type", placeholder="azure,azure_ad and azuread for Azure OpenAI, open_ai for OpenAI official", value="azure")237            openai_base = gr.Textbox(label="OpenAI API Base", placeholder="https://xxx.openai.azure.com/ for Azure OpenAI, https://api.openai.com/v1 for OpenAI official", value="https://xxx.openai.azure.com/")238            openai_version = gr.Textbox(label="OpenAI API Version", value="2023-03-15-preview")239            openai_token = gr.Textbox(label="OpenAI API Key", placeholder="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx for Azure OpenAI, sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx for OpenAI official",)240            topic = gr.Textbox(label="PPT的主题或内容")241            length = gr.Slider(minimum=1, maximum=50, value=6, label="生成的PPT页数", step=1)242            theme = gr.File(value="./theme.pptx", file_types=['pptx', 'ppt'], label="PPT模版")243            output_file = gr.File(interactive=False)244 245            topic.submit(246                fn=generate_ppt,247                inputs=[theme, topic, length, openai_type, openai_base, openai_version, openai_token],248                outputs=[output_file]249            )250 251            submit = gr.Button("生成")252            submit.click(253                fn=generate_ppt,254                inputs=[theme, topic, length, openai_type, openai_base, openai_version, openai_token],255                outputs=[output_file]256            )257 258if __name__ == "__main__":259    demo.launch()260