1
0
Fork 0

Add geotags, post to nostr

This commit is contained in:
Sjors Provoost 2024-08-31 23:09:58 +02:00
parent 4e1c42f3a7
commit 950de7f769
Signed by: sjors
GPG key ID: 57FF9BDBCC301009
3 changed files with 73 additions and 16 deletions

View file

@ -1,6 +1,7 @@
{ {
"imports": { "imports": {
"@nostrify/nostrify": "jsr:@nostrify/nostrify@^0.30.1", "@nostrify/nostrify": "jsr:@nostrify/nostrify@^0.30.1",
"nostr-geotags": "npm:nostr-geotags@^0.7.1",
"nostr-tools": "npm:nostr-tools@^2.7.2" "nostr-tools": "npm:nostr-tools@^2.7.2"
} }
} }

View file

@ -12,6 +12,7 @@
"npm:@scure/bip32@^1.4.0": "npm:@scure/bip32@1.4.0", "npm:@scure/bip32@^1.4.0": "npm:@scure/bip32@1.4.0",
"npm:@scure/bip39@^1.3.0": "npm:@scure/bip39@1.3.0", "npm:@scure/bip39@^1.3.0": "npm:@scure/bip39@1.3.0",
"npm:lru-cache@^10.2.0": "npm:lru-cache@10.4.3", "npm:lru-cache@^10.2.0": "npm:lru-cache@10.4.3",
"npm:nostr-geotags@^0.7.1": "npm:nostr-geotags@0.7.1",
"npm:nostr-tools@^2.7.0": "npm:nostr-tools@2.7.2", "npm:nostr-tools@^2.7.0": "npm:nostr-tools@2.7.2",
"npm:nostr-tools@^2.7.2": "npm:nostr-tools@2.7.2", "npm:nostr-tools@^2.7.2": "npm:nostr-tools@2.7.2",
"npm:websocket-ts@^2.1.5": "npm:websocket-ts@2.1.5", "npm:websocket-ts@^2.1.5": "npm:websocket-ts@2.1.5",
@ -122,10 +123,25 @@
"@scure/base": "@scure/base@1.1.7" "@scure/base": "@scure/base@1.1.7"
} }
}, },
"iso-3166@4.3.0": {
"integrity": "sha512-H4kM/sVbxTjSl9xnQCYOrNWdpN0R8Uz26j1BuXI9E6U+kw5wmd3HyPgr/v4+NCuvV/NcvwTfZxd5XZ4lPKvBNA==",
"dependencies": {}
},
"lru-cache@10.4.3": { "lru-cache@10.4.3": {
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
"dependencies": {} "dependencies": {}
}, },
"ngeohash@0.6.3": {
"integrity": "sha512-kltF0cOxgx1AbmVzKxYZaoB0aj7mOxZeHaerEtQV0YaqnkXNq26WWqMmJ6lTqShYxVRWZ/mwvvTrNeOwdslWiw==",
"dependencies": {}
},
"nostr-geotags@0.7.1": {
"integrity": "sha512-3xnmDUqTP7MzWLmaJvTgWYwlex3yYGmKi6qAEOHRrh+gZs26YEqECe5yalRH0i4rBZXNXDfkiZs/gvRts6eoAQ==",
"dependencies": {
"iso-3166": "iso-3166@4.3.0",
"ngeohash": "ngeohash@0.6.3"
}
},
"nostr-tools@2.7.2": { "nostr-tools@2.7.2": {
"integrity": "sha512-Bq3Ug0SZFtgtL1+0wCnAe8AJtI7yx/00/a2nUug9SkhfOwlKS92Tef12iCK9FdwXw+oFZWMtRnSwcLayQso+xA==", "integrity": "sha512-Bq3Ug0SZFtgtL1+0wCnAe8AJtI7yx/00/a2nUug9SkhfOwlKS92Tef12iCK9FdwXw+oFZWMtRnSwcLayQso+xA==",
"dependencies": { "dependencies": {
@ -192,6 +208,7 @@
"workspace": { "workspace": {
"dependencies": [ "dependencies": [
"jsr:@nostrify/nostrify@^0.30.1", "jsr:@nostrify/nostrify@^0.30.1",
"npm:nostr-geotags@^0.7.1",
"npm:nostr-tools@^2.7.2" "npm:nostr-tools@^2.7.2"
] ]
} }

71
main.ts
View file

@ -10,6 +10,8 @@ import { BlossomUploader } from '@nostrify/nostrify/uploaders';
import * as nip19 from 'nostr-tools/nip19' import * as nip19 from 'nostr-tools/nip19'
import ngeotags from 'nostr-geotags';
console.log("\nUse at your own risk!\n"); console.log("\nUse at your own risk!\n");
console.log("Considering trying it out with a throwaway nsec."); console.log("Considering trying it out with a throwaway nsec.");
console.log("All data will be public. Anything you upload is hard to delete.\n"); console.log("All data will be public. Anything you upload is hard to delete.\n");
@ -24,14 +26,12 @@ for (const i in posts) {
const post = posts[i] const post = posts[i]
} }
console.log("You can try one picture at a time, duplicates are skipped the next run."); console.log("You can try one picture at a time");
const offset = Number(prompt("Skip how many posts?", 0));
const n = Number(prompt("How many do you want to upload?", posts.length)); const n = Number(prompt("How many do you want to upload?", posts.length - offset));
if (n == 0) { Deno.exit(0); } if (n == 0) { Deno.exit(0); }
assert(n > 0); assert(n > 0);
assert(n <= posts.length); assert(n <= posts.length - offset);
const nsec_str = Deno.env.get("NSEC") || prompt("\nPlease enter your nsec:"); const nsec_str = Deno.env.get("NSEC") || prompt("\nPlease enter your nsec:");
@ -54,13 +54,11 @@ const relay = new NRelay1(relay_str);
console.log("\nAs a sanity check, here's your last message (if any):"); console.log("\nAs a sanity check, here's your last message (if any):");
for await (const msg of relay.req([{ kinds: [1], limit: 1, authors: [pubkey_hex] }])) { for await (const msg of relay.req([{ kinds: [1], limit: 960, authors: [pubkey_hex] }])) {
if (msg[0] === 'EVENT') console.log(msg[2].content); if (msg[0] === 'EVENT') console.log(msg[2].content);
if (msg[0] === 'EOSE') break; if (msg[0] === 'EOSE') break;
} }
await relay.close()
// TODO: suggest public (free or paid) Blossom servers, allow multiple // TODO: suggest public (free or paid) Blossom servers, allow multiple
const blossom_url = Deno.env.get("BLOSSOM") || prompt("Enter Blossom server URL:", "https://blossom.primal.net/"); const blossom_url = Deno.env.get("BLOSSOM") || prompt("Enter Blossom server URL:", "https://blossom.primal.net/");
@ -75,6 +73,7 @@ let completed = 0;
let events = []; let events = [];
for (const i in posts) { for (const i in posts) {
if (i < offset) continue;
const post = posts[i] const post = posts[i]
console.log(post); console.log(post);
@ -91,6 +90,9 @@ for (const i in posts) {
message = post.title + "\n"; message = post.title + "\n";
} }
// Populated from the first media item with coordinates
let geotags;
let first = true; let first = true;
for (const j in post.media) { for (const j in post.media) {
const media = post.media[j]; const media = post.media[j];
@ -112,6 +114,12 @@ for (const i in posts) {
if (media.uri.slice(-5) == ".webp") { if (media.uri.slice(-5) == ".webp") {
blob = new Blob([data], {type: 'image/webp'}); blob = new Blob([data], {type: 'image/webp'});
extension = ".webp" extension = ".webp"
} else if (media.uri.slice(-4) == ".jpg") {
blob = new Blob([data], {type: 'image/jpeg'});
extension = ".jpg"
} else if (media.uri.slice(-4) == ".mp4") {
blob = new Blob([data], {type: 'video/mp4'});
extension = ".mp4"
} else if (!media.uri.includes(".")) { } else if (!media.uri.includes(".")) {
// Assume it's an mp4 movie // Assume it's an mp4 movie
blob = new Blob([data], {type: 'video/mp4'}); blob = new Blob([data], {type: 'video/mp4'});
@ -122,21 +130,49 @@ for (const i in posts) {
console.log(post); console.log(post);
Deno.exit(1); Deno.exit(1);
} }
// TODO: if upload fails, log something useful
// * e.g. file size (might be over the upload limit)
const tags = await uploader.upload(blob); const tags = await uploader.upload(blob);
if (extension == ".mp4") {
console.log(tags);
}
// add URL to message (plus extension) // add URL to message (plus extension)
message += tags[0][1] + extension message += tags[0][1] + extension
// TODO: get city? if (geotags == undefined && media.media_metadata && media.media_metadata.photo_metadata) {
const options = {
geohash: true,
gps: true,
city: false,
iso31662: false,
iso31662: false,
iso31663: false
};
let exif_data = media.media_metadata.photo_metadata.exif_data;
if (exif_data) {
for (const k in exif_data) {
const exif_item = exif_data[k];
if (exif_item.latitude != undefined && exif_item.latitude != undefined) {
geotags = ngeotags({
lat: exif_item.latitude,
lon: exif_item.longitude
}, options);
}
}
}
}
} }
// Generate Nostr event // Generate Nostr event
const event = await signer.signEvent({ kind: 1, content: message, tags: [], created_at: created_at}); let event = {
kind: 1,
content: message,
tags: [],
created_at: created_at
}
if (geotags != undefined) {
event.tags = [...event.tags, ...geotags];
}
const signed_event = await signer.signEvent(event);
console.log(event); console.log(event);
events.push(event); events.push(event);
@ -147,7 +183,10 @@ for (const i in posts) {
alert("About to post to Nostr."); alert("About to post to Nostr.");
for (const event in events) { for (const event in events) {
await relay.event(event); console.log(event);
console.log(await relay.event(event));
} }
await relay.close()
console.log("Done!"); console.log("Done!");