Skip to content

Commit da434f7

Browse files
committed
Update 1.5.1 - Added a script and a workflow to fetch and update default data from the wiki API automatically
1 parent c226871 commit da434f7

File tree

2 files changed

+188
-0
lines changed

2 files changed

+188
-0
lines changed
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
import fs from 'fs';
2+
import path from 'path';
3+
import { fileURLToPath } from 'url';
4+
5+
const __filename = fileURLToPath(import.meta.url);
6+
const __dirname = path.dirname(__filename);
7+
8+
const apiPath = 'https://nomanssky.fandom.com/api.php';
9+
const MIN_REQUEST_INTERVAL = 35000; // 35 seconds between fetchs
10+
11+
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
12+
13+
const filterValidData = (data) => {
14+
return data.filter(item =>
15+
item.title.civilizeD &&
16+
item.title.civilizeD !== 'Uncharted' &&
17+
item.title.coordinateS &&
18+
item.title.galaxY &&
19+
item.title.pageName
20+
);
21+
};
22+
23+
const fetchCivilizationsPage = async (offset = 0) => {
24+
const params = new URLSearchParams();
25+
params.append('action', 'cargoquery');
26+
params.append('tables', 'Regions');
27+
params.append('fields', 'Regions.Civilized=civilizeD,Regions.Galaxy=galaxY,Regions.Coordinates=coordinateS,_pageName=pageName');
28+
params.append('group_by', '_pageName');
29+
params.append('order_by', '_pageName');
30+
params.append('limit', '500');
31+
params.append('offset', offset.toString());
32+
params.append('format', 'json');
33+
params.append('origin', '*');
34+
35+
const url = `${apiPath}?${params.toString()}`;
36+
console.log(`Fetching page with offset: ${offset}`);
37+
38+
const response = await fetch(url);
39+
if (!response.ok) {
40+
throw new Error(`HTTP error! status: ${response.status}`);
41+
}
42+
43+
const data = await response.json();
44+
return data.cargoquery || [];
45+
};
46+
47+
const fetchAllCivilizationsAndRegions = async () => {
48+
console.log('Starting data fetch...');
49+
let allData = [];
50+
let offset = 0;
51+
let hasMore = true;
52+
let requestCount = 0;
53+
54+
while (hasMore) {
55+
try {
56+
const pageData = await fetchCivilizationsPage(offset);
57+
const validPageData = filterValidData(pageData);
58+
59+
console.log(`Page ${requestCount + 1}: ${pageData.length} raw items, ${validPageData.length} valid items`);
60+
61+
if (pageData.length === 0) {
62+
hasMore = false;
63+
console.log('No more data available');
64+
} else {
65+
allData = allData.concat(validPageData);
66+
requestCount++;
67+
68+
console.log(`Total valid items so far: ${allData.length}`);
69+
70+
if (pageData.length < 50) {
71+
hasMore = false;
72+
console.log('Last page reached');
73+
} else {
74+
offset += 500;
75+
76+
if (hasMore) {
77+
console.log(`Waiting ${MIN_REQUEST_INTERVAL}ms before next request...`);
78+
await sleep(MIN_REQUEST_INTERVAL);
79+
}
80+
}
81+
}
82+
} catch (error) {
83+
console.error('Error fetching page:', error);
84+
throw error;
85+
}
86+
}
87+
88+
console.log(`Total valid items fetched: ${allData.length}`);
89+
90+
if (allData.length > 0) {
91+
const galaxies = [...new Set(
92+
allData.map(item => item.title.galaxY)
93+
)].filter(Boolean).sort();
94+
95+
const data = {};
96+
97+
galaxies.forEach(galaxy => {
98+
data[galaxy] = {
99+
civilizations: [],
100+
regions: {}
101+
};
102+
103+
const galaxyData = allData.filter(item => item.title.galaxY === galaxy);
104+
const civilizations = [...new Set(
105+
galaxyData.map(item => item.title.civilizeD)
106+
)].sort();
107+
108+
data[galaxy].civilizations = civilizations;
109+
110+
civilizations.forEach(civ => {
111+
data[galaxy].regions[civ] = galaxyData
112+
.filter(item => item.title.civilizeD === civ)
113+
.map(item => ({
114+
name: item.title.pageName,
115+
coordinates: item.title.coordinateS,
116+
}))
117+
.sort((a, b) => a.name.localeCompare(b.name));
118+
});
119+
});
120+
121+
return { galaxies, data };
122+
} else {
123+
throw new Error('No valid data could be fetched');
124+
}
125+
};
126+
127+
const main = async () => {
128+
try {
129+
console.log('=== Starting defaultData.json update ===');
130+
131+
const result = await fetchAllCivilizationsAndRegions();
132+
133+
const outputPath = path.join(__dirname, '../../public/assets/defaultData/defaultData.json');
134+
const outputDir = path.dirname(outputPath);
135+
136+
if (!fs.existsSync(outputDir)) {
137+
fs.mkdirSync(outputDir, { recursive: true });
138+
}
139+
140+
fs.writeFileSync(outputPath, JSON.stringify(result, null, 2));
141+
142+
console.log(`=== Data successfully saved to ${outputPath} ===`);
143+
console.log(`Total galaxies: ${result.galaxies.length}`);
144+
console.log(`Total civilizations: ${Object.values(result.data).reduce((sum, g) => sum + g.civilizations.length, 0)}`);
145+
146+
} catch (error) {
147+
console.error('=== Error updating data ===');
148+
console.error(error);
149+
process.exit(1);
150+
}
151+
};
152+
153+
main();
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Update Default Data
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
schedule:
8+
- cron: '0 3 * * 0'
9+
workflow_dispatch:
10+
11+
permissions:
12+
contents: write
13+
14+
jobs:
15+
update-data:
16+
runs-on: ubuntu-latest
17+
18+
steps:
19+
- name: Checkout repository
20+
uses: actions/checkout@v5
21+
22+
- name: Setup Node.js
23+
uses: actions/setup-node@v6
24+
with:
25+
node-version: 'lts'
26+
cache: 'npm'
27+
28+
- name: Fetch and update data
29+
run: node .github/scripts/update-default-data.js
30+
31+
- name: Commit and push if changed
32+
uses: stefanzweifel/git-auto-commit-action@v5
33+
with:
34+
commit_message: "chore: update defaultData.json [automated]"
35+
file_pattern: public/assets/defaultData/defaultData.json

0 commit comments

Comments
 (0)