Iniciando em .NET Core – 03

Olá! Vamos para mais post da série sobre .NET Core!

Neste post vamos acessar a nossa biblioteca de classes criada no artigo anterior, adicionar algumas classes e fazer a chamada delas em nosso console.

Abra a pasta DotNetCoreStart no Visual Studio Code e expanda o projeto DotNetCoreStart.Domain

Vamos que possui um arquivo csproj, onde ficam armazenadas as informações do projeto, e também uma class1.cs, que é uma classe em c#.

Antes de prosseguir, instale a extensão C# Extensions, que habilita a opção de criar diretamente classes em C# clicando com o botão direito do mouse em cima do projeto ou pasta selecionada.

Vamos então deletar a class1.cs e criar uma nova pasta, chamada Entities. Em seguida, crie uma nova classe C# na pasta Entities, com o nome de Customer.cs

Podemos ver que a nova classe criada já possui o namespace e a base. Isso acontece devido a extensão instalada anteriormente.

o “0 references” em cima de public class Customer serve para ter referência de onde a classe foi instanciada. Isto é graças ao plugin C# instalado no nosso primeiro post.

Vamos agora adicionar as propriedades, e criar um construtor para que toda vez que instanciar um novo Customer, adicione automaticamente o Id dele.

Nossa classe ficará assim:

using System;
namespace DotNetCoreStart.Domain.Entities
{
public class Customer
{
public Guid Id { get; private set; }
public string Name { get; set; }

public Customer()
{
Id = Guid.NewGuid();
}
}
}

Perceba em cima de Id apareceu “1 reference”, isso se deve ao fato de termos adicionado no construtor o Id.

Vamos agora ao nosso projeto console, e adicionar um novo customer.

Primeiramente, adicione a referência a nossa Domain no inicio do código

using DotNetCoreStart.Domain.Entities;

Em seguida, vamos adicionar um novo Customer, e adicionar um ReadLine, para que possamos definir um nome para o mesmo. Depois, vamos exibir o Id gerado para ele e o nome.

static void Main(string[] args)
{
Customer customer = new Customer();
System.Console.WriteLine("Digite o nome do cliente: ");
customer.Name = System.Console.ReadLine();

System.Console.WriteLine($"O cliente {customer.Name} possui o Id {customer.Id}");
}

Ao colocar um sinal de $ antes da frase a ser exibida, possibilita exibirmos os valores presentes nas classes, desde que eles estejam entre { }. Isso seria o equivalente ao string.Format anterior.

Vamos então rodar o comando dotnet build na raiz do nosso projeto. Em seguida acesse a pasta DotNetCoreStart.Console e execute o comando dotnet run.

 

Se tudo der certo, sua tela deverá ser semelhante a esta:

 

Abraços e até a próxima!

Compartilhar:

Iniciando em .NET Core – 02

Olá! Vamos para o nosso segundo post da série sobre .NET Core!

Neste post vamos adicionar uma biblioteca de classes e referenciar em nosso console. Para isto, vamos criar primeiramente uma solution e juntar os projetos nesta solution.

Abra a pasta DotNetCoreStart com o seu prompt de comando e digite o seguinte comando:

dotnet new sln

Com isto, ele vai criar um novo de solução chamado DotNetCoreStart.sln

Vamos dar uma olhada neste arquivo:

Ele possui informações de configurações de plataformas, versão do visual studio, entre outras.

Agora, vamos referenciar o nosso projeto DotNetCoreStart.Console na nossa Solução. Para isto, digite:

dotnet sln DotNetCoreStart.sln add DotNetCoreStart.Console\DotNEtCoreStart.Console.csproj

Com isto, nosso arquivo de Solução vai ter algumas alterações, como podemos ver:

Veja que foi adicionada uma linha chamada Project, que referencia nosso Console.

Com esta solução, agora podemos rodar um dotnet build na pasta raiz do projeto que ele vai consultar todos os projetos referenciados na solução, evitando assim que tenha que acessar cada pasta e rodar um build separado.

Vamos agora criar um novo projeto, chamado DotNetCoreStart.Domain

dotnet new classlib --name DotNetCoreStart.Domain

Em seguida, já vamos referenciar este projeto na solution

dotnet sln DotNetCoreStart.sln add DotNetCoreStart.Domain\DotNEtCoreStart.Domain.csproj

