Skip to content

Commit 711e80f

Browse files
author
art.tseng
committed
Initial commit: fxhash articles backup tool
CLI: python fxhash_backup.py <username> GitHub Actions: workflow_dispatch with username input, uploads zip artifact
0 parents  commit 711e80f

6 files changed

Lines changed: 913 additions & 0 deletions

File tree

.github/workflows/backup.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: Backup fxhash articles
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
username:
7+
description: "fxhash username (e.g. aquaponics.kana)"
8+
required: true
9+
type: string
10+
11+
permissions:
12+
contents: read
13+
14+
jobs:
15+
backup:
16+
runs-on: ubuntu-latest
17+
timeout-minutes: 30
18+
steps:
19+
- name: Checkout
20+
uses: actions/checkout@v4
21+
22+
- name: Set up Python
23+
uses: actions/setup-python@v5
24+
with:
25+
python-version: "3.12"
26+
27+
- name: Install dependencies
28+
run: |
29+
python -m pip install --upgrade pip
30+
pip install -r requirements.txt
31+
32+
- name: Run backup
33+
run: |
34+
mkdir -p out
35+
python fxhash_backup.py "${{ inputs.username }}" --output-dir out
36+
37+
- name: Upload zip
38+
uses: actions/upload-artifact@v4
39+
with:
40+
name: ${{ inputs.username }}-fxhash
41+
path: out/*.zip
42+
if-no-files-found: error
43+
retention-days: 30

.gitignore

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Python
2+
__pycache__/
3+
*.pyc
4+
.venv/
5+
venv/
6+
7+
# Build / output
8+
*.zip
9+
out/
10+
dist/
11+
12+
# OS / editor
13+
.DS_Store
14+
Thumbs.db
15+
.vscode/
16+
.idea/

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 javaing
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.

README.md

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# fxhash-articles-backup
2+
3+
Back up any fxhash author's articles into a single self-contained zip — ready
4+
to deploy as a static site on Cloudflare Pages, Netlify, GitHub Pages, etc.
5+
6+
The output zip contains:
7+
8+
- `index.html` — landing page listing every article, newest first
9+
- `posts/<date>-<slug>.html` — each article rendered as standalone HTML
10+
- `assets/` — article cover thumbnails, inline images / videos, and NFT
11+
embed thumbnails, all downloaded from IPFS
12+
- `manifest.json` — machine-readable index of every article (includes
13+
IPFS hashes so the originals can always be located on-chain)
14+
- `style.css`, `README.md`, `AGENT.md` — site assets and deploy notes
15+
16+
It also handles the fxhash-specific markdown directives:
17+
18+
- `::tezos-storage-pointer[]{...}` (NFT embeds) → resolved via the fxhash
19+
GraphQL API (for fxhash projects) or the public TzKT API (for any other
20+
Tezos NFT), then rendered as a clickable thumbnail figure
21+
- `::video[]{src=...}` → rendered as a `<video controls>` tag
22+
23+
---
24+
25+
## Use it (two ways)
26+
27+
### A. GitHub Actions — easiest, no install needed
28+
29+
1. **Fork** this repository.
30+
2. Open the **Actions** tab on your fork. If prompted, enable workflows.
31+
3. Pick **Backup fxhash articles** in the left sidebar.
32+
4. Click **Run workflow**, type the fxhash username (e.g. `aquaponics.kana`),
33+
and **Run workflow** again.
34+
5. When the run finishes, scroll to the bottom of the run page and download
35+
the `<username>-fxhash` artifact. Inside is the zip you can drop into
36+
Cloudflare Pages / Netlify / GitHub Pages.
37+
38+
### B. Run locally
39+
40+
Requires Python 3.10+.
41+
42+
```bash
43+
git clone https://github.com/javaing/fxhash-articles-backup.git
44+
cd fxhash-articles-backup
45+
pip install -r requirements.txt
46+
python fxhash_backup.py <username>
47+
```
48+
49+
The zip is written to the current directory as `<username>-fxhash.zip`.
50+
51+
Optional flag:
52+
53+
```bash
54+
python fxhash_backup.py <username> --output-dir ./out
55+
```
56+
57+
---
58+
59+
## Deploy the zip
60+
61+
1. Unzip it.
62+
2. Open Cloudflare **Workers & Pages → Create → Pages → Upload assets**.
63+
3. Drag the unzipped folder in. Click **Deploy site**.
64+
65+
No Node.js, no build command, no GitHub repo on Cloudflare's side. The same
66+
folder works on Netlify (drag-drop) and GitHub Pages (commit + enable Pages).
67+
68+
---
69+
70+
## How it works
71+
72+
| Step | Source |
73+
| --- | --- |
74+
| Article list & body | fxhash GraphQL — `https://api.fxhash.xyz/graphql` |
75+
| Cover thumbnails & inline images | IPFS gateways (nftstorage, cloudflare, ipfs.io, dweb.link, cf-ipfs) |
76+
| fxhash NFT embed metadata | fxhash GraphQL `generativeToken(id:…)` |
77+
| Other Tezos NFT embed metadata | TzKT public API — `https://api.tzkt.io/v1/tokens` |
78+
79+
Everything the script touches is public; no API key or login required.
80+
81+
---
82+
83+
## Limitations
84+
85+
- The script saves a **representative thumbnail** for each NFT embedded in an
86+
article, not the live generative artifact. If the original NFT is removed
87+
from IPFS / the contract storage, the embed degrades to a link only.
88+
- IPFS gateways occasionally rate-limit. The script tries five gateways in
89+
sequence; transient failures are reported but don't stop the run.
90+
- Articles authored on multi-author / collab accounts are listed under
91+
whichever single author the fxhash GraphQL API exposes.
92+
93+
---
94+
95+
## License
96+
97+
MIT — see [LICENSE](LICENSE).
98+
99+
The articles you back up belong to their authors; this tool only makes a
100+
copy easier to host. Respect the original authors' wishes if they ask you
101+
to take a backup down.

0 commit comments

Comments
 (0)