Repository: fga-eps-mds/2022-2-Certifik8 (language: python)

Issue:
Escolher tabela pelo gerenciador de arquivos do tkinter
## Descrição

- Implementação de nova funcionalidade para selecionar o caminho de múltiplas tabelas utilizando o filedialog do tkinter, e também foi definido um padrão para arquivos ".xlsx" para obtenção automática dos dados necessários. 
- Adição de recurso para gerar certificados em massa através de uma lista de paths nos arquivos "certificado.py", "html2pdf.py" e "main.py".

PR relacionados: (https://github.com/fga-eps-mds/2022-2-Certifik8/pull/56) e (https://github.com/fga-eps-mds/2022-2-Certifik8/pull/55)


Discussion / hints:

Fix patch:
diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml
new file mode 100644
index 0000000..4de8bfe
--- /dev/null
+++ b/.github/workflows/linter.yml
@@ -0,0 +1,25 @@
+name: Python Linter
+
+on:
+  push:
+  pull_request:
+  workflow_dispatch:
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3
+      - name: Set up Python
+        uses: actions/setup-python@v4
+        with:
+          python-version: '3.x'
+      - name: Install dependencies
+        run: |
+          python -m pip install --upgrade pip
+          pip install flake8
+          if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
+      - name: Lint flake8
+        run: |
+          flake8 src --count --select=E9,F63,F7,F82 --show-source --statistics
+          flake8 src --count --max-complexity=10 --max-line-length=120 --statistics
diff --git a/.gitignore b/.gitignore
index 7f28e51..23dfda4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
-# Ignora todos os arquivos de Tabelas
-*2022-2-Squad08/.xlsx
\ No newline at end of file
+dist/
+Certifik8.egg-info/
+src/Certifik8/__pycache__/
+poetry.lock
\ No newline at end of file
diff --git a/2022-2-Squad08/main.py b/2022-2-Squad08/main.py
deleted file mode 100644
index 3d94904..0000000
--- a/2022-2-Squad08/main.py
+++ /dev/null
@@ -1,129 +0,0 @@
-from pathlib import Path
-import pdfkit
-import os
-from bs4 import BeautifulSoup
-import pandas as pd
-from datetime import date
-
-
-class DataEmissao:
-    
-    def __init__(self):
-        self.meses = (
-            'Janeiro',
-            'Fevereiro',
-            'Março',
-            'Abril',
-            'Mail',
-            'Junho',
-            'Julho',
-            'Agosto',
-            'Setembro',
-            'Outubro',
-            'Novembro',
-            'Dezembro',
-        )
-
-    def getDataPorExtenso(self) -> str:
-        dia = date.today().strftime('%d')
-        mes = int(date.today().strftime('%m'))-1
-        ano = date.today().strftime('%Y')
-        return f'{dia} de {self.meses[mes]} de {ano}'
-
-    def printDataPorExtensoDebuger(self):
-        print(self.getDataPorExtenso())
-
-class Html2Pdf:
-    """
-    Classe para fazer a conversao de html para pdf
-
-    Returns:
-        _type_: _description_
-    """
-    
-    options = {
-        "page-size": "A5",
-        "orientation": "landscape",
-        "encoding": "UTF-8",
-    }
-    
-    def __init__(self, html="template.html"):
-        self.html2pdf = html
-
-    def convert(self, output_name) -> None: 
-        download_folder = self.get_download_path()
-        pdfkit.from_file(self.html2pdf, download_folder + f"{output_name}.pdf", options=self.options)
-
-    # Funcao que pega o caminho para pasta download do sistema.
-    def get_download_path(self):
-        if os.name == "nt":
-            import winreg
-
-            sub_key = (
-                r"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
-            )
-            downloads_guid = "{374DE290-123F-4565-9164-39C4925E467B}"
-            with winreg.OpenKey(winreg.HKEY_CURRENT_USER, sub_key) as key:
-                location = winreg.QueryValueEx(key, downloads_guid)[0]
-            return location
-        else:
-            return os.path.join(os.path.expanduser("~"), "Downloads/")
-
-class Certificados:
-    html_template = 'template.html'
-    DataEmissao = DataEmissao()
-
-    def get_full_path(self, filename):
-        pre = os.path.dirname(os.path.realpath(__file__))
-        return pre + "/" + filename
-
-    def xlsx_content(self, path):
-        data_frame = pd.read_excel(path)
-        return data_frame
-
-    def gerarCertificados(self, 
-                filename, 
-                nome_evento, 
-                carga_hor,
-                nome_prof,
-                nome_dep,
-                data_inicial,
-                data_final
-                ):
-        try:
-            df = self.xlsx_content(filename)
-        except:
-            df = self.xlsx_content(self.get_full_path(filename))
-
-        data_emissao = self.DataEmissao.getDataPorExtenso()
-        for i in df.index:
-            html_doc = open(self.html_template).read()
-            soup = BeautifulSoup(html_doc, 'html.parser')
-            soup.find("span", class_="nome_participante").replace_with(df['Nome'][i])
-            soup.find("span", class_="cpf_participante").replace_with(df['cpf'][i])
-            soup.find("span", class_="nome_evento").replace_with(nome_evento)
-            soup.find("span", class_="carga_hor").replace_with(carga_hor)
-            soup.find("span", class_="nome_prof").replace_with(nome_prof)
-            soup.find("span", class_="nome_dep").replace_with(nome_dep)
-            soup.find("span", class_="cargo_participante").replace_with(df['Função'][i])
-            soup.find("span", class_="frequencia_participante").replace_with(str(df['Frequência'][i]))
-            soup.find("span", class_="data_inicial").replace_with(data_inicial) 
-            soup.find("span", class_="data_final").replace_with(data_final) 
-            soup.find("span", class_="data_emissao").replace_with(data_emissao) 
-            with open(df['Nome'][i] + '.html', 'w') as file:
-                file.writelines(soup.prettify())
-            Html2Pdfs = Html2Pdf(html=df['Nome'][i]+'.html')
-            Html2Pdfs.convert(df['Nome'][i])
-            os.remove(df['Nome'][i]+'.html')
-
-'''
-filename, 
-                nome_evento, 
-                carga_hor,
-                nome_prof,
-                data_inicial,
-                data_final
-'''
-if __name__ == "__main__":
-    certificados = Certificados()
-    certificados.gerarCertificados("teste.xlsx", "Curso Básico Python", "10", "Bernardini Glauco", "Departamento de Computação", "08 de Novembro de 2022", "17 de Novembro de 2022")
\ No newline at end of file
diff --git a/2022-2-Squad08/template.html b/2022-2-Squad08/template.html
deleted file mode 100644
index 7723385..0000000
--- a/2022-2-Squad08/template.html
+++ /dev/null
@@ -1,76 +0,0 @@
-<!DOCTYPE html>
-<html lang="pt-br">
-<head>
-    <meta charset="UTF-8">
-    <meta http-equiv="X-UA-Compatible" content="IE=edge">
-    <meta name="viewport" content="width=device-width,initial-scale=1.0">
-    <title>Template</title>
-    <style>
-        @import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');
-        main{
-            position: relative;
-            width: 1096px;
-            height: 748px;
-            font-family: 'Roboto', sans-serif;
-            background-image: url(https://cdn.discordapp.com/attachments/1034883038586351647/1049011662566465546/template.png);
-        }
-
-        #texto_principal{
-            position: absolute;
-            top: 250px;
-            left: 148px;
-            width: 800px;
-            text-align: justify;
-            font-size: 18px;
-            font-weight: 700;
-        
-        }
-
-        .nome_participante, .cpf_participante, .nome_evento, .nome_prof, .nome_dep, .cargo_participante, .frequencia_participante{
-            text-transform: uppercase;
-        }
-
-        #local_data{
-            position: absolute;
-            top: 400px;
-            right: 148px;
-            font-size: 22px;
-            font-weight: 700;
-        }
-
-        #informacoes_adicionais{
-            position: absolute;
-            top: 470px;
-            width: 1096px;
-        }
-
-        .texto_adicional{
-            margin: 0;
-            font-size: 22px;
-            text-align: center;
-            font-weight: 700;
-        }
-
-        p.nao_negrito{
-            font-size: 20px;
-            font-weight: 400;
-        }
-    </style>
-</head>
-<body>
-    <main>
-        <p id="texto_principal">Certificamos que, <span class="nome_participante"></span>, CPF <span class="cpf_participante"></span>, participou do
-            evento de extensão <span class="nome_evento"></span>, com carga horária de <span class="carga_hor"></span>
-            hora(s), coordenado pelo(a) Professor(a) <span class="nome_prof"></span>, promovido
-            pelo(a) <span class="nome_dep"></span>, na função de <span class="cargo_participante"></span>,
-            com frequência <span class="frequencia_participante"></span>%. A atividade foi realizada no período de <span class="data_inicial"></span> a
-            <span class="data_final">***</span>.
-        </p>
-        <p id="local_data">Brasília, <span class="data_emissao"></span></p>
-        <div id="informacoes_adicionais">
-            <p class="texto_adicional">OLGAMIR AMANCIA FERREIRA</p>
-            <p class="texto_adicional nao_negrito">Decana de Extensão</p>
-        </div>
-    </main>
-</body>
-</html>
\ No newline at end of file
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
deleted file mode 100644
index a2d7775..0000000
--- a/CODE_OF_CONDUCT.md
+++ /dev/null
@@ -1,128 +0,0 @@
-# Contributor Covenant Code of Conduct
-
-## Our Pledge
-
-We as members, contributors, and leaders pledge to make participation in our
-community a harassment-free experience for everyone, regardless of age, body
-size, visible or invisible disability, ethnicity, sex characteristics, gender
-identity and expression, level of experience, education, socio-economic status,
-nationality, personal appearance, race, religion, or sexual identity
-and orientation.
-
-We pledge to act and interact in ways that contribute to an open, welcoming,
-diverse, inclusive, and healthy community.
-
-## Our Standards
-
-Examples of behavior that contributes to a positive environment for our
-community include:
-
-* Demonstrating empathy and kindness toward other people
-* Being respectful of differing opinions, viewpoints, and experiences
-* Giving and gracefully accepting constructive feedback
-* Accepting responsibility and apologizing to those affected by our mistakes,
-  and learning from the experience
-* Focusing on what is best not just for us as individuals, but for the
-  overall community
-
-Examples of unacceptable behavior include:
-
-* The use of sexualized language or imagery, and sexual attention or
-  advances of any kind
-* Trolling, insulting or derogatory comments, and personal or political attacks
-* Public or private harassment
-* Publishing others' private information, such as a physical or email
-  address, without their explicit permission
-* Other conduct which could reasonably be considered inappropriate in a
-  professional setting
-
-## Enforcement Responsibilities
-
-Community leaders are responsible for clarifying and enforcing our standards of
-acceptable behavior and will take appropriate and fair corrective action in
-response to any behavior that they deem inappropriate, threatening, offensive,
-or harmful.
-
-Community leaders have the right and responsibility to remove, edit, or reject
-comments, commits, code, wiki edits, issues, and other contributions that are
-not aligned to this Code of Conduct, and will communicate reasons for moderation
-decisions when appropriate.
-
-## Scope
-
-This Code of Conduct applies within all community spaces, and also applies when
-an individual is officially representing the community in public spaces.
-Examples of representing our community include using an official e-mail address,
-posting via an official social media account, or acting as an appointed
-representative at an online or offline event.
-
-## Enforcement
-
-Instances of abusive, harassing, or otherwise unacceptable behavior may be
-reported to the community leaders responsible for enforcement at
-pedrodsm1819@gmail.com.
-All complaints will be reviewed and investigated promptly and fairly.
-
-All community leaders are obligated to respect the privacy and security of the
-reporter of any incident.
-
-## Enforcement Guidelines
-
-Community leaders will follow these Community Impact Guidelines in determining
-the consequences for any action they deem in violation of this Code of Conduct:
-
-### 1. Correction
-
-**Community Impact**: Use of inappropriate language or other behavior deemed
-unprofessional or unwelcome in the community.
-
-**Consequence**: A private, written warning from community leaders, providing
-clarity around the nature of the violation and an explanation of why the
-behavior was inappropriate. A public apology may be requested.
-
-### 2. Warning
-
-**Community Impact**: A violation through a single incident or series
-of actions.
-
-**Consequence**: A warning with consequences for continued behavior. No
-interaction with the people involved, including unsolicited interaction with
-those enforcing the Code of Conduct, for a specified period of time. This
-includes avoiding interactions in community spaces as well as external channels
-like social media. Violating these terms may lead to a temporary or
-permanent ban.
-
-### 3. Temporary Ban
-
-**Community Impact**: A serious violation of community standards, including
-sustained inappropriate behavior.
-
-**Consequence**: A temporary ban from any sort of interaction or public
-communication with the community for a specified period of time. No public or
-private interaction with the people involved, including unsolicited interaction
-with those enforcing the Code of Conduct, is allowed during this period.
-Violating these terms may lead to a permanent ban.
-
-### 4. Permanent Ban
-
-**Community Impact**: Demonstrating a pattern of violation of community
-standards, including sustained inappropriate behavior,  harassment of an
-individual, or aggression toward or disparagement of classes of individuals.
-
-**Consequence**: A permanent ban from any sort of public interaction within
-the community.
-
-## Attribution
-
-This Code of Conduct is adapted from the [Contributor Covenant][homepage],
-version 2.0, available at
-https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
-
-Community Impact Guidelines were inspired by [Mozilla's code of conduct
-enforcement ladder](https://github.com/mozilla/diversity).
-
-[homepage]: https://www.contributor-covenant.org
-
-For answers to common questions about this code of conduct, see the FAQ at
-https://www.contributor-covenant.org/faq. Translations are available at
-https://www.contributor-covenant.org/translations.
diff --git a/Dockerfile b/Dockerfile
deleted file mode 100644
index 112d2e2..0000000
--- a/Dockerfile
+++ /dev/null
@@ -1,16 +0,0 @@
-FROM python:3
-ENV PYTHONUNBUFFERED=1
-ENV PIP_ROOT_USER_ACTION=ignore
-WORKDIR /code
-RUN apt-get update && apt-get install -y wkhtmltopdf
-RUN pip install --upgrade pip
-RUN pip install pandas
-RUN pip install --upgrade setuptools pip
-RUN pip install opencv-python
-RUN pip install --upgrade pip
-RUN pip install --upgrade Pillow
-RUN pip install PyPDF2
-RUN pip install pdfkit
-
-COPY 2022-2-Squad08/main.py .
-CMD ["python3", "main.py"]
\ No newline at end of file
diff --git a/README.md b/README.md
index 442c95e..f837626 100644
--- a/README.md
+++ b/README.md
@@ -1,30 +1,31 @@
-
-# 2022-2-CertiFlow
+# 2022-2-Certifik8
 
 <a name="readme-top"></a>
 
 <div align="center">
 
-[![Contributors](https://img.shields.io/github/contributors/fga-eps-mds/2022-2-Squad08.svg?style=for-the-badge&color=blueviolet)](https://github.com/fga-eps-mds/2022-2-Squad08/graphs/contributors)
-[![Issues](https://img.shields.io/github/issues/fga-eps-mds/2022-2-Squad08.svg?style=for-the-badge&color=blueviolet)](https://github.com/fga-eps-mds/2022-2-Squad08/issues)
-[![MIT License](https://img.shields.io/github/license/fga-eps-mds/2022-2-Squad08.svg?style=for-the-badge&color=blueviolet)](https://github.com/fga-eps-mds/2022-2-Squad08/blob/main/LICENSE)
+[![Contributors](https://img.shields.io/github/contributors/fga-eps-mds/2022-2-Certifik8.svg?style=for-the-badge&color=e703f7)](https://github.com/fga-eps-mds/2022-2-Certifik8/graphs/contributors)
+[![Issues](https://img.shields.io/github/issues/fga-eps-mds/2022-2-Certifik8.svg?style=for-the-badge&color=e703f7)](https://github.com/fga-eps-mds/2022-2-Certifik8/issues)
+[![MIT License](https://img.shields.io/github/license/fga-eps-mds/2022-2-Certifik8.svg?style=for-the-badge&color=e703f7)](https://github.com/fga-eps-mds/2022-2-Certifik8/blob/main/LICENSE)
 
 </div>
 
 <br />
 <div align="center">
-  <a href="https://github.com/fga-eps-mds/2022-2-Squad08">
-    <img src="">
+  <a href="https://github.com/fga-eps-mds/2022-2-Certifik8">
+    <img src="https://github.com/fga-eps-mds/2022-2-Certifik8/blob/main/docs/imagens/logo.png" width="300" height="300">
   </a>
-
-  <h3 align="center">CertiFlow</h3>
+  
+  <h3 align="center">Certifik8</h3>
 
   <p align="center">
-   Gerador Automatico de Certificados
+   Gerador Automatico de Certificados 
     <br />
-    <a href="https://github.com/fga-eps-mds/2022-2-Squad08/blob/main/SECURITY.md">Reportar Bug</a>
+    <a href="docs">Documentos</a>
+    -
+    <a href="https://github.com/fga-eps-mds/2022-2-Certifik8/blob/main/docs/SECURITY.md#pol%C3%ADtica-de-seguran%C3%A7a">Reportar Bug</a>
     -
-    <a href="https://github.com/fga-eps-mds/2022-2-Squad08/issues">Recomendar Feature</a>
+    <a href="https://github.com/fga-eps-mds/2022-2-Certifik8/issues">Recomendar Feature</a>
   </p>
 </div>
 
@@ -33,36 +34,142 @@
   <summary>Conteúdo</summary>
   <ol>
     <li>
-      <a href="#Sobre-o-projeto">Sobre o projeto</a>
+      <a href="#-sobre-o-projeto">📝 Sobre o projeto</a>
       <ul>
-        <li><a href="#Tecnologias">Tecnologias</a></li>
+        <li><a href="#-tecnologias">💻 Tecnologias</a></li>
       </ul>
     </li>
-    <li><a href="#Como-rodar">Como rodar</a></li>
-    <li><a href="#Backlog-do-produto">Backlog do produto</a></li>
-    <li><a href="#Devenvolvedores">Desenvolvedores</a></li>
+    <li><a href="#-funcionalidade">🤖 Funcionalidade</a></li>
+    <li><a href="#-requisitos">❗ Requisitos</a></li>
+    <li><a href="#-como-rodar">🛞 Como executar</a>
+	<ul>
+        <li><a href="#---usuário">👩‍🦰 Usuário</a></li>
+        </ul>
+	<ul>
+        <li><a href="#--%EF%B8%8F-desenvolvimento-local">🧙🏼‍♀️ Desenvolvimento local</a></li>
+        </ul>  
+    </li>
+    <li><a href="#-desenvolvedores">👨‍💻 Desenvolvedores</a></li>
   </ol>
 </details>
 
-## Sobre o projeto
+## 📝 Sobre o projeto
 
-CertiFlow é um projeto...
+Certifik8 é um gerador de certificados automático criado em Python. O projeto busca facilitar a geração massiva de documentos a serem emitidos após algum evento. 
 
-## Tecnologias
+## 💻 Tecnologias
 
 #### Tecnologias utilizadas neste projeto:
 
 <p align="center">
 	<a href="https://skillicons.dev">
-		<img src="https://skillicons.dev/icons?i=python,html,css,docker,git,"/>
+		<img src="https://skillicons.dev/icons?i=python,html,css"/>
 	</a>
 </p>
 
-## Como rodar
+## 🤖 Funcionalidade
+O Certifik8 necessita de duas entradas de dados, uma tabela (Excel) no formato XLSX, e dados gerais sobre o evento. Para cada conjunto de informações passadas, um documento com um modelo já preestabelecido é gerado. Os certificados em formato PDF são salvos diretamente na pasta Downloads do computador do usuário.
+
+<div align="center">
+  <a href="https://github.com/fga-eps-mds/2022-2-Certifik8/blob/main/docs/exemplo/Melissa%20Ribeiro%20Araujo.png">
+    <img src="https://github.com/fga-eps-mds/2022-2-Certifik8/blob/main/docs/exemplo/Melissa%20Ribeiro%20Araujo.png" width="413" height="291">
+  </a>
+</div>
+
+## ❗ Requisitos
+O Certifik8 só funciona em sistemas operacionais Linux. 
+
+Testado no:
+- Linux Mint 21
+- Ubuntu 22.04.01
+
+<div align="center">
+
+![LinuxMint](https://img.shields.io/badge/Linux_Mint-87CF3E?style=for-the-badge&logo=linux-mint&logoColor=black)
+
+![Ubuntu](https://img.shields.io/static/v1?style=for-the-badge&message=Ubuntu&color=E95420&logo=Ubuntu&logoColor=FFFFFF&label=)
+
+</div>
+
+
+**Para conseguir executá-lo, o usuário precisa instalar:**
+  - **Python3 e Pip**
+    ```
+    sudo apt install python3 && sudo apt install python3-pip
+    ```
+
+  - **Instalar a ferramenta wkhtmltopdf**
+    ```
+    sudo apt install wkhtmltopdf
+    ```
+
+## 🛞 Como executar/rodar
+### **- 👩‍🦰 Usuário**
+1. **Instalando o Certifik8:**
+```
+pip install -i https://test.pypi.org/simple/ Certifik8==0.0.2
+```
+
+2. **Digite o comando para obter o endereço da biblioteca:**
+ ```
+ pip show Certifik8 
+ ```
+<div align="center">
+<img src="https://github.com/fga-eps-mds/2022-2-Certifik8/blob/main/docs/imagens/pip-show.png" width="500" height="300">
+
+Copie o endereço após a "Location", marcado de vermelho na imagem.
+</div>
+
+3. **Executando a aplicação:**
+ ```
+ python3 {endereço_biblioteca}/Certifik8/main.py
+ ```
+<div align="center">
+<img src="https://github.com/fga-eps-mds/2022-2-Certifik8/blob/main/docs/imagens/path-image.png" width="762" height="95">
+
+Substitua a chave {endereço_biblioteca} pelo endereço copiado no passo 2.
+</div>
+
+4. **Insira os dados conforme pedido:**
+
+* O endereço da tabela deve ser absoluto.
+
+* Estrutura da tabela Excel ([Exemplo](docs/exemplo/exemplo.xlsx)): 
+  - Obs: a tabela deve seguir essa estrutura obrigatoriamente.
+    | 1  | Nome | cpf | Função | Frequência |
+    |---|------|-----|--------|------------|
+    | 2 | Samuel Barbosa Alves | 729.334.326-41 | PARTICIPANTE | 100 |
+    | 3 | Melissa Ribeiro Araujo | 201.544.482-30 | MONITOR | 97 |
+    | 4 | Gabrielly Rodrigues Castro | 451.016.912-40 | PARTICIPANTE | 80 |
+    | ... | ... | ... | ... | ... |
+  
+
+<div align="center">
+
+*Demonstração de funcionalidade.*
+
+<img src="https://github.com/fga-eps-mds/2022-2-Certifik8/blob/main/docs/imagens/demonstracao.png" width="500" height="300">
+
+</div>
+
+### **- 🧙🏼‍♀️ Desenvolvimento local**
+1. **Clone o repositório**
+```
+git clone https://github.com/fga-eps-mds/2022-2-Certifik8.git
+```
+
+2. **Rode os comandos:**
+
+```
+sudo docker build -t squad08
+```
+
+```
+docker run --name cont_squad08 -it squad08
+```
 
-## Backlog do produto
 
-## Desenvolvedores
+## 👨‍💻 Desenvolvedores
 
 <center>
 <table style="margin-left: auto; margin-right: auto;">
diff --git a/docs/CODE_OF_CONDUCT.md b/docs/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..aba90bd
--- /dev/null
+++ b/docs/CODE_OF_CONDUCT.md
@@ -0,0 +1,87 @@
+
+# Código de Conduta de Colaboração
+
+## Nossa promessa
+
+Como pessoas participantes, colaboradoras e líderes, nós nos comprometemos a fazer com que a participação em nossa comunidade seja uma experiência livre de assédio para todas as pessoas, independentemente de idade, tamanho do corpo, deficiência aparente ou não aparente, etnia, características sexuais, identidade ou expressão de gênero, nível de experiência, educação, situação sócio-econômica, nacionalidade, aparência pessoal, raça, religião ou identidade e orientação sexuais.
+
+Comprometemo-nos a agir e interagir de maneiras que contribuam para uma comunidade aberta, acolhedora, diversificada, inclusiva e saudável.
+
+## Nossos padrões
+
+Exemplos de comportamentos que contribuem para criar um ambiente positivo para a nossa comunidade incluem:
+
+* Demonstrar empatia e bondade com as outras pessoas
+* Respeitar opiniões, pontos de vista e experiências contrárias
+* Dar e receber feedbacks construtivos de maneira respeitosa
+* Assumir responsabilidade, pedir desculpas às pessoas afetadas por nossos erros e aprender com a experiência
+* Focar no que é melhor não só para nós individualmente, mas para a comunidade em geral
+
+Exemplos de comportamentos inaceitáveis incluem:
+
+* Uso de linguagem ou imagens sexualizadas, bem como o assédio sexual ou de qualquer natureza
+* Comentários insultuosos/depreciativos e ataques pessoais ou políticos (*Trolling*)
+* Assédio público ou privado
+* Publicar informações particulares de outras pessoas, como um endereço de e-mail ou endereço físico, sem a permissão explícita delas
+* Outras condutas que são normalmente consideradas inapropriadas em um ambiente profissional
+
+## Aplicação das nossas responsabilidades
+
+A liderança da comunidade é responsável por esclarecer e aplicar nossos padrões de comportamento aceitáveis e tomará ações corretivas apropriadas e justas em resposta a qualquer comportamento que considerar impróprio, ameaçador, ofensivo ou problemático.
+
+A liderança da comunidade tem o direito e a responsabilidade de remover, editar ou rejeitar comentários, commits, códigos, edições na wiki, erros e outras contribuições que não estão alinhadas com este Código de Conduta e irá comunicar as razões por trás das decisões da moderação quando for apropriado.
+
+## Escopo
+
+Este Código de Conduta se aplica dentro de todos os espaços da comunidade e também se aplica quando uma pessoa estiver representando oficialmente a comunidade em espaços públicos.
+Exemplos de representação da nossa comunidade incluem usar um endereço de e-mail oficial, postar em contas oficiais de mídias sociais ou atuar como uma pessoa indicada como representante em um evento online ou offline.
+
+## Aplicação
+
+Ocorrências de comportamentos abusivos, de assédio ou que sejam inaceitáveis por qualquer outro motivo poderão ser reportadas para a liderança da comunidade, responsável pela aplicação, via contato pedrodsm1819@gmail.com.
+
+Todas as reclamações serão revisadas e investigadas imediatamente e de maneira justa.
+
+A liderança da comunidade tem a obrigação de respeitar a privacidade e a segurança de quem reportar qualquer incidente.
+
+## Diretrizes de aplicação
+
+A liderança da comunidade seguirá estas Diretrizes de Impacto na Comunidade para determinar as consequências de qualquer ação que considerar violadora deste Código de Conduta:
+
+### 1. Ação Corretiva
+
+**Impacto na comunidade**: Uso de linguagem imprópria ou outro comportamento considerado anti-profissional ou repudiado pela comunidade.
+
+**Consequência**: Aviso escrito e privado da liderança da comunidade, esclarecendo a natureza da violação e com a explicação do motivo pelo qual o comportamento era impróprio. Um pedido de desculpas público poderá ser solicitado.
+
+### 2. Advertência
+
+**Impacto na comunidade**: Violação por meio de um incidente único ou atitudes repetidas.
+
+**Consequência**: Advertência com consequências para comportamento repetido. Não poderá haver interações com as pessoas envolvidas, incluindo interações não solicitadas com as pessoas que estiverem aplicando o Código de Conduta, por um período determinado. Isto inclui evitar interações em espaços da comunidade, bem como canais externos como as mídias sociais. A violação destes termos pode levar a um banimento temporário ou permanente.
+
+### 3. Banimento Temporário
+
+**Impacto na comunidade**: Violação grave dos padrões da comunidade, incluindo a persistência do comportamento impróprio.
+
+**Consequência**: Banimento temporário de qualquer tipo de interação ou comunicação pública com a comunidade por um determinado período. Estarão proibidas as interações públicas ou privadas com as pessoas envolvidas, incluindo interações não solicitadas com as pessoas que estiverem aplicando o Código de Conduta. A violação destes termos pode resultar em um banimento permanente.
+
+### 4. Banimento Permanente
+
+**Impacto na comunidade**: Demonstrar um padrão na violação das normas da comunidade, incluindo a persistência do comportamento impróprio, assédio a uma pessoa ou agressão ou depreciação a classes de pessoas.
+
+**Consequência**: Banimento permanente de qualquer tipo de interação pública dentro da comunidade.
+
+## Atribuição
+
+Este Código de Conduta é adaptado do [Contributor Covenant][homepage],
+versão 2.0, disponível em
+https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
+
+As Diretrizes de Impacto na Comunidade foram inspiradas pela [Aplicação do código de conduta Mozilla](https://github.com/mozilla/diversity).
+
+[homepage]: https://www.contributor-covenant.org
+
+Para obter respostas a perguntas comuns sobre este código de conduta, veja a página de Perguntas Frequentes (*FAQ*) em
+https://www.contributor-covenant.org/faq. Traduções estão disponíveis em
+https://www.contributor-covenant.org/translations.
diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md
index 60dc774..4903ee5 100644
--- a/docs/CONTRIBUTING.md
+++ b/docs/CONTRIBUTING.md
@@ -11,7 +11,7 @@ Antes de começar a contribuir para o projeto, crie uma issue para descrever sua
 ### Branchs
 
 #### Crie uma nova branch
-Para criar uma nova branch, digite o comando 'git checkout -o nome_branch' no terminal.
+Para criar uma nova branch, digite o comando 'git checkout -b nome_branch' no terminal.
 
 #### Troque de branch
 Para mudar para uma branch existente, digite o comando 'git checkout nome_branch' no terminal.
diff --git a/SECURITY.md b/docs/SECURITY.md
similarity index 91%
rename from SECURITY.md
rename to docs/SECURITY.md
index 8eef922..7079bff 100644
--- a/SECURITY.md
+++ b/docs/SECURITY.md
@@ -7,7 +7,7 @@
 
 ## Relatando uma Vulnerabilidade
 
-Se houver alguma vulnerabilidade no repositório **2022-2-Squad08**, não hesite em _relatá-la_.
+Se houver alguma vulnerabilidade no repositório **2022-2-Certifik8**, não hesite em _relatá-la_.
 
 - Use um destes e-mails:
 	 - pedro.sampaio.dias.rocha@gmail.com
diff --git a/docs/User Story Map.png b/docs/User Story Map.png
new file mode 100644
index 0000000..41b1c8d
Binary files /dev/null and b/docs/User Story Map.png differ
diff --git a/docs/exemplo/Melissa Ribeiro Araujo.png b/docs/exemplo/Melissa Ribeiro Araujo.png
new file mode 100644
index 0000000..3972466
Binary files /dev/null and b/docs/exemplo/Melissa Ribeiro Araujo.png differ
diff --git a/docs/exemplo/exemplo-certificados.zip b/docs/exemplo/exemplo-certificados.zip
new file mode 100644
index 0000000..8c4f097
Binary files /dev/null and b/docs/exemplo/exemplo-certificados.zip differ
diff --git a/docs/exemplo/exemplo1.xlsx b/docs/exemplo/exemplo1.xlsx
new file mode 100644
index 0000000..a1d25bf
Binary files /dev/null and b/docs/exemplo/exemplo1.xlsx differ
diff --git a/docs/exemplo/exemplo2.xlsx b/docs/exemplo/exemplo2.xlsx
new file mode 100644
index 0000000..816ce25
Binary files /dev/null and b/docs/exemplo/exemplo2.xlsx differ
diff --git a/docs/imagens/demonstracao.png b/docs/imagens/demonstracao.png
new file mode 100644
index 0000000..0f4d1ee
Binary files /dev/null and b/docs/imagens/demonstracao.png differ
diff --git a/docs/imagens/logo.png b/docs/imagens/logo.png
new file mode 100644
index 0000000..abe9eca
Binary files /dev/null and b/docs/imagens/logo.png differ
diff --git a/docs/imagens/path-image.png b/docs/imagens/path-image.png
new file mode 100644
index 0000000..45dc1d8
Binary files /dev/null and b/docs/imagens/path-image.png differ
diff --git a/docs/imagens/pip-show.png b/docs/imagens/pip-show.png
new file mode 100644
index 0000000..ed6fd14
Binary files /dev/null and b/docs/imagens/pip-show.png differ
diff --git a/docs/prototipo.png b/docs/prototipo.png
new file mode 100644
index 0000000..ef65082
Binary files /dev/null and b/docs/prototipo.png differ
diff --git a/pyproject.toml b/pyproject.toml
index b5a3c46..c4d99c6 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,34 @@
+[tool.poetry]
+name = "certifik8"
+version = "0.2.1"
+description = "Certifik8 é um gerador de certificados automático criado em Python. O projeto busca facilitar a geração massiva de documentos a serem emitidos após algum evento."
+authors = [
+    "Victorio <victorio.lazaro15@gmail.com>",
+    "Pedro Henrique <pedrodsm1819@gmail.com>",
+    "Pedro Sampaio <pedro.sampaio.dias.rocha@gmail.com>", 
+    "Leandro <leanddrosouzasilva@gmail.com>", 
+    "Daniel <sousadanielsb@gmail.com>", 
+    "Geovane <galefreitas@gmail.com>"]
+license = "MIT"
+readme = "README.md"
+packages = [{include = "src/Certifik8"}]
+repository = "https://github.com/fga-eps-mds/Certifik8"
+
+[tool.poetry.dependencies]
+python = "^3.10"
+pandas = "1.5.2"
+setuptools = "65.6.3"
+Pillow = "9.3.0"
+PyPDF2 = "2.11.1"
+pdfkit = "1.0.0"
+pendulum = "^2.1.2"
+beautifulsoup4 = "^4.11.1"
+openpyxl = "^3.0.10"
+
+
 [build-system]
-requires = [
-    "setuptools>=42",
-    "wheel"
-]
-build-backend = "setuptools.build_meta"
\ No newline at end of file
+requires = ["poetry-core"]
+build-backend = "poetry.core.masonry.api"
+
+[tool.poetry.scripts]
+certifik8 = 'src.Certifik8.main:run'
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
deleted file mode 100644
index 87f3513..0000000
--- a/requirements.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-pandas==1.5.2
-setuptools==65.6.3
-opencv-python==4.6.0
-Pillow==9.3.0
-PyPDF==2.11.1
\ No newline at end of file
diff --git a/setup.cfg b/setup.cfg
deleted file mode 100644
index 9303fa6..0000000
--- a/setup.cfg
+++ /dev/null
@@ -1,19 +0,0 @@
-[metadata]
-name = certifik8
-version = 0.0.1
-description = A small example package
-long_description = file: README.md
-long_description_content_type = text/markdown
-classifiers =
-    Programming Language :: Python :: 3
-    License :: OSI Approved :: MIT License
-    Operating System :: OS Independent
-
-[options]
-package_dir =
-    = src
-packages = find:
-python_requires = >=3.6
-
-[options.packages.find]
-where = src
\ No newline at end of file
diff --git a/src/Certifik8/__init__.py b/src/Certifik8/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/src/Certifik8/certificado.py b/src/Certifik8/certificado.py
new file mode 100644
index 0000000..181b184
--- /dev/null
+++ b/src/Certifik8/certificado.py
@@ -0,0 +1,145 @@
+from src.Certifik8.html2pdf import Html2Pdf
+import pandas as pd
+import os
+from src.Certifik8.data_emissao import DataEmissao
+from bs4 import BeautifulSoup
+
+html_doc = """
+<!DOCTYPE html>
+<html lang="pt-br">
+<head>
+    <meta charset="UTF-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width,initial-scale=1.0">
+    <title>Template</title>
+    <style>
+        @import url(
+        'https://fonts.googleapis.com/css2?family=Roboto&display=swap');
+        main{
+            position: relative;
+            width: 1096px;
+            height: 748px;
+            font-family: 'Roboto', sans-serif;
+            background-image: url(
+            https://cdn.discordapp.com/attachments/1034883038586351647/1049011662566465546/template.png);
+        }
+        #texto_principal{
+            position: absolute;
+            top: 250px;
+            left: 148px;
+            width: 800px;
+            text-align: justify;
+            font-size: 18px;
+            font-weight: 700;
+        }
+        .nome_participante,
+        .cpf_participante,
+        .nome_evento,
+        .nome_prof,
+        .nome_dep,
+        .cargo_participante,
+        .frequencia_participante{
+            text-transform: uppercase;
+        }
+        #local_data{
+            position: absolute;
+            top: 400px;
+            right: 148px;
+            font-size: 22px;
+            font-weight: 700;
+        }
+        #informacoes_adicionais{
+            position: absolute;
+            top: 470px;
+            width: 1096px;
+        }
+        .texto_adicional{
+            margin: 0;
+            font-size: 22px;
+            text-align: center;
+            font-weight: 700;
+        }
+        p.nao_negrito{
+            font-size: 20px;
+            font-weight: 400;
+        }
+    </style>
+</head>
+<body>
+    <main>
+        <p id="texto_principal">Certificamos que, <span class="nome_participante"></span>, CPF
+            <span class="cpf_participante"></span>, participou do
+            evento de extensão <span class="nome_evento"></span>, com carga horária de
+            <span class="carga_hor"></span>
+            hora(s), coordenado pelo(a) Professor(a) <span class="nome_prof"></span>, promovido
+            pelo(a) <span class="nome_dep"></span>, na função de
+            <span class="cargo_participante"></span>,
+            com frequência <span class="frequencia_participante"></span>%.
+            A atividade foi realizada no período de <span class="data_inicial"></span> a
+            <span class="data_final">***</span>.
+        </p>
+        <p id="local_data">Brasília, <span class="data_emissao"></span></p>
+        <div id="informacoes_adicionais">
+            <p class="texto_adicional">OLGAMIR AMANCIA FERREIRA</p>
+            <p class="texto_adicional nao_negrito">Decana de Extensão</p>
+        </div>
+    </main>
+</body>
+</html>
+"""
+
+
+class Certificados:
+    DataEmissao = DataEmissao()
+
+    def xlsx_content(self, path):
+        data_frame = pd.read_excel(path)
+        return data_frame
+
+    def gerarCertificados(
+        self,
+        filepath,
+    ):
+        try:
+            df = self.xlsx_content(filepath)
+        except Exception as error:
+            print(f'An error occurred: {error}')
+            return
+
+        def separarTabela(self, df):
+            df_info = df[["Informações"]].copy()
+            df.drop(columns=["Informações"], inplace=True)
+            return df_info
+
+        df_info = separarTabela(self, df)
+
+        data_emissao = self.DataEmissao.getDataPorExtenso()
+        for i in df.index:
+            soup = BeautifulSoup(html_doc, "html.parser")
+            soup.find("span", class_="nome_participante").replace_with(df["Nome"][i])
+            soup.find("span", class_="cpf_participante").replace_with(df["CPF"][i])
+            soup.find("span", class_="nome_evento").replace_with(df_info.iloc[0, 0])
+            soup.find("span", class_="carga_hor").replace_with(df_info.iloc[1, 0])
+            soup.find("span", class_="nome_prof").replace_with(df_info.iloc[2, 0])
+            soup.find("span", class_="nome_dep").replace_with(df_info.iloc[3, 0])
+            soup.find("span", class_="cargo_participante").replace_with(df["Função"][i])
+            soup.find("span", class_="frequencia_participante").replace_with(
+                str(df["Frequência"][i])
+            )
+            soup.find("span", class_="data_inicial").replace_with(df_info.iloc[4, 0])
+            soup.find("span", class_="data_final").replace_with(df_info.iloc[5, 0])
+            soup.find("span", class_="data_emissao").replace_with(data_emissao)
+            with open(df["Nome"][i] + ".html", "w") as file:
+                file.writelines(soup.prettify())
+
+            foldername = filepath.split("/")
+            foldername = foldername[-1]
+            foldername = foldername.split(".")[0]
+
+            Html2Pdfs = Html2Pdf(html=df["Nome"][i] + ".html")
+            Html2Pdfs.convert(df["Nome"][i], foldername)
+            os.remove(df["Nome"][i] + ".html")
+
+
+if __name__ == "__main__":
+    pass
diff --git a/src/Certifik8/data_emissao.py b/src/Certifik8/data_emissao.py
new file mode 100644
index 0000000..32c8998
--- /dev/null
+++ b/src/Certifik8/data_emissao.py
@@ -0,0 +1,31 @@
+from datetime import date
+
+
+class DataEmissao:
+    meses = (
+        "Janeiro",
+        "Fevereiro",
+        "Março",
+        "Abril",
+        "Mail",
+        "Junho",
+        "Julho",
+        "Agosto",
+        "Setembro",
+        "Outubro",
+        "Novembro",
+        "Dezembro",
+    )
+
+    def getDataPorExtenso(self) -> str:
+        dia = date.today().strftime("%d")
+        mes = int(date.today().strftime("%m")) - 1
+        ano = date.today().strftime("%Y")
+        return f"{dia} de {self.meses[mes]} de {ano}"
+
+    def printDataPorExtensoDebuger(self):
+        print(self.getDataPorExtenso())
+
+
+if __name__ == "__main__":
+    pass
diff --git a/src/Certifik8/html2pdf.py b/src/Certifik8/html2pdf.py
new file mode 100644
index 0000000..cc3e9ba
--- /dev/null
+++ b/src/Certifik8/html2pdf.py
@@ -0,0 +1,31 @@
+import pdfkit
+import os
+
+
+class Html2Pdf:
+    options = {
+        "page-size": "A5",
+        "orientation": "landscape",
+        "encoding": "UTF-8",
+    }
+
+    def __init__(self, html="template/template.html"):
+        self.html2pdf = html
+
+    def convert(self, output_name, foldername) -> None:
+        download_folder = self.get_download_path()
+
+        new_path = download_folder + f"{foldername}"
+        if not os.path.exists(new_path):
+            os.makedirs(new_path)
+
+        pdfkit.from_file(
+            self.html2pdf, new_path + f"/{output_name}.pdf", options=self.options
+        )
+
+    def get_download_path(self):
+        return os.path.join(os.path.expanduser("~"), "Downloads/")
+
+
+if __name__ == "__main__":
+    pass
diff --git a/src/Certifik8/main.py b/src/Certifik8/main.py
new file mode 100644
index 0000000..1f6efed
--- /dev/null
+++ b/src/Certifik8/main.py
@@ -0,0 +1,21 @@
+from src.Certifik8.certificado import Certificados
+from tkinter import filedialog
+import os
+
+
+def run():
+    certificados = Certificados()
+
+    print(
+        "Bem-vindo ao Certifik8, gerador de certificados da Semana Universitária da UnB"
+    )
+
+    paths = filedialog.askopenfilenames()
+
+    for path in paths:
+        if os.path.exists(path) and os.path.splitext(path)[1] == ".xlsx":
+            certificados.gerarCertificados(
+                path,
+            )
+        else:
+            print("Tabela não encontrada")


Test patch:
diff --git a/2022-2-Squad08/teste.xlsx b/2022-2-Squad08/teste.xlsx
deleted file mode 100644
index dd4e400..0000000
Binary files a/2022-2-Squad08/teste.xlsx and /dev/null differ