Vamos também rodar um novo comando, que será referenciar a nossa ClassLib no nosso Console. Rode o seguinte comando:

dotnet add DotNetCoreStart.Console\DotNetCoreStart.Console.csproj reference DotNetCoreStart.Domain\DotNetCoreStart.Domain.csproj

Feito isto, vamos abrir no Visual Studio Code o nosso projeto DotNetCoreStart.Console e verificar o arquivo DotNetCoreStart.Console.csproj

Veja que ele adicionou um ItemGroup, com um project reference que inclui a nossa ClassLib no projeto.

Vamos agora rodar um dotnet restore na raiz do projeto para restaurar os pacotes

Obs: Você pode abrir uma tela do terminal no próprio VS Code indo em “View”, depois “Integrated Terminal”, ou apenas apertando (no meu caso) CTRL + ‘.Feito isso, vai abrir uma tela do Power Shell no seu VSCode

Executando o comando dotnet restore na raiz, pode perceber que ele vai buscar os dois projetos em suas respectivas pastas, isto graças ao solution file adicionado e as referências realizadas nele.

Bom, assim finalizamos nosso segundo post.

No próximo, vamos adicionar classes em nossa classlib e chamá-las em nosso Console Project.

Até a próxima!

Compartilhar:

Iniciando em .Net Core

Olá!

Vamos iniciar aqui uma série de posts sobre .Net Core, o framework Open Source da Microsoft.

Iniciei meus estudos nele recentemente e gostaria de compartilhar o conhecimento com todos para que assim cada vez mais a linguagem C# e o framework .Net Core seja aceito pela comunidade e assim dissipado!

Os exemplos utilizados poderão ser baixados no meu GitHub porém, recomendo que você siga e digite todo o código, para que vá fixando cada vez mais.

Irei realizar o desenvolvimento intercalando em uma máquina com Mac OS e outra com Windows, para mostrar que o mesmo código pode ser utilizado em ambas as plataformas.

Obs: Eu não vou aqui fazer uma explicação sobre o que é o .Net Core, mas vou deixar alguns links para referência:

InfoQ – Conhecendo o .Net Core

MSDN – O .NET Core – .NET Transforma-se em uma Plataforma Cruzada com o .NET Core

Umbler – ASP.Net CORE

Eduardo Pires – Introdução ao ASP.Net Core 1.0

Ferramentas utilizadas:

Visual Studio Code (ou o da sua preferência. Nos exemplos utilizarei o Code.)

– Plugin para C# Visual Studio Code

.Net Core Versão Atual deste post: 1.1 (Siga o passo a passo de acordo com o seu sistema operacional)

 

Iniciando o Repositório

 

Primeiramente, vamos criar uma pasta chamada DotNetCoreStart, onde vamos trabalhar durante todo o projeto.

 

Em seguida, vamos iniciar um git, para controle de versão.

Vamos criar um arquivo .gitignore, para que não suba pastas como builds, bin, entre outras exclusivas do projeto na sua máquina para o git. Para isto, vou utilizar o default fornecido pela Microsoft que peguei no Visual Studio For Mac. Caso você queira utilizá-lo, clique aqui.

Agora, caso você queira subir o seu projeto em algum servidor Git, basta seguir os procedimentos do servidor desejado. Caso não queira, pode realizar os comits na sua máquina mesmo para controle.

 

Iniciando um Console Project

 

Vamos iniciar nosso projeto com uma Console. Para isto, digite o seguinte comando dentro da pasta DotNetCoreStart:

dotnet new console --name DotNetCoreStart.Console

Com este comando, ele vai criar uma Console Application (console) dentro da pasta DotNetCoreStart.Console (parâmetro –name).

Caso você execute o seguinte comando, dentro da pasta DotNetCoreStart:

dotnet new console

Ele vai criar os mesmos arquivos que estão na pasta DotNetCoreStart.Console, mas dentro da pasta DotNetCoreStart, e seguindo a nomenclatura DotNetCoreStart. Ou seja, você tem 2 opções:

1 – Criar uma sub pasta dentro da pasta raiz e dentro dela rodar o comando new;

2 – Na pasta raiz, rodar o comando new passando o parâmetro –name, que vai criar a pasta com o projeto dentro.

