import os from time import sleep from dotenv import load_dotenv from google import genai from reportlab.platypus import Paragraph, Frame from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.lib.pagesizes import A4 from reportlab.lib.utils import ImageReader from reportlab.pdfgen import canvas load_dotenv() api_token = os.environ.get("SYNAP") class Model(): def __init__(self, titulo_pdf, titulo, n_paginas): self.titulo = titulo self.n_paginas = n_paginas self.oppo = genai.Client(api_key=api_token, http_options={"api_version": "v1beta"}) print(f"Escolhendo os Subtemas") self.subtemas = self.API(f"Sobre o tema {titulo} cria no total {self.n_paginas} subtemas para um trabalho academico, e sempre começa com a introdução mas não inclui a conclusão, e deixa nesse formato, Nome_do_subtema - tem que estar tudo junto separado por _, nomes curtos , apenas quero ver os temas, mais nenhuma outra resposta, tudo limpo so com os temas, nao pode ter espaco, tudo precisa estar ligado com _ ou -, mais nenhuma coisa, só os temas separados com _, por exemplo, Redes Neurais pode virar Redes_Neurais, separa com _ e não com -. Subtemas Curtos e devem vir bem escritos e acentuados e curtos (TEMAS CURTOS)").split() sleep(5) print(f"Subtemas Escolhidos!") self.largura, self.altura = A4 self.c = canvas.Canvas(titulo_pdf, pagesize=A4) self.pagina = 0 self.pagina_idc = 0 def capa(self, logo, capaImage, titulo, subtitulo, instituto): self.logo = ImageReader(logo) self.capaImage = ImageReader(capaImage) self.titulo = titulo self.instituto = instituto self.professor = professor x = (self.largura - 350) y = self.altura - 150 self.c.drawImage(self.logo, x + 15, y, width=100, height=100) self.c.setFont("Times-Roman", 10) self.c.drawCentredString(x + 65, 675, "República de Angola") self.c.setFont("Times-Roman", 10) self.c.drawCentredString(x + 65, 660, "Ministério da Educação") self.c.setFont("Times-Roman", 10) self.c.drawCentredString(x + 65, 645, instituto) self.c.setFont("Times-Bold", 35) self.c.drawCentredString(x + 65, 580, titulo) self.c.setFont("Times-Roman", 20) self.c.drawCentredString(x + 65, 550, subtitulo) self.c.drawImage(self.capaImage, (x - 65) / 2, (self.altura - 610), width=(576 + 270)/2, height=(315 + 200)/2) margem = 20 self.c.rect(margem, margem, self.largura - 2*margem, self.altura - 2*margem) self.c.setFont("Times-Roman", 15) self.c.drawCentredString(x + 165, 150, "Docente") self.c.line(320, 100, 490, 100) def integrantes(self, integrantes, disciplina, grupo, classe, turma, curso, turno): self.c.showPage() self.paginar_letra("I") y = 700 self.c.setFont("Times-Bold", 20) self.c.drawCentredString(200, 750, "Integrantes do Grupo") self.integrantes = integrantes numero = 1 for i in integrantes: self.c.setFont("Times-Roman", 15) self.c.drawString(110, y, f"{numero}.") self.c.drawString(130, y, f"{i}") y -= 25 numero += 1 self.c.setFont("Times-Bold", 15) self.c.drawString(110, 300, "Disciplina: ") self.c.setFont("Times-Roman", 15) self.c.drawString(190, 300, disciplina) self.c.setFont("Times-Bold", 15) self.c.drawString(110, 280, "Grupo: ") self.c.setFont("Times-Roman", 15) self.c.drawString(165, 280, grupo) self.c.setFont("Times-Bold", 15) self.c.drawString(110, 260, "Classe: ") self.c.setFont("Times-Roman", 15) self.c.drawString(165, 260, classe) self.c.setFont("Times-Bold", 15) self.c.drawString(110, 240, "Turma: ") self.c.setFont("Times-Roman", 15) self.c.drawString(165, 240, turma) self.c.setFont("Times-Bold", 15) self.c.drawString(110, 220, "Curso: ") self.c.setFont("Times-Roman", 15) self.c.drawString(165, 220, curso) self.c.setFont("Times-Bold", 15) self.c.drawString(110, 200, "Turno: ") self.c.setFont("Times-Roman", 15) self.c.drawString(165, 200, turno) def agradecimentos(self, prof): prompt = f"Cria uma nota de agradecimentos, imagina que um grupo escolara fez um trabalho academico e precisa fazer a parte dos agradecimentos, agradecer a Jesus Cristo e professor/a {prof}, OBS: a nota deve ser pequena, umas 4 linhas, não deve conter simbolos como ** ## ou outro, apenas texto puro, faz om agradecimento de forma geral, sem citar nós como alunos ou turma, apenas agradecendo" print(f"Criando os Agradecimentos - Página {self.pagina}") texto = self.API(prompt) sleep(5) self.c.showPage() self.paginar_letra("II") self.c.setFont("Times-Bold", 17) self.c.drawCentredString(595/2, 750, "Agradecimentos") styles = getSampleStyleSheet() text = f"{texto}" meust = ParagraphStyle( "Marius", parent=styles["Normal"], fontName="Times-Roman", fontSize=12, alignment=4 ) frame = Frame(100, 100, 400, 630, showBoundary=0) p = Paragraph(text, meust) frame.addFromList([p], self.c) def dedicatoria(self): prompt = f"É um trabalho academico, cria uma dedicatoria pequena sobre a startup de criação de software CloseSource de Marius Jabami, uma nota meio pequena, umas 8 linhas, só quero a dedicatoria e mais nada, OBS: não usa simbolos como ** ou ##, podes usar tags html para negritar como " print(f"Criando a Dedicatória - Página {self.pagina}") texto = self.API(prompt) sleep(5) self.c.showPage() self.paginar_letra("III") self.c.setFont("Times-Bold", 17) self.c.drawCentredString(595/2, 750, "Dedicatória") styles = getSampleStyleSheet() text = f"{texto}" meust = ParagraphStyle( "Marius", parent=styles["Normal"], fontName="Times-Roman", fontSize=12, alignment=4 ) frame = Frame(100, 100, 400, 630, showBoundary=0) p = Paragraph(text, meust) frame.addFromList([p], self.c) def epigrafe(self): prompt = "Manda uma frase famosa e aleatoria, com duplos sentidos, OBS: apenas quero a frase, mais nada escrito, interface totalmente limpa, nao usar simbolos como ** ##, apenas texto puro" print(f"Criando a Epígrafe - Página {self.pagina}") texto = self.API(prompt) sleep(5) self.c.showPage() self.paginar_letra("IV") self.c.setFont("Times-Bold", 17) self.c.drawCentredString(595/2, 750, "Epígrafe") styles = getSampleStyleSheet() text = f'"{texto}"' meust = ParagraphStyle( "Marius", parent=styles["Normal"], fontName="Times-Italic", fontSize=12, alignment=2 ) frame = Frame(400, -350, 170, 630, showBoundary=0) p = Paragraph(text, meust) frame.addFromList([p], self.c) def resumo(self): prompt = f"Faz um resumo sobre o tema {self.titulo} em um trabalho academico, dizendo de forma geral o que o trabalho vai abordar OBS: nao usa simbolos como ** ou ##, quero apenas texto puro e apenas o resumo, sem nenhuma outra coisa, e usa
usar dois para quebrar linha de preferência" print(f"Criando o Resumo - Página {self.pagina}") texto = self.API(prompt) sleep(5) self.c.showPage() self.paginar_letra("V") self.c.setFont("Times-Bold", 17) self.c.drawCentredString(595/2, 750, "Resumo") styles = getSampleStyleSheet() text = f"{texto}" meust = ParagraphStyle( "Marius", parent=styles["Normal"], fontName="Times-Roman", fontSize=12, alignment=4 ) frame = Frame(100, 100, 400, 630, showBoundary=0) p = Paragraph(text, meust) frame.addFromList([p], self.c) def indice(self): print(f"Criando Índice - Página {self.pagina}") self.c.showPage() self.paginar_letra("VI") y = 700 self.c.setFont("Times-Bold", 20) self.c.drawCentredString(595/2, 750, "Índice") temas = [] for i in self.subtemas: temas.append(i.replace("_", " ")) x_inicial = 110 x_limite = 500 temas.append("Conclusão") temas.append("Referências Bibliográficas") for nome in temas: self.pagina_idc +=1 self.c.setFont("Times-Roman", 15) self.c.drawString(x_inicial, y, f"{nome} ") largura_nome = self.c.stringWidth(nome, "Times-Roman", 15) x_atual = x_inicial + largura_nome largura_ponto = self.c.stringWidth(".", "Times-Roman", 15) while x_atual + largura_ponto < x_limite: self.c.drawString(x_atual, y, ".") x_atual += largura_ponto if nome == "Conclusão": self.c.drawString(x_limite + 10, y, "I") elif nome == "Referências Bibliográficas": self.c.drawString(x_limite + 10, y, "II") else: self.c.drawString(x_limite + 10, y, str(self.pagina_idc)) y -= 25 def desenvolvimento(self): sub = self.subtemas sub.append("Conclusão") temas = [] for t in sub: temas.append(t.replace("_", " ")) for subtemas in temas: prompt = f""" Você é um assistente especializado em produzir DSENVOLVIMENTOS DE TEXTOS ACADÊMICOS claros, objetivos e bem estruturados. INSTRUÇÕES OBRIGATÓRIAS: - Tema principal: {self.titulo} - Subtema a desenvolver: {subtemas} FORMATO E ESTILO: 1. A saída deve conter APENAS o texto do desenvolvimento. Não inclua títulos, cabeçalho, explicações, notas, listas, metadados ou qualquer tipo de marcação extra. 2. Não utilize símbolos de Markdown (como **, ##, ###, ``` ou blocos de código). NÃO PRODUZA MARKDOWN. 3. São permitidas apenas as seguintes tags HTML: - `
` para uma quebra curta de linha dentro de um parágrafo. - `

` para separar parágrafos (OBRIGATÓRIO: cada novo parágrafo deve começar após exatamente `

`). - `...` para negrito. 4. Não utilize listas com “-”, “*”, “1.” ou similares; escreva em parágrafos contínuos. 5. Não inclua citações, referências, URLs ou notas explicativas. 6. Mantenha tom objetivo, técnico e adequado ao nível informado, evitando qualquer linguagem promocional. 7. Não mistura paragrafos, eles devem ter no maximo 5 linhas, evita misturas, quebre linha sempre que poder 8. Se o subtema for extenso nao tenha medo de desenvolver muito mais CONTEÚDO: - Apresente uma definição breve do subtema no contexto do tema principal. - Desenvolva de 2 a 4 ideias centrais essenciais para compreender o subtema. - Finalize com uma frase conclusiva que sintetize a relevância do subtema dentro do tema principal. EXEMPLO DE FORMATO (não reproduzir no resultado): Parágrafo 1...

Parágrafo 2 com termo importante... ENTREGA: - Responda somente com o desenvolvimento final. - Não inclua linhas em branco extras no início ou no fim. - Use `

` para separar parágrafos e `` apenas para destaque de termos essenciais. DA O TEU MELHOR NA ORGANIZACAO, ORGANIZA MUITO BEM E SEM CONFUSÃO Agora, seguindo rigorosamente todas as instruções acima, gere o resumo solicitado. """ print(f"Criando o Subtema {subtemas} - Página {self.pagina + 1}") texto = self.API(prompt) print(f"Subtema {subtemas} criado!") sleep(10) self.pagina += 1 self.c.showPage() if subtemas == "Conclusão": self.paginar_letra("I") else: self.paginar(self.pagina) self.c.setFont("Times-Bold", 17) self.c.drawCentredString(595/2, 750, subtemas) styles = getSampleStyleSheet() text = f"{texto}" meust = ParagraphStyle( "Marius", parent=styles["Normal"], fontName="Times-Roman", fontSize=12, alignment=4 ) frame = Frame(100, 100, 400, 630, showBoundary=0) p = Paragraph(text, meust) frame.addFromList([p], self.c) def ref(self): prompt = f""" Você é um assistente que gera REFERÊNCIAS BIBLIOGRÁFICAS em formato padronizado. TEMA: {self.titulo} INSTRUÇÕES OBRIGATÓRIAS: 1. Gere EXATAMENTE 5 referências relacionadas ao tema informado. 2. Cada referência deve conter EXATAMENTE 3 linhas: - 1ª linha: Autor(es) e ano. - 2ª linha: Título da obra/artigo. - 3ª linha: Link em formato HTML, usando exclusivamente .... 3. Cada referência deve ser separada da seguinte por exatamente `

`. 4. Não usar listas, não usar markdown, não usar negrito ou itálico nas referências. 5. Não adicionar explicações, textos extras ou comentários — apenas as referências no formato exigido. 6. As referências podem ser fictícias, mas devem parecer verossímeis. FORMATO EXEMPLO (NÃO reproduzir os dados abaixo): Autor, Ano Título da obra link...

Agora gere as 5 referências conforme o tema. """ print(f"Criando o Subtema Referências Bibliográficas - Página {self.pagina + 1}") texto = self.API(prompt) print(f" Trabalho finalizado criado!") #sleep(7) self.c.showPage() self.pagina += 1 self.paginar_letra("II") self.c.setFont("Times-Bold", 17) self.c.drawCentredString(595/2, 750, "Referências Bibliográficas") styles = getSampleStyleSheet() text = f"{texto}" meust = ParagraphStyle( "Marius", parent=styles["Normal"], fontName="Times-Roman", fontSize=12, alignment=4 ) frame = Frame(100, 100, 400, 630, showBoundary=0) p = Paragraph(text, meust) frame.addFromList([p], self.c) def paginar(self, pag): self.c.drawString(500, 50, str(pag)) def paginar_letra(self, pag): self.c.drawString(500, 50, pag) def API(self, prompt): while True: try: sleep(3) print("Gerando...") res = self.oppo.models.generate_content(model="gemma-3-27b-it", contents=prompt) return self.limpar(res.text) except Exception as e: print("erro:", e) print("Tentando novamente") def limpar(self, texto): texto = texto.replace("", "<img>") texto = texto.replace("

", "<p>").replace("

", "</p>") texto = texto.replace("
", "<div>").replace("
", "</div>") texto = texto.replace("

", "<h1>").replace("

", "</h1>") return texto def save(self): self.c.save() def criar_trabalho(logo, capaImage, titulo, subtitulo, instituto, integrantes, prof, disciplina, grupo, classe, turma, curso, turno, n_paginas): txt = [t[0] for t in integrantes] txt1 = [] for i in txt: txt1.append(i) nn = Model(f"{titulo}.pdf", titulo, n_paginas) nn.capa(logo, capaImage, titulo, subtitulo, instituto) nn.integrantes(txt, disciplina, grupo, classe, turma, curso, turno) nn.agradecimentos(prof) nn.dedicatoria() nn.epigrafe() nn.resumo() nn.indice() nn.desenvolvimento() nn.ref() nn.save() return f"{titulo}.pdf" logo = "logo.png" titulo = "Alcoolismo em Angola" inst = "Complexo Escolar Politécnico Girassol" professor = "Hélder Vunge" capa = "images.png" sub = "Alto nível de alcoolismo em Angola" #criar_trabalho(logo, capa, titulo, sub, inst) import numpy as np import gradio as gr with gr.Blocks(theme="NoCrypt/miku") as demo: gr.Markdown("# PaperFlow - As tuas mãos invisíveis") gr.Textbox( label="ISSO PODE DEMORAR ~5MIN, MINHA CPU É RUINZINHA KKK", value="DESENVOLVIDO PELA STARTUP CLOSESOURCE (CS)", interactive=False ) saida_do_pdf = gr.File(label="BAIXAR PDF") with gr.Row(): logo = gr.Image(label="LOGO DO INSTITUTO OU ESCOLA", type="filepath") capaImage = gr.Image(label="IMAGEM DA CAPA", type="filepath") with gr.Row(): titulo = gr.Textbox(label="TÍTULO OU TEMA") subtitulo = gr.Textbox(label="SUBTÍTULO") instituto = gr.Textbox(label="INSTITUTO") with gr.Row(): disciplina = gr.Textbox(label="DISCIPLINA") grupo = gr.Textbox(label="GRUPO") classe = gr.Textbox(label="CLASSE") turma = gr.Textbox(label="TURMA") curso = gr.Textbox(label="CURSO") turno = gr.Textbox(label="TURNO") with gr.Row(): professor = gr.Textbox(label="NOME DO PROFESSOR") n_paginas = gr.Textbox(label="NÚMERO DE PÁGINAS (CONTEÚDO)") integrantes = gr.DataFrame( headers = ["Nome dos Integrantes"], row_count=15, col_count=1, type="array", interactive=True, wrap=True ) botao_criar = gr.Button("CRIAR TRABALHO") botao_criar.click(fn=criar_trabalho, inputs=[logo, capaImage, titulo, subtitulo, instituto, integrantes, professor, disciplina, grupo, classe, turma, curso, turno, n_paginas], outputs=[saida_do_pdf]) demo.launch(share=True)