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": {
"@nostrify/nostrify": "jsr:@nostrify/nostrify@^0.30.1",
"nostr-geotags": "npm:nostr-geotags@^0.7.1",
"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/bip39@^1.3.0": "npm:@scure/bip39@1.3.0",
"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.2": "npm:nostr-tools@2.7.2",
"npm:websocket-ts@^2.1.5": "npm:websocket-ts@2.1.5",
@ -122,10 +123,25 @@
"@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": {
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
"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": {
"integrity": "sha512-Bq3Ug0SZFtgtL1+0wCnAe8AJtI7yx/00/a2nUug9SkhfOwlKS92Tef12iCK9FdwXw+oFZWMtRnSwcLayQso+xA==",
"dependencies": {
@ -192,6 +208,7 @@
"workspace": {
"dependencies": [
"jsr:@nostrify/nostrify@^0.30.1",
"npm:nostr-geotags@^0.7.1",
"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 ngeotags from 'nostr-geotags';
console.log("\nUse at your own risk!\n");
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");
@ -24,14 +26,12 @@ for (const i in posts) {
const post = posts[i]
}
console.log("You can try one picture at a time, duplicates are skipped the next run.");
const n = Number(prompt("How many do you want to upload?", posts.length));
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 - offset));
if (n == 0) { Deno.exit(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:");
@ -54,13 +54,11 @@ const relay = new NRelay1(relay_str);
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] === 'EOSE') break;
}
await relay.close()
// 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/");
@ -75,6 +73,7 @@ let completed = 0;
let events = [];
for (const i in posts) {
if (i < offset) continue;
const post = posts[i]
console.log(post);
@ -91,6 +90,9 @@ for (const i in posts) {
message = post.title + "\n";
}
// Populated from the first media item with coordinates
let geotags;
let first = true;
for (const j in post.media) {
const media = post.media[j];
@ -112,6 +114,12 @@ for (const i in posts) {
if (media.uri.slice(-5) == ".webp") {
blob = new Blob([data], {type: 'image/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(".")) {
// Assume it's an mp4 movie
blob = new Blob([data], {type: 'video/mp4'});
@ -122,21 +130,49 @@ for (const i in posts) {
console.log(post);
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);
if (extension == ".mp4") {
console.log(tags);
}
// add URL to message (plus 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
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);
events.push(event);
@ -147,7 +183,10 @@ for (const i in posts) {
alert("About to post to Nostr.");
for (const event in events) {
await relay.event(event);
console.log(event);
console.log(await relay.event(event));
}
await relay.close()
console.log("Done!");