Obs: Caso tenha rodado o comando dotnet new console dentro da pasta DotNetCoreStart, delete os arquivos DotNetCoreStart.csproj e Program.cs.

 

Hello World

Dentro da pasta DotNetCoreStart, digite o comando code . para abrir o Visual Studio Code.

Com o Visual Studio Code aberto, vamos primeiramente instalar a extensão para c# para visual studio code. Para isto, clique no último ícone da barra lateral esquerda.

Em Search Extensions in Marketplace, procure por C# e instale a seguinte extensão

Após instalado, reinicie o Visual Studio code.

Você deve ter reparado que apareceu uma mensagem informando para fazer o “restore” de alguns componentes. Isto se deve a ter que restaurar os pacotes necessários para trabalhar neste projeto.

Para tal, digite o seguinte comando dentro da pasta DotNetCoreStart.Console:

dotnet restore

Isto vai restaurar os pacotes necessários para a execução do nosso projeto.

Em seguida, execute o comando:

dotnet run

Quando executei este comando, deu o seguinte erro:

Para resolver, abra o arquivo Program.cs e adicione a palavra System. antes de Console.WriteLine, na linha 9:

Feito isto, vamos rodar um novo dotnet run:

 

Com isto, iniciamos um Console Project em .NET Core. No próximo artigo, vamos adicionar uma classlib e realizar alguns testes.

Pretendo com a série de posts passar por todos os templates, criando uma WebApi com acesso a dados e consumindo a mesma em um projeto Angular.

Até a próxima!

Compartilhar:

Bora para o 2o. Stone Tech Saturday?

Fala pessoal!

Dia 01/07 vai acontecer em São Paulo o 2 Stone Tech Saturday com temas sobre Xamarin, Qualidade, SQL Server 2017, Bots, Docker/Linux.

O evento será realizado na Stone Pagamentos, localizada na  Rua Fidêncio Ramos, 308 – 10º Andar, São Paulo, e é idealizado pelo grupo .NET São Paulo.

Maiores informações e cadastro no link: https://www.meetup.com/dotnet-Sao-Paulo/events/240723522/?_locale=pt-BR

Grande abraço!

Compartilhar:

Transformando Meses de numeral em texto no Pentaho

Olá!

A partir de hoje, vou fazer umas postagens sobre uma ferramenta que tenho trabalhado muito por estes dias, o Pentaho Data Integration.

Uma dúvida que surgiu estes dias seria como transformar meses de numeral para texto. Exemplo: 01 = Janeiro, 02 = Fevereiro, e por aí vai.

Um meio de fazer isso seria pegando a data, extraindo o mês e realizar um string replace.

Segue o processo:

1 – Crie uma nova transformação e insira 4 steps:

  • Data Grid
  • Calculator
  • Replace in string
  • Text file output

Este é o modelo como vai ficar nossa transformação


2 – No step Data Grid, vamos criar um campo Data, tipo “Date”, format “dd/MM/yyyy”


3 – Vamos preencher o campo com alguns valores para teste


4 – No step Calculator, faça o seguinte processo, se atentando em colocar no campo Conversion Mask o valor 00, para o campo mes_string. Isto vai definir que os valores mês fiquem 01, ao invés de 1


5 – Na step Replace in string, vamos colocar os valores referente aos meses.


6 – Na step Text file output, informe os campos que vão para o arquivo de texto


Pronto! Salve e execute a transformação.

Caso queira baixar a transformação, segue o link do github:

https://github.com/tir4y/exemplo_blog/blob/master/PDI/pegar_mes.ktr

Grande abraço e até a próxima!

Compartilhar:

A Vida é uma caixinha de surpresas…

A vida é mesmo uma caixinha de surpresas e tem dias que vem para nos surpreender…
Este dia foi 27/10/2015.
Você acorda todo animado para para ir trabalhar, acorda até antes do despertador (o que para mim é uma batalha hehe)!

Fui trabalhar, cheguei, liguei meu computador, ele pediu para scanear o disco, deixei!
Depois de umas 2h de trabalho, resolvi ligar para minha mãe para saber se ela tinha conseguido configurar o facebook no tablet que tinha ganhado no dia anterior.
Ela me atendeu, falou que estava no hospital com meu pai, que tinha sofrido um derrame.

Corpo gelou! Veio mil coisas na cabeça…

