portulong 0.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 portulong
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,145 @@
1
+ Metadata-Version: 2.4
2
+ Name: portulong
3
+ Version: 0.0.1
4
+ Summary: Linguagem 100% PT-PT para desenvolvimento web — interpretador, servidor e extensão VS Code integrados.
5
+ Author: Silvio
6
+ Author-email: silvio@portulong.dev
7
+ License-Expression: MIT
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Python: >=3.6
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+ Provides-Extra: discord
14
+ Requires-Dist: discord.py>=2.0.0; extra == "discord"
15
+ Provides-Extra: supabase
16
+ Requires-Dist: supabase; extra == "supabase"
17
+ Provides-Extra: dev
18
+ Requires-Dist: pytest; extra == "dev"
19
+ Requires-Dist: vsce; extra == "dev"
20
+ Dynamic: author-email
21
+ Dynamic: license-file
22
+ Dynamic: requires-python
23
+
24
+ # Portulong (v1.1.0)
25
+
26
+ Linguagem de programação em Português de Portugal para criar páginas web e aplicações completas com interpretador e servidor integrado.
27
+
28
+ ## Instalação
29
+
30
+ ```bash
31
+ pip install portulong-sistema
32
+ ```
33
+
34
+ ## Utilização
35
+
36
+ Para executar um ficheiro `.ptg`:
37
+
38
+ ```bash
39
+ ptg meu_programa.ptg
40
+ ```
41
+
42
+ Para iniciar o servidor web integrado:
43
+
44
+ ```bash
45
+ ptg meu_programa.ptg --servidor
46
+ ```
47
+
48
+ ## Publicar no PyPI
49
+
50
+ Para publicar a versão **1.1.0** no PyPI:
51
+
52
+ ```bash
53
+ # 1. Instalar as ferramentas de publicação
54
+ pip install --upgrade build twine
55
+
56
+ # 2. Gerar o pacote em dist/
57
+ python -m build
58
+
59
+ # 3. Enviar para o PyPI
60
+ twine upload dist/*
61
+ ```
62
+
63
+ Ou execute diretamente o script auxiliar:
64
+ ```bash
65
+ bash publicar_pypi.sh
66
+ ```
67
+
68
+ ## Exemplo (`ola_mundo.ptg`)
69
+
70
+ ```ptg
71
+ pagina "Minha Primeira Pagina"
72
+
73
+ cabecalho "Olá, Mundo em Portulong!"
74
+ paragrafo "Criado com sintaxe 100% em Português de Portugal."
75
+
76
+ estilo:
77
+ corpo { fundo: #f0fdf4; espacamento: 40px; }
78
+
79
+ script:
80
+ escrever("ola tudo ?")
81
+ ```
82
+
83
+ ## Novidades v1.1.0
84
+
85
+ ### Bloco Supabase Declarativo
86
+ Conecte à sua base de dados Supabase com uma sintaxe simples:
87
+
88
+ ```ptg
89
+ supabase:
90
+ url "https://teu-projeto.supabase.co"
91
+ chave "tua-chave-api"
92
+ fim_supabase
93
+ ```
94
+
95
+ ### Rotas Backend com Execução Dinâmica
96
+ Rotas que executam código Python e retornam JSON dinamicamente:
97
+
98
+ ```ptg
99
+ rota GET /api/usuarios:
100
+ resposta = {"usuarios": [{"id": 1, "nome": "João"}]}
101
+ fim_rota
102
+
103
+ rota POST /api/usuario:
104
+ nome_usuario = dados.get("nome", "")
105
+ resposta = {"sucesso": verdadeiro, "mensagem": "Utilizador " + nome_usuario + " criado!"}
106
+ fim_rota
107
+ ```
108
+
109
+ ### Múltiplos Ecrãs (SPA)
110
+ Crie aplicações de página única com navegação sem recarregar:
111
+
112
+ ```ptg
113
+ tela "inicio":
114
+ cabecalho "Bem-vindo"
115
+ botao "Ir para Dashboard" acao "mostrar_tela('dashboard')"
116
+ fim_tela
117
+
118
+ tela "dashboard":
119
+ cabecalho "Dashboard"
120
+ botao "Voltar" acao "mostrar_tela('inicio')"
121
+ fim_tela
122
+ ```
123
+
124
+ ### CSS Avançado — Liberdade Total
125
+ Suporte completo a animações, responsividade e efeitos visuais:
126
+
127
+ ```ptg
128
+ estilo:
129
+ @keyframes pulse {
130
+ 0% { opacidade: 0.6; }
131
+ 50% { opacidade: 1; }
132
+ 100% { opacidade: 0.6; }
133
+ }
134
+
135
+ @media (max-width: 768px) {
136
+ corpo { espacamento: 15px; }
137
+ }
138
+
139
+ .botao-animado {
140
+ animacao: pulse 2s infinito;
141
+ transformar: escorregar(10px);
142
+ fundo: linear-gradient(135deg, #2563eb, #1e40af);
143
+ }
144
+ fim_estilo
145
+ ```
@@ -0,0 +1,122 @@
1
+ # Portulong (v1.1.0)
2
+
3
+ Linguagem de programação em Português de Portugal para criar páginas web e aplicações completas com interpretador e servidor integrado.
4
+
5
+ ## Instalação
6
+
7
+ ```bash
8
+ pip install portulong-sistema
9
+ ```
10
+
11
+ ## Utilização
12
+
13
+ Para executar um ficheiro `.ptg`:
14
+
15
+ ```bash
16
+ ptg meu_programa.ptg
17
+ ```
18
+
19
+ Para iniciar o servidor web integrado:
20
+
21
+ ```bash
22
+ ptg meu_programa.ptg --servidor
23
+ ```
24
+
25
+ ## Publicar no PyPI
26
+
27
+ Para publicar a versão **1.1.0** no PyPI:
28
+
29
+ ```bash
30
+ # 1. Instalar as ferramentas de publicação
31
+ pip install --upgrade build twine
32
+
33
+ # 2. Gerar o pacote em dist/
34
+ python -m build
35
+
36
+ # 3. Enviar para o PyPI
37
+ twine upload dist/*
38
+ ```
39
+
40
+ Ou execute diretamente o script auxiliar:
41
+ ```bash
42
+ bash publicar_pypi.sh
43
+ ```
44
+
45
+ ## Exemplo (`ola_mundo.ptg`)
46
+
47
+ ```ptg
48
+ pagina "Minha Primeira Pagina"
49
+
50
+ cabecalho "Olá, Mundo em Portulong!"
51
+ paragrafo "Criado com sintaxe 100% em Português de Portugal."
52
+
53
+ estilo:
54
+ corpo { fundo: #f0fdf4; espacamento: 40px; }
55
+
56
+ script:
57
+ escrever("ola tudo ?")
58
+ ```
59
+
60
+ ## Novidades v1.1.0
61
+
62
+ ### Bloco Supabase Declarativo
63
+ Conecte à sua base de dados Supabase com uma sintaxe simples:
64
+
65
+ ```ptg
66
+ supabase:
67
+ url "https://teu-projeto.supabase.co"
68
+ chave "tua-chave-api"
69
+ fim_supabase
70
+ ```
71
+
72
+ ### Rotas Backend com Execução Dinâmica
73
+ Rotas que executam código Python e retornam JSON dinamicamente:
74
+
75
+ ```ptg
76
+ rota GET /api/usuarios:
77
+ resposta = {"usuarios": [{"id": 1, "nome": "João"}]}
78
+ fim_rota
79
+
80
+ rota POST /api/usuario:
81
+ nome_usuario = dados.get("nome", "")
82
+ resposta = {"sucesso": verdadeiro, "mensagem": "Utilizador " + nome_usuario + " criado!"}
83
+ fim_rota
84
+ ```
85
+
86
+ ### Múltiplos Ecrãs (SPA)
87
+ Crie aplicações de página única com navegação sem recarregar:
88
+
89
+ ```ptg
90
+ tela "inicio":
91
+ cabecalho "Bem-vindo"
92
+ botao "Ir para Dashboard" acao "mostrar_tela('dashboard')"
93
+ fim_tela
94
+
95
+ tela "dashboard":
96
+ cabecalho "Dashboard"
97
+ botao "Voltar" acao "mostrar_tela('inicio')"
98
+ fim_tela
99
+ ```
100
+
101
+ ### CSS Avançado — Liberdade Total
102
+ Suporte completo a animações, responsividade e efeitos visuais:
103
+
104
+ ```ptg
105
+ estilo:
106
+ @keyframes pulse {
107
+ 0% { opacidade: 0.6; }
108
+ 50% { opacidade: 1; }
109
+ 100% { opacidade: 0.6; }
110
+ }
111
+
112
+ @media (max-width: 768px) {
113
+ corpo { espacamento: 15px; }
114
+ }
115
+
116
+ .botao-animado {
117
+ animacao: pulse 2s infinito;
118
+ transformar: escorregar(10px);
119
+ fundo: linear-gradient(135deg, #2563eb, #1e40af);
120
+ }
121
+ fim_estilo
122
+ ```
@@ -0,0 +1,10 @@
1
+ __version__ = "0.0.1"
2
+ __author__ = "Silvio"
3
+ __license__ = "MIT"
4
+
5
+ from .core import Empretador, PortulongCompilador
6
+ from .erros import PortulongErro, ErroSintaxe, ErroServidor
7
+ from . import discord
8
+ from . import ambiente
9
+ from . import base_dados
10
+ from . import bots
@@ -0,0 +1,4 @@
1
+ from .cli import main
2
+
3
+ if __name__ == "__main__":
4
+ main()
@@ -0,0 +1,48 @@
1
+ """
2
+ Módulo Ambiente Portulong (.env)
3
+ 100% em Português de Portugal para carregar e gerir variáveis de ambiente.
4
+ """
5
+
6
+ import os
7
+ import sys
8
+
9
+ def carregar_ambiente(caminho=".env"):
10
+ """Carrega variáveis de um ficheiro .env para o ambiente de execução."""
11
+ if not os.path.exists(caminho):
12
+ return False
13
+ try:
14
+ with open(caminho, "r", encoding="utf-8") as f:
15
+ for linha in f:
16
+ linha = linha.strip()
17
+ if not linha or linha.startswith("#"):
18
+ continue
19
+ if "=" in linha:
20
+ chave, valor = linha.split("=", 1)
21
+ chave = chave.strip()
22
+ valor = valor.strip().strip('"\'')
23
+ os.environ[chave] = valor
24
+ return True
25
+ except Exception as e:
26
+ print(f"Erro ao carregar .env: {e}")
27
+ return False
28
+
29
+ def obter_ambiente(chave, padrao=None):
30
+ """Obtém o valor de uma variável de ambiente."""
31
+ return os.environ.get(chave, padrao)
32
+
33
+ def obter_variavel(chave, padrao=None):
34
+ """Alias em português para obter uma variável."""
35
+ return os.environ.get(chave, padrao)
36
+
37
+ def definir_ambiente(chave, valor):
38
+ """Define uma variável de ambiente em tempo de execução."""
39
+ os.environ[chave] = str(valor)
40
+
41
+ def verificar_ambiente():
42
+ """Verifica se o interpretador Python 3 está ativo."""
43
+ return sys.version_info.major >= 3
44
+
45
+ # Aliases em português
46
+ carregar_env = carregar_ambiente
47
+ obter = obter_ambiente
48
+ definir = definir_ambiente
@@ -0,0 +1,120 @@
1
+ """
2
+ Módulo Base de Dados e Supabase Portulong
3
+ 100% em Português de Portugal para integração com bases de dados e Supabase.
4
+ """
5
+
6
+ import json
7
+ import os
8
+ import urllib.request
9
+ import urllib.error
10
+
11
+ class ClienteSupabase:
12
+ """Cliente nativo para conectar ao Supabase usando sintaxe 100% em Português."""
13
+ def __init__(self, url, chave):
14
+ self.url = url.rstrip("/")
15
+ self.chave = chave
16
+ self.cabecalhos = {
17
+ "apikey": self.chave,
18
+ "Authorization": f"Bearer {self.chave}",
19
+ "Content-Type": "application/json",
20
+ "Prefer": "return=representation"
21
+ }
22
+
23
+ def tabela(self, nome_tabela):
24
+ """Retorna um objeto de consulta para a tabela especificada."""
25
+ return ConsultaTabela(self.url, nome_tabela, self.cabecalhos)
26
+
27
+ def de(self, nome_tabela):
28
+ """Alias em português: supabase.de('utilizadores')"""
29
+ return self.tabela(nome_tabela)
30
+
31
+ class ConsultaTabela:
32
+ def __init__(self, url_base, tabela, cabecalhos):
33
+ self.url = f"{url_base}/rest/v1/{tabela}"
34
+ self.cabecalhos = cabecalhos
35
+
36
+ def selecionar(self, colunas="*"):
37
+ """Executa um GET para buscar dados da tabela."""
38
+ url = f"{self.url}?select={colunas}"
39
+ req = urllib.request.Request(url, headers=self.cabecalhos)
40
+ try:
41
+ with urllib.request.urlopen(req) as resp:
42
+ return json.loads(resp.read().decode("utf-8"))
43
+ except Exception as e:
44
+ return {"erro": str(e)}
45
+
46
+ def inserir(self, dados):
47
+ """Executa um POST para inserir um novo registo."""
48
+ corpo = json.dumps(dados).encode("utf-8")
49
+ req = urllib.request.Request(self.url, data=corpo, headers=self.cabecalhos, method="POST")
50
+ try:
51
+ with urllib.request.urlopen(req) as resp:
52
+ return json.loads(resp.read().decode("utf-8"))
53
+ except Exception as e:
54
+ return {"erro": str(e)}
55
+
56
+ def atualizar(self, id_registo, dados):
57
+ """Executa um PATCH para atualizar um registo."""
58
+ url = f"{self.url}?id=eq.{id_registo}"
59
+ corpo = json.dumps(dados).encode("utf-8")
60
+ req = urllib.request.Request(url, data=corpo, headers=self.cabecalhos, method="PATCH")
61
+ try:
62
+ with urllib.request.urlopen(req) as resp:
63
+ return json.loads(resp.read().decode("utf-8"))
64
+ except Exception as e:
65
+ return {"erro": str(e)}
66
+
67
+ def apagar(self, id_registo):
68
+ """Executa um DELETE para remover um registo."""
69
+ url = f"{self.url}?id=eq.{id_registo}"
70
+ req = urllib.request.Request(url, headers=self.cabecalhos, method="DELETE")
71
+ try:
72
+ with urllib.request.urlopen(req) as resp:
73
+ return {"sucesso": True}
74
+ except Exception as e:
75
+ return {"erro": str(e)}
76
+
77
+ def conectar_supabase(url, chave):
78
+ """Função em português para instanciar a conexão Supabase."""
79
+ return ClienteSupabase(url, chave)
80
+
81
+ class BaseDadosMemoria:
82
+ """Base de dados em memória e ficheiro JSON para persistência simples."""
83
+ def __init__(self, arquivo="dados_portulong.json"):
84
+ self.arquivo = arquivo
85
+ self.tabelas = {}
86
+ self.carregar()
87
+
88
+ def carregar(self):
89
+ if os.path.exists(self.arquivo):
90
+ try:
91
+ with open(self.arquivo, "r", encoding="utf-8") as f:
92
+ self.tabelas = json.load(f)
93
+ except Exception:
94
+ self.tabelas = {}
95
+
96
+ def guardar(self):
97
+ try:
98
+ with open(self.arquivo, "w", encoding="utf-8") as f:
99
+ json.dump(self.tabelas, f, ensure_ascii=False, indent=2)
100
+ except Exception as e:
101
+ print(f"Aviso base de dados: {e}")
102
+
103
+ def obter(self, tabela, id_registo=None):
104
+ dados_tabela = self.tabelas.get(tabela, [])
105
+ if id_registo is not None:
106
+ for r in dados_tabela:
107
+ if r.get("id") == id_registo:
108
+ return r
109
+ return None
110
+ return dados_tabela
111
+
112
+ def inserir(self, tabela, registo):
113
+ if tabela not in self.tabelas:
114
+ self.tabelas[tabela] = []
115
+ dados_tabela = self.tabelas[tabela]
116
+ if "id" not in registo:
117
+ registo["id"] = len(dados_tabela) + 1
118
+ dados_tabela.append(registo)
119
+ self.guardar()
120
+ return registo
@@ -0,0 +1,21 @@
1
+ """
2
+ Módulo Bots Portulong (Discord, Telegram e Automação)
3
+ 100% em Português de Portugal.
4
+ """
5
+
6
+ from . import discord
7
+
8
+ class PortulongBot:
9
+ """Suporte geral para bots e automação em Portulong."""
10
+ def __init__(self, nome="Bot Portulong"):
11
+ self.nome = nome
12
+
13
+ def executar_tarefa(self, tarefa):
14
+ print(f"[{self.nome}] A executar tarefa: {tarefa}")
15
+ return True
16
+
17
+ # Integração direta do submódulo Discord dentro de bots
18
+ Discord = discord.BotDiscord
19
+ CriarBotDiscord = discord.CriarBot
20
+ Incorporado = discord.Incorporado
21
+ Contexto = discord.ContextoPortulong