aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--174bg/discord-bot/commands/pocketbase.js341
1 files changed, 291 insertions, 50 deletions
diff --git a/174bg/discord-bot/commands/pocketbase.js b/174bg/discord-bot/commands/pocketbase.js
index 8b97822..91b35c3 100644
--- a/174bg/discord-bot/commands/pocketbase.js
+++ b/174bg/discord-bot/commands/pocketbase.js
@@ -16,6 +16,21 @@ export default {
.setName("uex_items")
.setDescription("Populates the uex_items collection with data from the bot's UEX cache.")
)
+ .addSubcommand((subcommand) =>
+ subcommand
+ .setName("uex_space_stations")
+ .setDescription("Populates the uex_space_stations collection with data from the bot's UEX cache.")
+ )
+ .addSubcommand((subcommand) =>
+ subcommand
+ .setName("uex_points_of_interest")
+ .setDescription("Populates the uex_points_of_interest collection with data from the bot's UEX cache.")
+ )
+ .addSubcommand((subcommand) =>
+ subcommand
+ .setName("inventory_locations")
+ .setDescription("Populates the inventory_locations collection with data from the bot's UEX cache.")
+ )
),
execute: async (interaction) => {
// only zuedev can run any of these commands
@@ -28,64 +43,290 @@ export default {
const subcommand = interaction.options.getSubcommand();
if (subcommandGroup === "populate") {
- if (subcommand === "uex_items") {
- const pb = new PocketBase(process.env.POCKETBASE_URL);
- pb.authStore.save(process.env.POCKETBASE_AUTH_TOKEN, null);
+ switch (subcommand) {
+ case "uex_items":
+ populateUexItems(interaction);
+ break;
+ case "uex_space_stations":
+ populateUexSpaceStations(interaction);
+ break;
+ case "uex_points_of_interest":
+ populateUexPointsOfInterest(interaction);
+ break;
+ case "inventory_locations":
+ populateInventoryLocations(interaction);
+ break;
+ }
+ }
+ },
+};
+
+async function populateUexItems(interaction) {
+ const pb = new PocketBase(process.env.POCKETBASE_URL);
+ pb.authStore.save(process.env.POCKETBASE_AUTH_TOKEN, null);
+
+ const items = uex.items ?? [];
- interaction.reply({
- content: `Populating uex_items collection with ${uex.items.length} items...`,
+ interaction.reply({
+ content: `Populating uex_items collection with ${items.length} items...`,
+ ephemeral: true,
+ });
+
+ let ops = 0;
+ let failed = 0;
+ let updates = 0;
+ let creates = 0;
+
+ for (const item of items) {
+ try {
+ // does it already exist?
+ const existingItem = await pb.collection("uex_items").getFullList({
+ filter: `id="${item.id}"`,
+ });
+
+ if (existingItem.length > 0) {
+ // compare times to see if we need to update
+ // example pocketbase: "2026-07-18 12:30:02.405Z"
+ // example uex: 1746219762
+ if (new Date(existingItem[0].updated).getTime() < item.updated * 1000) {
+ await pb.collection("uex_items").update(existingItem[0].id, {
+ name: item.name,
+ });
+ updates++;
+ }
+ } else {
+ await pb.collection("uex_items").create({
+ id: item.id,
+ name: item.name,
+ });
+ creates++;
+ }
+ ops++;
+
+ // update the interaction every 1000 operations to avoid timeout
+ if (ops % 1000 === 0) {
+ interaction.editReply({
+ content: `Populating uex_items collection with ${items.length} items... (${ops} processed, ${updates} updated, ${creates} created, ${failed} failed)`,
ephemeral: true,
});
+ }
+ } catch (error) {
+ console.error(`Failed to create item ${item.name}:`, error);
+ failed++;
+ }
+ }
+
+ interaction.editReply({
+ content: `Successfully populated uex_items collection with ${items.length} items. (${ops} processed, ${updates} updated, ${creates} created, ${failed} failed)`,
+ ephemeral: true,
+ });
+}
+
+async function populateUexSpaceStations(interaction) {
+ const pb = new PocketBase(process.env.POCKETBASE_URL);
+ pb.authStore.save(process.env.POCKETBASE_AUTH_TOKEN, null);
+
+ const stations = uex.space_stations ?? [];
+
+ interaction.reply({
+ content: `Populating uex_space_stations collection with ${stations.length} stations...`,
+ ephemeral: true,
+ });
+
+ let ops = 0;
+ let failed = 0;
+ let updates = 0;
+ let creates = 0;
- let ops = 0;
- let failed = 0;
- let updates = 0;
- let creates = 0;
-
- for (const item of uex.items) {
- try {
- // does it already exist?
- const existingItem = await pb.collection("uex_items").getFullList({
- filter: `id="${item.id}"`,
- });
-
- if (existingItem.length > 0) {
- // compare times to see if we need to update
- // example pocketbase: "2026-07-18 12:30:02.405Z"
- // example uex: 1746219762
- if (new Date(existingItem[0].updated).getTime() < item.updated * 1000) {
- await pb.collection("uex_items").update(existingItem[0].id, {
- name: item.name,
- });
- updates++;
- }
- } else {
- await pb.collection("uex_items").create({
- id: item.id,
- name: item.name,
- });
- creates++;
- }
- ops++;
-
- // update the interaction every 1000 operations to avoid timeout
- if (ops % 1000 === 0) {
- interaction.editReply({
- content: `Populating uex_items collection with ${uex.items.length} items... (${ops} processed, ${updates} updated, ${creates} created, ${failed} failed)`,
- ephemeral: true,
- });
- }
- } catch (error) {
- console.error(`Failed to create item ${item.name}:`, error);
- failed++;
- }
+ for (const station of stations) {
+ try {
+ // does it already exist?
+ const existingStation = await pb.collection("uex_space_stations").getFullList({
+ filter: `id="${station.id}"`,
+ });
+
+ if (existingStation.length > 0) {
+ // compare times to see if we need to update
+ // example pocketbase: "2026-07-18 12:30:02.405Z"
+ // example uex: 1746219762
+ if (new Date(existingStation[0].updated).getTime() < station.updated * 1000) {
+ await pb.collection("uex_space_stations").update(existingStation[0].id, {
+ name: station.name,
+ });
+ updates++;
}
+ } else {
+ await pb.collection("uex_space_stations").create({
+ id: station.id,
+ name: station.name,
+ });
+ creates++;
+ }
+ ops++;
+ // update the interaction every 1000 operations to avoid timeout
+ if (ops % 1000 === 0) {
interaction.editReply({
- content: `Successfully populated uex_items collection with ${uex.items.length} items. (${ops} processed, ${updates} updated, ${creates} created, ${failed} failed)`,
+ content: `Populating uex_space_stations collection with ${stations.length} stations... (${ops} processed, ${updates} updated, ${creates} created, ${failed} failed)`,
ephemeral: true,
});
}
+ } catch (error) {
+ console.error(`Failed to create space station ${station.name}:`, error);
+ failed++;
}
- },
-};
+ }
+
+ interaction.editReply({
+ content: `Successfully populated uex_space_stations collection with ${stations.length} stations. (${ops} processed, ${updates} updated, ${creates} created, ${failed} failed)`,
+ ephemeral: true,
+ });
+}
+
+async function populateUexPointsOfInterest(interaction) {
+ const pb = new PocketBase(process.env.POCKETBASE_URL);
+ pb.authStore.save(process.env.POCKETBASE_AUTH_TOKEN, null);
+
+ const pointsOfInterest = uex.points_of_interest ?? [];
+
+ interaction.reply({
+ content: `Populating uex_points_of_interest collection with ${pointsOfInterest.length} points of interest...`,
+ ephemeral: true,
+ });
+
+ let ops = 0;
+ let failed = 0;
+ let updates = 0;
+ let creates = 0;
+
+ for (const point of pointsOfInterest) {
+ try {
+ // does it already exist?
+ const existingPoint = await pb.collection("uex_points_of_interest").getFullList({
+ filter: `name="${point.name}"`,
+ });
+
+ if (existingPoint.length > 0) {
+ await pb.collection("uex_points_of_interest").update(existingPoint[0].id, {
+ name: point.name,
+ });
+ updates++;
+ } else {
+ await pb.collection("uex_points_of_interest").create({
+ id: point.id,
+ name: point.name,
+ });
+ creates++;
+ }
+ ops++;
+
+ // update the interaction every 1000 operations to avoid timeout
+ if (ops % 1000 === 0) {
+ interaction.editReply({
+ content: `Populating uex_points_of_interest collection with ${pointsOfInterest.length} points of interest... (${ops} processed, ${updates} updated, ${creates} created, ${failed} failed)`,
+ ephemeral: true,
+ });
+ }
+ } catch (error) {
+ console.error(`Failed to create point of interest ${point.name}:`, error);
+ failed++;
+ }
+ }
+
+ interaction.editReply({
+ content: `Successfully populated uex_points_of_interest collection with ${pointsOfInterest.length} points of interest. (${ops} processed, ${updates} updated, ${creates} created, ${failed} failed)`,
+ ephemeral: true,
+ });
+}
+
+async function populateInventoryLocations(interaction) {
+ const pb = new PocketBase(process.env.POCKETBASE_URL);
+ pb.authStore.save(process.env.POCKETBASE_AUTH_TOKEN, null);
+
+ const stations = uex.space_stations ?? [];
+ const pointsOfInterest = uex.points_of_interest ?? [];
+
+ // merge + dedupe by name (case-insensitive)
+ const locationMap = new Map();
+
+ for (const station of stations) {
+ if (!station?.name) continue;
+ const key = station.name.trim().toLowerCase();
+ locationMap.set(key, {
+ id: station.id,
+ name: station.name,
+ updated: station.updated ?? 0,
+ });
+ }
+
+ for (const point of pointsOfInterest) {
+ if (!point?.name) continue;
+ const key = point.name.trim().toLowerCase();
+ const existing = locationMap.get(key);
+
+ // keep whichever has the newest timestamp when duplicates exist
+ if (!existing || (point.updated ?? 0) > (existing.updated ?? 0)) {
+ locationMap.set(key, {
+ id: point.id,
+ name: point.name,
+ updated: point.updated ?? 0,
+ });
+ }
+ }
+
+ const locations = Array.from(locationMap.values());
+
+ interaction.reply({
+ content: `Populating inventory_locations collection with ${locations.length} locations...`,
+ ephemeral: true,
+ });
+
+ let ops = 0;
+ let failed = 0;
+ let updates = 0;
+ let creates = 0;
+
+ for (const location of locations) {
+ try {
+ const safeName = String(location.name).replaceAll('"', '\\"');
+
+ const existingLocation = await pb.collection("inventory_locations").getFullList({
+ filter: `name="${safeName}"`,
+ });
+
+ if (existingLocation.length > 0) {
+ const pbUpdated = new Date(existingLocation[0].updated).getTime();
+ const uexUpdated = (location.updated ?? 0) * 1000;
+
+ if (pbUpdated < uexUpdated) {
+ await pb.collection("inventory_locations").update(existingLocation[0].name, {
+ name: location.name,
+ });
+ updates++;
+ }
+ } else {
+ await pb.collection("inventory_locations").create({
+ name: location.name,
+ });
+ creates++;
+ }
+
+ ops++;
+
+ if (ops % 1000 === 0) {
+ interaction.editReply({
+ content: `Populating inventory_locations collection with ${locations.length} locations... (${ops} processed, ${updates} updated, ${creates} created, ${failed} failed)`,
+ ephemeral: true,
+ });
+ }
+ } catch (error) {
+ console.error(`Failed to create inventory location ${location?.name}:`, error);
+ failed++;
+ }
+ }
+
+ interaction.editReply({
+ content: `Successfully populated inventory_locations collection with ${locations.length} locations. (${ops} processed, ${updates} updated, ${creates} created, ${failed} failed)`,
+ ephemeral: true,
+ });
+} \ No newline at end of file