Ao longo da manhã, fui ligando, e fui sendo informado que ele ia ser transferido para a Santa Casa de Bom DEspacho, aguardando para fazer a tumografia.

Em uma dessas ligações, consigo trocar umas palavras com ele:
– E aí veião, que fria heim?

Em meio a sua dificuldade de falar, devido ao derrame, ele me manda:

– Fria nada, gelada! Vai dar tudo certo.

A única palavra que eu conseguia repetir para ele era:
– Você vai sair dessa Emoticon smile

Nisso foi passando as horas, e nada de fazerem o exame ou tomarem as providências. As vezes penso porque a Santa Casa não tomou iniciativa, vendo o estado grave do paciente, que estava em um quarto com mais 4 e paralisado totalmente do lado esquerdo.

Nisto, por volta das 16h, eu estava trabalhando e começo a ter uma tremedeira… Passado uns 10 minutos eu recebo a triste notícia que o Sr. Jarbas, aquele com quem tive altas desavenças e momentos de alegria; com quem eu muitas vezes passava horas ouvindo falar, seu eu dar nenhum pio, infelizmente faleceu.

Na hora, deu um choque. Eu não conseguia pensar. Não saia um choro. A unica coisa que eu conseguia era falar com minha mãe: Fique calma, ele está bem.

Pode ser estranho, mas desde o momento em que eu entrei naquele avião com destino a confins, todo momento em que eu parava, aparecia uma pessoa que simplesmente puxava papo comigo, pessoas estas que eu nunca tinha visto na vida e uma que eu tinha visto no festival em que participei, mas sempre estas pessoas conversavam tão tranquilamente comigo, que eu simplesmente não conseguia ficar triste.

Desse jeito eu vim para Bom Despacho, cumprimentei todo mundo com um sorriso no rosto e agradecendo por tudo que fez por ele, por este que sem dúvida nenhuma, soube viver a vida do modo dele, fazendo bagunças, deixando a casa desarrumada, trazendo coisas da rua, falando mais que maritaca (as vezes ainda falava “eu sei que já te contei, mas vou contar novamente”), mas feliz.

Ele estava feliz. Na minha visão ele estava apenas ali, dormindo, igual eu o encontrava muitas as vezes.

Hoje corre lágrimas do meu rosto, mas não de tristeza e sim de alegria, pois este foi um homem que venceu uma doença que o acompanhou por grande parte da vida e que agora, se assim permitir, está do lado de sua mãe e seu pai, o qual ele tanto valorizava e se orgulhava em dizer que tinha cuidado dos dois.

Obrigado pai, por você ter feito o que pode para que eu me tornasse o homem que sou hoje.

Te amo muito, e desculpa qualquer coisa.

Lembrancinha-Jarbas

(Lembrancinha entregue na missa de 7º dia)

Compartilhar:

Utilizando o Dropbox como repositório GIT

Olá, tudo bem?

Você precisa de um repositório GIT privado, e não quer pagar para ter isto no Github ou então utilizar outros serviços como por exemplo Bitbucket?

E se eu te falar que é possível ter repositório GIT privado utilizando o famoso serviço de nuvem Dropbox?

Vamos então configurar o Dropbox para ser o nosso repositório GIT, e assim ter um repositório privado ou até mesmo compartilhado somente com os envolvidos no projeto e que será atualizado em todas as máquina que você possuir o Dropbox instalado.

Os requisitos:

  • Ter uma conta no Dropbox, e instalar o aplicativo em sua máquina. (caso ainda não tenha, clique aqui e crie a sua!)
  • Ter o git instalado. (Caso não tenha, clique aqui e baixe de acordo com seu S.O.)

Vamos aos passos:

  • Após ter instalado o aplicativo do Dropbox em sua máquina e logado, crie uma pasta na pasta do Dropbox em seu computador. Aqui, vamos chamar esta pasta de “Projetos”;
  • Agora, vamos iniciar um novo projeto GIT, na pasta criada anteriormente. Para isto, vamos acessar a pasta Projetos criada com o Terminal ou CMDOS, e digitar o seguinte comando:
git init --bare meuprojeto.git

Troque meuprojeto.git para o nome do seu projeto

Com isso, temos o nosso repositório GIT criado!

