Arquivos do projeto Catalogador DCAT-BR

parent 5f3e2f3e
from flask import Flask, render_template, request, send_file
from rdflib import Graph, Namespace, URIRef, Literal
from rdflib.namespace import DCTERMS, FOAF, RDF, XSD # Importação corrigida
import uuid
app = Flask(__name__)
# Namespaces
DCAT = Namespace("http://www.w3.org/ns/dcat#")
ADMS = Namespace("http://www.w3.org/ns/adms#")
VCARD = Namespace("http://www.w3.org/2006/vcard/ns#")
@app.route('/')
def form():
return render_template('form.html')
@app.route('/generate_rdf', methods=['POST'])
def generate_rdf():
# Validar campos obrigatórios
required_fields = ['title', 'description', 'publisher', 'contactPoint', 'license', 'accrualPeriodicity']
for field in required_fields:
if not request.form.get(field):
return f"Campo obrigatório faltando: {field}", 400
# Criar grafo RDF
g = Graph()
g.bind("dcterms", DCTERMS)
g.bind("dcat", DCAT)
g.bind("foaf", FOAF)
g.bind("vcard", VCARD)
g.bind("adms", ADMS)
# URIs
dataset_id = URIRef(f"https://dados.gov.br/dados/conjuntos-dados/{uuid.uuid4()}")
creator_id = URIRef(f"https://dados.gov.br/dados/organizacoes/{uuid.uuid4()}")
contact_point_id = URIRef(f"mailto:{request.form['contactPoint']}")
# Dataset
g.add((dataset_id, RDF.type, DCAT.Dataset))
g.add((dataset_id, DCTERMS.title, Literal(request.form['title']))) # Agora funcionará
g.add((dataset_id, DCTERMS.description, Literal(request.form['description'])))
g.add((dataset_id, DCTERMS.publisher, Literal(request.form['publisher'])))
g.add((dataset_id, DCAT.license, URIRef(request.form['license'])))
g.add((dataset_id, DCTERMS.accrualPeriodicity, Literal(request.form['accrualPeriodicity'])))
g.add((dataset_id, DCTERMS.accessRights, Literal(request.form['accessRights'])))
g.add((dataset_id, ADMS.version, Literal(request.form['version'])))
# Criador (Organização)
g.add((dataset_id, DCTERMS.creator, creator_id))
g.add((creator_id, RDF.type, FOAF.Organization))
g.add((creator_id, FOAF.name, Literal(request.form['creator'])))
# Contact Point
g.add((dataset_id, DCAT.contactPoint, contact_point_id))
g.add((contact_point_id, RDF.type, VCARD.Organization))
g.add((contact_point_id, VCARD.hasEmail, contact_point_id))
# Palavras chave
for keyword in request.form['keywords'].split(','):
g.add((dataset_id, DCAT.keyword, Literal(keyword.strip())))
# Temas
for theme in request.form['theme'].split(','):
g.add((dataset_id, DCAT.theme, Literal(theme.strip())))
# Salvar RDF em arquivo temporário
rdf_content = g.serialize(format='pretty-xml')
return rdf_content, 200, {
'Content-Type': 'application/rdf+xml',
'Content-Disposition': 'attachment; filename=metadata.rdf'
}
if __name__ == '__main__':
app.run(debug=True)
\ No newline at end of file
Flask
rdflib
\ No newline at end of file
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Catalogador de conjuntos de dados DCAT-BR - Governo Federal</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body {
font-family: 'Public Sans', sans-serif;
background-color: #f8f9fa;
}
.gov-header {
background-color: #0f3866;
border-bottom: 4px solid #f5c400;
color: white;
}
.required-label::after {
content: "*";
color: #dc3545;
margin-left: 3px;
}
</style>
</head>
<body>
<header class="gov-header py-3">
<div class="container">
<div class="row align-items-center">
<div class="col-auto">
<img src="https://www.gov.br/++theme++padrao_govbr/img/govbr-colorido-b.png"
alt="Governo Federal"
style="height: 50px;">
</div>
<div class="col">
<h1 class="h4 mb-0">Catalogador DCAT-BR</h1>
<p class="mb-0">Catálogo Nacional de Dados</p>
</div>
</div>
</div>
</header>
<main class="container my-5">
<div class="row justify-content-center">
<div class="col-lg-8">
<form action="/generate_rdf" method="POST" class="needs-validation" novalidate>
<!-- Título -->
<div class="mb-3">
<label for="title" class="form-label required-label">Título (dcterms:title)</label>
<input type="text" class="form-control" id="title" name="title" required>
<div class="invalid-feedback">Campo obrigatório.</div>
</div>
<!-- Descrição -->
<div class="mb-3">
<label for="description" class="form-label required-label">Descrição (dcterms:description)</label>
<textarea class="form-control" id="description" name="description" rows="3" required></textarea>
<div class="invalid-feedback">Campo obrigatório.</div>
</div>
<!-- Periodicidade de Atualização -->
<div class="mb-3">
<label for="accrualPeriodicity" class="form-label required-label">Periodicidade (dcterms:accrualPeriodicity)</label>
<select class="form-select" id="accrualPeriodicity" name="accrualPeriodicity" required>
<option value="http://purl.org/cld/freq/daily">Diária</option>
<option value="http://purl.org/cld/freq/weekly">Semanal</option>
<option value="http://purl.org/cld/freq/monthly">Mensal</option>
<option value="http://purl.org/cld/freq/annual">Anual</option>
<option value="SOB_DEMANDA">Sob Demanda</option>
</select>
</div>
<!-- Palavras-chave -->
<div class="mb-3">
<label for="keywords" class="form-label">Palavras-chave (dcat:keyword)</label>
<input type="text" class="form-control" id="keywords" name="keywords"
placeholder="Separe por vírgulas">
</div>
<!-- E-mail da Área Técnica -->
<div class="mb-3">
<label for="contactPoint" class="form-label required-label">E-mail (dcat:contactPoint)</label>
<input type="email" class="form-control" id="contactPoint" name="contactPoint" required>
<div class="invalid-feedback">Insira um e-mail válido.</div>
</div>
<!-- Área Técnica Responsável -->
<div class="mb-3">
<label for="publisher" class="form-label required-label">Área Técnica (dcterms:publisher)</label>
<input type="text" class="form-control" id="publisher" name="publisher" required>
<div class="invalid-feedback">Campo obrigatório.</div>
</div>
<!-- Versão -->
<div class="mb-3">
<label for="version" class="form-label">Versão (adms:version)</label>
<input type="text" class="form-control" id="version" name="version">
</div>
<!-- Observância Legal -->
<div class="mb-3">
<label for="accessRights" class="form-label required-label">Observância Legal (dcterms:accessRights)</label>
<input type="text" class="form-control" id="accessRights" name="accessRights" required>
<div class="invalid-feedback">Campo obrigatório.</div>
</div>
<!-- Temas -->
<div class="mb-3">
<label for="theme" class="form-label required-label">Temas (dcat:theme)</label>
<input type="text" class="form-control" id="theme" name="theme"
placeholder="Separe por vírgulas" required>
<div class="invalid-feedback">Campo obrigatório.</div>
</div>
<!-- Licença -->
<div class="mb-3">
<label for="license" class="form-label required-label">Licença (dcterms:license)</label>
<input type="url" class="form-control" id="license" name="license"
placeholder="Ex: https://opendefinition.org/licenses/odc-odbl" required>
<div class="invalid-feedback">Insira uma URI válida.</div>
</div>
<!-- Organização -->
<div class="mb-3">
<label for="creator" class="form-label required-label">Organização (dcterms:creator)</label>
<input type="text" class="form-control" id="creator" name="creator" required>
<div class="invalid-feedback">Campo obrigatório.</div>
</div>
<!-- Botões -->
<div class="d-grid gap-2 d-md-flex justify-content-md-end mt-4">
<button type="reset" class="btn btn-outline-secondary">Limpar</button>
<button type="submit" class="btn btn-primary">Gerar RDF</button>
</div>
</form>
</div>
</div>
</main>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
// Validação de formulário
(() => {
'use strict'
const forms = document.querySelectorAll('.needs-validation')
Array.from(forms).forEach(form => {
form.addEventListener('submit', event => {
if (!form.checkValidity()) {
event.preventDefault()
event.stopPropagation()
}
form.classList.add('was-validated')
}, false)
})
})()
</script>
</body>
</html>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment