Spaces:
Configuration error
Configuration error
Deploy oficial MatVerse Memory Registry - Action B Package
Browse files- MANIFEST.json +38 -0
- MATVERSE_UNIFICATION_PAPER.md +96 -0
- README.md +15 -48
- deploy_artifacts.json +21 -0
- receipt_pole_anchor.json +15 -0
- zenodo_metadata.json +39 -0
- zenodo_upload_local.py +58 -0
MANIFEST.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"files": [
|
| 3 |
+
{
|
| 4 |
+
"path": "MATVERSE_UNIFICATION_PAPER.md",
|
| 5 |
+
"sha256": "4d1b8f0842c2edb4bb630a16a82600e69e2c80dd89534658a93c4a9496e3cf64",
|
| 6 |
+
"size_bytes": 3147
|
| 7 |
+
},
|
| 8 |
+
{
|
| 9 |
+
"path": "README.md",
|
| 10 |
+
"sha256": "6ae4158321d480081a7546f87f082f21952a1f1d9ae893fe6b01c1be54fed803",
|
| 11 |
+
"size_bytes": 700
|
| 12 |
+
},
|
| 13 |
+
{
|
| 14 |
+
"path": "deploy_artifacts.json",
|
| 15 |
+
"sha256": "0bbee31a58512e30b37d16746744ad1456ecb21609e91bc01014a9b8e90a8c2c",
|
| 16 |
+
"size_bytes": 1004
|
| 17 |
+
},
|
| 18 |
+
{
|
| 19 |
+
"path": "receipt_pole_anchor.json",
|
| 20 |
+
"sha256": "6cac82d14fa65ae83eb4de483986809d1a60392631d0e78af60c54a250f9b35e",
|
| 21 |
+
"size_bytes": 681
|
| 22 |
+
},
|
| 23 |
+
{
|
| 24 |
+
"path": "zenodo_metadata.json",
|
| 25 |
+
"sha256": "dc709fe30ee716f4232b6e6f625c0e1d796d256d80070d3b05e9438f16b239ea",
|
| 26 |
+
"size_bytes": 1536
|
| 27 |
+
},
|
| 28 |
+
{
|
| 29 |
+
"path": "zenodo_upload_local.py",
|
| 30 |
+
"sha256": "cf1a18b96f1b5cf58c0029bed6ad71f54be323c4806cf3c69419ebefbd658927",
|
| 31 |
+
"size_bytes": 2350
|
| 32 |
+
}
|
| 33 |
+
],
|
| 34 |
+
"generated_at_utc": "2026-05-08T19:34:57.422674Z",
|
| 35 |
+
"schema": "matverse.zenodo.action_b.manifest.v1",
|
| 36 |
+
"source_zip": "matverse_current_reality_release_deploy.zip",
|
| 37 |
+
"source_zip_sha256": "b74e30199e6ff6d796de33a200cc6216e9268a2661bc101d4f1c99f033770b1d"
|
| 38 |
+
}
|
MATVERSE_UNIFICATION_PAPER.md
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# MatVerse: Unificação Operacional, PoLE e Evidência de Ancoragem na Polygon Amoy
|
| 2 |
+
|
| 3 |
+
**Autor**: Mateus Areas
|
| 4 |
+
**ORCID**: 0009-0008-2973-4047
|
| 5 |
+
**Afiliação**: MatVerse Institute
|
| 6 |
+
**Data**: 2026-05-08
|
| 7 |
+
**Versão**: Action B Zenodo Evidence Package v1.0
|
| 8 |
+
|
| 9 |
+
## Resumo
|
| 10 |
+
|
| 11 |
+
Este artefato documenta a evidência local do evento `AMOY_POLE_ANCHOR` associado ao MatVerse, incluindo contrato de ancoragem, Merkle Root canônica, receipt PoLE e metadados de deploy. O pacote separa evidência computável, metadados institucionais e paper de unificação operacional.
|
| 12 |
+
|
| 13 |
+
O estado declarado neste pacote é **PASS local / pendente de confirmação externa do explorer ou RPC**. A política constitucional permanece `plaintext(secret) -> BLOCK`; nenhum token, senha, mnemonic ou chave privada deve ser incluído no depósito.
|
| 14 |
+
|
| 15 |
+
## 1. Modelo operacional
|
| 16 |
+
|
| 17 |
+
O MatVerse é tratado como uma arquitetura de governança verificável para eventos informacionais, digitais e físicos. O fluxo canônico é:
|
| 18 |
+
|
| 19 |
+
```text
|
| 20 |
+
evento -> MNB -> Omega-Gate -> decisão -> receipt -> ledger -> replay -> anchor
|
| 21 |
+
```
|
| 22 |
+
|
| 23 |
+
## 2. PoLE: Proof of Ledger Evolution
|
| 24 |
+
|
| 25 |
+
O PoLE materializa evidência pública de evolução do ledger por meio de uma Merkle Root ancorada em blockchain pública/testnet.
|
| 26 |
+
|
| 27 |
+
### Dados da ancoragem
|
| 28 |
+
|
| 29 |
+
```json
|
| 30 |
+
{
|
| 31 |
+
"network": "Polygon Amoy Testnet",
|
| 32 |
+
"chain_id": 80002,
|
| 33 |
+
"contract_address": "0xBB9Ae7a2c308057EF5f735dc74744fB686B08229",
|
| 34 |
+
"deploy_tx_hash": "0x0b3e848ef71731f023ba7918141861575c5a43c473a07dadb053c17c112f6616",
|
| 35 |
+
"anchor_tx_hash": "0xc930f8faeb7258caba763f1babcba6a5df247b3d56500d57590172cda08d8612",
|
| 36 |
+
"block_number": 38024912,
|
| 37 |
+
"signer_address": "0x5e3451Dd4783F026cD9af10a46B9DBb99FedeD79",
|
| 38 |
+
"merkle_root": "0x60ff4fa71823d9e837c5f0d593bd4f275950354784a01a2745b89b78f939203c",
|
| 39 |
+
"receipt_hash": "811f50ff7e1e59b9f8cef097108b02f2888d10d2301e9d08721d7fa91b3f9069",
|
| 40 |
+
"timestamp_utc": "2026-05-08T19:19:10.355000Z"
|
| 41 |
+
}
|
| 42 |
+
```
|
| 43 |
+
|
| 44 |
+
## 3. Omega-Gate
|
| 45 |
+
|
| 46 |
+
O operador de admissibilidade é:
|
| 47 |
+
|
| 48 |
+
\[
|
| 49 |
+
\Omega(x)=0.4\Psi+0.3\hat{\Theta}+0.2(1-CVaR)+0.1PoLE
|
| 50 |
+
\]
|
| 51 |
+
|
| 52 |
+
Com os parâmetros operacionais usados no fechamento:
|
| 53 |
+
|
| 54 |
+
\[
|
| 55 |
+
\Psi=0.91,\quad \hat{\Theta}=0.91,\quad CVaR=0.03,\quad PoLE=1
|
| 56 |
+
\]
|
| 57 |
+
|
| 58 |
+
\[
|
| 59 |
+
\Omega=0.4(0.91)+0.3(0.91)+0.2(0.97)+0.1(1)=0.931
|
| 60 |
+
\]
|
| 61 |
+
|
| 62 |
+
Resultado local:
|
| 63 |
+
|
| 64 |
+
```text
|
| 65 |
+
Omega_runtime = 0.931 >= 0.85 -> PASS_LOCAL
|
| 66 |
+
```
|
| 67 |
+
|
| 68 |
+
## 4. Limitações e status de validação
|
| 69 |
+
|
| 70 |
+
Este pacote **não declara peer review**, adoção institucional externa ou settlement mainnet. Ele declara:
|
| 71 |
+
|
| 72 |
+
```text
|
| 73 |
+
PoLE receipt localmente consistente = true
|
| 74 |
+
receipt_hash recalculado = true
|
| 75 |
+
chain_id Amoy = 80002
|
| 76 |
+
external_chain_verification = pending
|
| 77 |
+
```
|
| 78 |
+
|
| 79 |
+
Para promover o estado de `PASS_LOCAL` para `PASS_EXTERNAL`, confirmar no explorer/RPC:
|
| 80 |
+
|
| 81 |
+
```text
|
| 82 |
+
tx.status = success
|
| 83 |
+
block_number = 38024912
|
| 84 |
+
from = 0x5e3451Dd4783F026cD9af10a46B9DBb99FedeD79
|
| 85 |
+
to = 0xBB9Ae7a2c308057EF5f735dc74744fB686B08229
|
| 86 |
+
root = 0x60ff4fa71823d9e837c5f0d593bd4f275950354784a01a2745b89b78f939203c
|
| 87 |
+
```
|
| 88 |
+
|
| 89 |
+
## 5. Política de segurança
|
| 90 |
+
|
| 91 |
+
Nenhum segredo deve ser publicado no Zenodo. O pacote usa apenas dados públicos: endereços, hashes, Merkle Root, receipt hash e metadados de rede.
|
| 92 |
+
|
| 93 |
+
```text
|
| 94 |
+
plaintext(secret) -> BLOCK
|
| 95 |
+
secret_ref-only -> PASS
|
| 96 |
+
```
|
README.md
CHANGED
|
@@ -1,54 +1,21 @@
|
|
| 1 |
-
|
| 2 |
-
title: MatVerse Memory Registry
|
| 3 |
-
emoji: 🧠
|
| 4 |
-
colorFrom: indigo
|
| 5 |
-
colorTo: purple
|
| 6 |
-
sdk: gradio
|
| 7 |
-
sdk_version: "5.24.0"
|
| 8 |
-
python_version: "3.10"
|
| 9 |
-
app_file: app.py
|
| 10 |
-
pinned: false
|
| 11 |
-
fullWidth: true
|
| 12 |
-
header: default
|
| 13 |
-
short_description: Landing page oficial e dashboard de prova MatVerse.
|
| 14 |
-
tags:
|
| 15 |
-
- governance
|
| 16 |
-
- ledger
|
| 17 |
-
- public-proof
|
| 18 |
-
- dashboard
|
| 19 |
-
- matverse
|
| 20 |
-
---
|
| 21 |
|
| 22 |
-
|
| 23 |
|
| 24 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 25 |
|
| 26 |
-
|
| 27 |
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
- dashboard de deploy dos artefatos soberanos
|
| 31 |
-
- trilha de verificação com links externos
|
| 32 |
-
- estado fail-closed explícito para módulos bloqueados
|
| 33 |
|
| 34 |
-
|
|
|
|
| 35 |
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
- `proof_data.json`
|
| 39 |
-
- `requirements.txt`
|
| 40 |
-
|
| 41 |
-
## Observação operacional
|
| 42 |
-
|
| 43 |
-
Se o Space continuar em erro após o commit:
|
| 44 |
-
1. confira se o `README.md` começa exatamente com o bloco YAML acima
|
| 45 |
-
2. confirme que `app_file: app.py` aponta para um arquivo real na raiz
|
| 46 |
-
3. use hardware CPU padrão, não ZeroGPU, para este Space de dashboard/landing
|
| 47 |
-
4. reinicie o Space após o push
|
| 48 |
-
|
| 49 |
-
## Fonte das métricas exibidas
|
| 50 |
-
|
| 51 |
-
Os números de exemplo e o seed do dashboard foram organizados para refletir:
|
| 52 |
-
- operador Ω e fail-closed do stack MNB
|
| 53 |
-
- ledger append-only com Merkle root e replay
|
| 54 |
-
- inventário KiloApps com 25 apps, 23 deploys bem-sucedidos e 2 falhas
|
|
|
|
| 1 |
+
# MatVerse Zenodo Action B Package
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
|
| 3 |
+
Status: PASS_LOCAL / HOLD_EXTERNAL_CHAIN_VERIFY
|
| 4 |
|
| 5 |
+
Files:
|
| 6 |
+
- receipt_pole_anchor.json: primary PoLE receipt
|
| 7 |
+
- deploy_artifacts.json: normalized deployment and anchor metadata
|
| 8 |
+
- MATVERSE_UNIFICATION_PAPER.md: operational unification paper
|
| 9 |
+
- zenodo_metadata.json: Zenodo API-compatible metadata envelope
|
| 10 |
+
- MANIFEST.json: checksums and package inventory
|
| 11 |
|
| 12 |
+
Do not add secrets. Do not upload .env, wallet files, terminal history, or unredacted logs.
|
| 13 |
|
| 14 |
+
Anchor transaction:
|
| 15 |
+
0xc930f8faeb7258caba763f1babcba6a5df247b3d56500d57590172cda08d8612
|
|
|
|
|
|
|
|
|
|
| 16 |
|
| 17 |
+
Contract:
|
| 18 |
+
0xBB9Ae7a2c308057EF5f735dc74744fB686B08229
|
| 19 |
|
| 20 |
+
Merkle Root:
|
| 21 |
+
0x60ff4fa71823d9e837c5f0d593bd4f275950354784a01a2745b89b78f939203c
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
deploy_artifacts.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"anchorTxHash": "0xc930f8faeb7258caba763f1babcba6a5df247b3d56500d57590172cda08d8612",
|
| 3 |
+
"blockNumber": 38024912,
|
| 4 |
+
"chainId": 80002,
|
| 5 |
+
"contractAddress": "0xBB9Ae7a2c308057EF5f735dc74744fB686B08229",
|
| 6 |
+
"deployTxHash": "0x0b3e848ef71731f023ba7918141861575c5a43c473a07dadb053c17c112f6616",
|
| 7 |
+
"externalChainVerification": "PENDING_USER_OR_EXPLORER_CONFIRMATION",
|
| 8 |
+
"gasUsed": 23931,
|
| 9 |
+
"merkleRoot": "0x60ff4fa71823d9e837c5f0d593bd4f275950354784a01a2745b89b78f939203c",
|
| 10 |
+
"network": "Polygon Amoy Testnet",
|
| 11 |
+
"omegaScore": 0.931,
|
| 12 |
+
"pole": 1,
|
| 13 |
+
"receiptHash": "811f50ff7e1e59b9f8cef097108b02f2888d10d2301e9d08721d7fa91b3f9069",
|
| 14 |
+
"receiptHashRecomputed": "811f50ff7e1e59b9f8cef097108b02f2888d10d2301e9d08721d7fa91b3f9069",
|
| 15 |
+
"receiptHashValid": true,
|
| 16 |
+
"schema": "matverse.deploy_artifacts.v1",
|
| 17 |
+
"securityPolicy": "secret_ref_only_no_plaintext_secret_in_package",
|
| 18 |
+
"signer": "0x5e3451Dd4783F026cD9af10a46B9DBb99FedeD79",
|
| 19 |
+
"timestampMs": 1778267950355,
|
| 20 |
+
"timestampUtc": "2026-05-08T19:19:10.355000Z"
|
| 21 |
+
}
|
receipt_pole_anchor.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"anchor_tx_hash": "c930f8faeb7258caba763f1babcba6a5df247b3d56500d57590172cda08d8612",
|
| 3 |
+
"block_number": 38024912,
|
| 4 |
+
"chain_id": 80002,
|
| 5 |
+
"contract_address": "0xBB9Ae7a2c308057EF5f735dc74744fB686B08229",
|
| 6 |
+
"deploy_tx_hash": "0b3e848ef71731f023ba7918141861575c5a43c473a07dadb053c17c112f6616",
|
| 7 |
+
"event": "AMOY_POLE_ANCHOR",
|
| 8 |
+
"gas_used": 23931,
|
| 9 |
+
"merkle_root": "0x60ff4fa71823d9e837c5f0d593bd4f275950354784a01a2745b89b78f939203c",
|
| 10 |
+
"receipt_hash": "811f50ff7e1e59b9f8cef097108b02f2888d10d2301e9d08721d7fa91b3f9069",
|
| 11 |
+
"schema": "matverse.pole.anchor.receipt.v1",
|
| 12 |
+
"signer_address": "0x5e3451Dd4783F026cD9af10a46B9DBb99FedeD79",
|
| 13 |
+
"status": 1,
|
| 14 |
+
"timestamp_ms": 1778267950355
|
| 15 |
+
}
|
zenodo_metadata.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"metadata": {
|
| 3 |
+
"title": "MatVerse Institutionalization: PoLE Anchor Evidence Package on Polygon Amoy",
|
| 4 |
+
"upload_type": "publication",
|
| 5 |
+
"publication_type": "technicalnote",
|
| 6 |
+
"description": "Evidence package for the MatVerse Proof of Ledger Evolution (PoLE) anchor on Polygon Amoy. Includes a PoLE receipt, deployment artifacts, Merkle Root, and an operational unification paper. The package reports local receipt consistency and Omega runtime PASS (Omega = 0.931), with external chain verification to be confirmed through Amoy explorer/RPC.",
|
| 7 |
+
"creators": [
|
| 8 |
+
{
|
| 9 |
+
"name": "Areas, Mateus",
|
| 10 |
+
"orcid": "0009-0008-2973-4047",
|
| 11 |
+
"affiliation": "MatVerse Institute"
|
| 12 |
+
}
|
| 13 |
+
],
|
| 14 |
+
"license": "cc-by-4.0",
|
| 15 |
+
"keywords": [
|
| 16 |
+
"MatVerse",
|
| 17 |
+
"PoLE",
|
| 18 |
+
"Proof of Ledger Evolution",
|
| 19 |
+
"Polygon Amoy",
|
| 20 |
+
"Merkle root",
|
| 21 |
+
"blockchain",
|
| 22 |
+
"computational governance",
|
| 23 |
+
"auditability"
|
| 24 |
+
],
|
| 25 |
+
"notes": "Security policy: no private keys, tokens, mnemonics, passwords, .env files, or raw shell histories are included. Transaction hashes and addresses are public metadata.",
|
| 26 |
+
"related_identifiers": [
|
| 27 |
+
{
|
| 28 |
+
"identifier": "0xc930f8faeb7258caba763f1babcba6a5df247b3d56500d57590172cda08d8612",
|
| 29 |
+
"relation": "isDocumentedBy",
|
| 30 |
+
"resource_type": "other"
|
| 31 |
+
},
|
| 32 |
+
{
|
| 33 |
+
"identifier": "0x0b3e848ef71731f023ba7918141861575c5a43c473a07dadb053c17c112f6616",
|
| 34 |
+
"relation": "isDocumentedBy",
|
| 35 |
+
"resource_type": "other"
|
| 36 |
+
}
|
| 37 |
+
]
|
| 38 |
+
}
|
| 39 |
+
}
|
zenodo_upload_local.py
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""Create a Zenodo deposition draft and upload Action B files.
|
| 3 |
+
|
| 4 |
+
Usage:
|
| 5 |
+
export ZENODO_TOKEN="..." # keep local; never paste into chat/logs
|
| 6 |
+
python zenodo_upload_local.py --sandbox
|
| 7 |
+
python zenodo_upload_local.py --publish
|
| 8 |
+
|
| 9 |
+
Default behavior creates a draft and uploads files, but does not publish.
|
| 10 |
+
"""
|
| 11 |
+
from __future__ import annotations
|
| 12 |
+
import argparse, json, os, sys
|
| 13 |
+
from pathlib import Path
|
| 14 |
+
import requests
|
| 15 |
+
|
| 16 |
+
FILES = [
|
| 17 |
+
"receipt_pole_anchor.json",
|
| 18 |
+
"deploy_artifacts.json",
|
| 19 |
+
"MATVERSE_UNIFICATION_PAPER.md",
|
| 20 |
+
"zenodo_metadata.json",
|
| 21 |
+
"MANIFEST.json",
|
| 22 |
+
"README.md",
|
| 23 |
+
]
|
| 24 |
+
|
| 25 |
+
def main() -> int:
|
| 26 |
+
ap = argparse.ArgumentParser()
|
| 27 |
+
ap.add_argument("--sandbox", action="store_true", help="Use sandbox.zenodo.org")
|
| 28 |
+
ap.add_argument("--publish", action="store_true", help="Publish after upload. Use only after manual review")
|
| 29 |
+
args = ap.parse_args()
|
| 30 |
+
token = os.environ.get("ZENODO_TOKEN")
|
| 31 |
+
if not token:
|
| 32 |
+
print("ERROR: ZENODO_TOKEN missing. Keep it in your local environment only.", file=sys.stderr)
|
| 33 |
+
return 2
|
| 34 |
+
base = "https://sandbox.zenodo.org" if args.sandbox else "https://zenodo.org"
|
| 35 |
+
headers = {"Content-Type": "application/json", "Authorization": f"Bearer {token}"}
|
| 36 |
+
root = Path(__file__).resolve().parent
|
| 37 |
+
metadata = json.loads((root / "zenodo_metadata.json").read_text(encoding="utf-8"))
|
| 38 |
+
r = requests.post(f"{base}/api/deposit/depositions", json={}, headers=headers, timeout=30)
|
| 39 |
+
r.raise_for_status()
|
| 40 |
+
deposition = r.json()
|
| 41 |
+
bucket_url = deposition["links"]["bucket"]
|
| 42 |
+
for fname in FILES:
|
| 43 |
+
path = root / fname
|
| 44 |
+
with path.open("rb") as fp:
|
| 45 |
+
put = requests.put(f"{bucket_url}/{fname}", data=fp, headers={"Authorization": f"Bearer {token}"}, timeout=120)
|
| 46 |
+
put.raise_for_status()
|
| 47 |
+
m = requests.put(deposition["links"]["self"], json=metadata, headers=headers, timeout=30)
|
| 48 |
+
m.raise_for_status()
|
| 49 |
+
if args.publish:
|
| 50 |
+
p = requests.post(deposition["links"]["publish"], headers={"Authorization": f"Bearer {token}"}, timeout=30)
|
| 51 |
+
p.raise_for_status()
|
| 52 |
+
print(json.dumps(p.json(), indent=2))
|
| 53 |
+
else:
|
| 54 |
+
print(json.dumps({"draft": deposition.get("links", {}).get("html"), "deposition_id": deposition.get("id")}, indent=2))
|
| 55 |
+
return 0
|
| 56 |
+
|
| 57 |
+
if __name__ == "__main__":
|
| 58 |
+
raise SystemExit(main())
|