Agora vamos começar a  trabalhar com este projeto:

  • Crie uma pasta em outro local no mesmo computador e adicione os arquivos que você deseja que vá para o repositório. No meu exemplo a pasta também será chamada meuprojeto;
  • Em seguida, acesse a pasta que você acabou de criar com o Terminal e adicionou os arquivos e digite a seguinte sequência:
git init

git add .

git commit -m "Primeiro Commit"

Agora nós adicionamos os arquivos e realizamos o primeiro commit na nossa pasta. Agora, vamos adicionar o nosso repositório do Dropbox e fazer um push dos arquivos.

git remote add origin ~/Dropbox/Projetos/meuprojeto.git

git push -u origin master

Pronto! Seu repositório já está com os arquivos!

Para testar se deu certo, execute o seguinte comando:

git clone ~/Dropbox/Projetos/meuprojeto.git meuprojeto2

Agora você pode acessar a pasta meuprojeto2 e ver que os arquivos estão lá.

Compartilhando o repositório

Caso queira compartilhar o seu repositório com algum amigo, time, etc, vá na sua pasta do Dropbox, clique com o botão direito em cima da pasta com final .git e clique em “Compartilhar Link da Pasta”, ou então acesse o site dropbox.com, selecione a pasta .git que deseja compartilhar e adicione os emails.

Em seguida, execute os comandos:

git clone linkdorepositorio nome

git pull

Aí é só correr para o abraço!

Caso queira utilizar uma interface visual para ter o controle do código, recomendo utilizar a interface desktop do Github. Após instalada, basta adicionar a sua pasta de desenvolvimento (não é o repositório que está no dropbox), e acompanhar a evolução do código!

Até a próxima galera!

Compartilhar:

Comprimindo Backups MS SQL Server com Python

 

No post anterior vimos como criar um backup em base MS SQL Server utilizando Python, com a biblioteca pyodbc.
Hoje, vamos melhorar este código, adicionando a função de comprimir o arquivo .bak gerado.

Você pode baixar o código criado no post anterior clicando aqui.

Vamos continuar!

Vamos definir então uma nova função, chamada comprimir.

Para definir uma função em Python, basta colocar def nomedafuncao(): caso queira sem parâmetros ou então def nomedafuncao(parametro):, caso queira passar um parâmetro.

Está função ficará entre a função backup e a função main e receberá como parâmentro o zipname e filename:

#Função para comprimir arquivo
def comprimir(zipname="",filename=""):

Em seguida, vamos instânciar __zipname, que vai receber zipname + “.zip” e __filename, que vai receber filename + “.bak”.

#Função para comprimir arquivo
def comprimir(zipname="",filename=""):
  __zipname = zipname + ".zip"
  __filename = filename + ".bak"

Agora, vamos criar o nosso zip, e adicionar nele o arquivo .bak gerado.

#Cria o arquivo .zip, com as informações passadas e adiciona o arquivo .bak neste zip.
  with zipfile.ZipFile(__zipname, mode='w', allowZip64=True) as myzip:
    myzip.write(__filename, compress_type = zipfile.ZIP_DEFLATED)

Agora, vamos chamar está função.

Depois de

while __cursor.nextset():
  pass

Coloque:

comprimir(__destinationpath + "teste",__destinationpath + __dbname)

Vamos aos “macetes”.

Você deve informar sempre o __destinationpath antes, para que ele zip no mesmo local onde foi criado o bak, e aonde você informa o __dbname você também deve colocar o __destionationpath, para que ele possa pegar o arquivo no caminho onde você salvou.

Pronto! O seu zip será gerado com o arquivo .bak inserido!

Você pode baixar o código criado neste post clicando aqui.

Grande abraço e até a próxima!

Compartilhar:

Realizando Backups de Bancos MS SQL Server com Python

Olá, tudo bem?

Recentemente precisei criar uma rotina de backups de bases MS SQL Server, mas não queria fazer a mesma utilizando o shell do MS SQL Server.

Diante disto, resolvi implementar a mesma em Python, mas, como fazer?

Neste exemplo foi utilizando o pyodbc e o Python 3.4.3.

Bom, vamos ao passos:

Vamos criar um arquivo chamado backup.py e importar a biblioteca do pyodbc

import pypyodbc

Em seguida, vamos criar a classe main() e instanciar

import pypyodbc

def backup():

if __name__ == '__main__':
  backup()

Agora vamos criar 2 variáveis, onde você poderá informar o nome do banco que será realizado o backup e o diretório para onde vai o arquivo “.bak”

import pypyodbc

def backup():
  __dbname = ""
  __destinationpath = ""
  
if __name__ == '__main__':
  backup()

Agora, vamos declara variáveis para informar os dados de acesso. (Gosto de fazer isto para não ficar mexendo na string de conexão. Você pode também criar um arquivo “config.ini”, e salvar os dados dentro deste arquivo)

import pypyodbc

def backup():
  __dbname = ""
  __destinationpath = ""
  __driver = ""
  __server = ""
  __database = ""
  __user = ""
  __passwd = ""

if __name__ == '__main__':
  backup()

Preencha as variáveis de acordo com seu servidor, lembrando que __driver deve receber {SQL Server} e __database deve receber “master”.

Agora, vamos montar nossa string de conexão e abrir esta conexão

import pypyodbc

def backup():
  __dbname = "meubanco"
  __destinationpath = "C:\teste\"
  __driver = "{SQL Server}"
  __server = "."
  __database = "master"
  __user = "sa"
  __passwd = "sa"
  __connectionString = 'Driver=%s;Server=%s;Database=%s;uid=%s;pwd=%s' % (__driver,__server,__database,__user,__passwd)
  __connection = pypyodbc.connect(__connectionString,autocommit=True)

if __name__ == '__main__':
  backup()

Agora vamos a parte mais importante, o script a ser executado.

Um script de backup consiste em:

– Informar o nome do banco a ser realizado o backup e caso seja necessário, informar o caminho. Neste exemplo vamos informar o caminho.

O script ficará semelhante a este:

BACKUP DATABASE MeuBanco 
TO DISK=N'C:\Teste\MeuBanco.bak' 
WITH NOFORMAT, 
INIT, 
NOUNLOAD, 
NAME ='MeuBanco Backup', NOSKIP, STATS = 10

Vamos então criar um cursor, que vai receber __connection.cursor() e em seguida colocar o comando a ser executado.

import pypyodbc

def backup():
  __dbname = ""
  __destinationpath = ""
  __driver = ""
  __server = ""
  __database = ""
  __user = ""
  __passwd = ""
  __connectionString = 'Driver=%s;Server=%s;Database=%s;uid=%s;pwd=%s' % (__driver,__server,__database,__user,__passwd)
  __connection = pypyodbc.connect(__connectionString,autocommit=True)
  __cursor = __connection.cursor()
  __cursor.execute("BACKUP DATABASE ? TO DISK=? WITH NOFORMAT, INIT, NOUNLOAD, NAME ='? Backup', NOSKIP, STATS = 10", [__dbname, __destinationpath + __dbname + '.bak'], __dbname)
  while __cursor.nextset():
    pass

if __name__ == '__main__':
  backup()

Explicando:

Lembra que declaramos lá em cima a variável __dbname e __destinationpath?
Pois então, no script sql que criamos, vamos colocar as variáveis, que irão substituir o ? presente no script.

 

__cursor.execute("BACKUP DATABASE ? TO DISK=? WITH NOFORMAT, INIT, NOUNLOAD, NAME ='? Backup', NOSKIP, STATS = 10", [__dbname, __destinationpath + __dbname + '.bak'], __dbname)

–  o primeiro ? será substituido pelo __dbname;

– o segundo ? será substituido por __destinationpath + __dbname;

– o terceiro ? será substituido por __dbname.

 

Pronto! Agora basta colocar os nomes nas variáveis e executar o backup.py!

Você pode baixar o código fonte no meu github clicando aqui.

Abraços e até a próxima!

Compartilhar:

Comprimindo arquivos em “.zip” com a biblioteca ZipFile do Python

Olá!
Vamos aqui a uma dica rápida de como comprimir arquivos com Python.

É bem simples:

(Testado com Python 3.4.3)
Crie um arquivo main.py, e junto com este arquivo crie também um arquivo teste.txt (este será o arquivo a ser comprimido).

Abra o arquivo main.py e digite o seguinte código:

from zipfile import ZipFile

with ZipFile("meuzip.zip","w") as myzip:
  myzip.write('teste.txt')

Pronto! Você já está comprimindo arquivos em Python 🙂

Referências: https://docs.python.org/3/library/zipfile.html#module-zipfile

Compartilhar: