This commit is contained in:
Karol Wypchlo 2021-10-01 14:35:54 +02:00
parent cd35522cc1
commit 229b9ab888
No known key found for this signature in database
GPG Key ID: C92C016317A964D0
9 changed files with 33 additions and 66 deletions

View File

@ -218,5 +218,5 @@ services:
networks: networks:
shared: shared:
ipv4_address: 10.10.10.59 ipv4_address: 10.10.10.59
ports: expose:
- "27017:27017" - 27017

View File

@ -0,0 +1,2 @@
dist
package.json

View File

@ -0,0 +1,3 @@
{
"printWidth": 120
}

View File

@ -28,6 +28,7 @@
"@types/got": "9.6.12", "@types/got": "9.6.12",
"@types/mime-types": "2.1.1", "@types/mime-types": "2.1.1",
"@types/node": "16.9.2", "@types/node": "16.9.2",
"prettier": "^2.4.1",
"rimraf": "3.0.2", "rimraf": "3.0.2",
"ts-node": "10.2.1", "ts-node": "10.2.1",
"tslint": "6.1.3", "tslint": "6.1.3",

View File

@ -2,6 +2,7 @@ export const API_HOSTNAME = "0.0.0.0";
export const API_PORT = "3100"; export const API_PORT = "3100";
export const UPLOAD_PATH = "/tmp"; export const UPLOAD_PATH = "/tmp";
export const IPFS_INFURA_API = "https://ipfs.infura.io:5001"; export const IPFS_INFURA_API = "https://ipfs.infura.io:5001";
export const IPFS_INTERNAL_API = "http://10.10.10.57:5001";
export const IPFS_GATEWAY = "https://cloudflare-ipfs.com/ipfs/"; export const IPFS_GATEWAY = "https://cloudflare-ipfs.com/ipfs/";
export const SKYNET_PORTAL = "https://siasky.net"; export const SKYNET_PORTAL = "https://siasky.net";
export const MONGO_CONNECTIONSTRING = `mongodb://${process.env.IPFS_MONGO_USERNAME}:${process.env.IPFS_MONGO_PASSWORD}@ipfs-mongo:27017`; export const MONGO_CONNECTIONSTRING = `mongodb://${process.env.IPFS_MONGO_USERNAME}:${process.env.IPFS_MONGO_PASSWORD}@ipfs-mongo:27017`;

View File

@ -1,19 +1,10 @@
import { import { Collection, CreateIndexesOptions, Db, MongoClient, MongoClientOptions } from "mongodb";
Collection,
CreateIndexesOptions,
Db,
MongoClient,
MongoClientOptions,
} from "mongodb";
export class MongoDB { export class MongoDB {
private db: Db; private db: Db;
private client: MongoClient; private client: MongoClient;
public constructor( public constructor(private connectionString: string, private databaseName: string) {}
private connectionString: string,
private databaseName: string
) {}
public async connect() { public async connect() {
const options: MongoClientOptions = { const options: MongoClientOptions = {
@ -27,9 +18,7 @@ export class MongoDB {
this.db = this.client.db(this.databaseName); this.db = this.client.db(this.databaseName);
} }
public async createCollection<T>( public async createCollection<T>(collectionName: string): Promise<Collection<T>> {
collectionName: string
): Promise<Collection<T>> {
return await this.db.createCollection<T>(collectionName); return await this.db.createCollection<T>(collectionName);
} }
@ -37,12 +26,8 @@ export class MongoDB {
await this.db.dropCollection(collectionName); await this.db.dropCollection(collectionName);
} }
public async ensureCollection<T>( public async ensureCollection<T>(collectionName: string): Promise<Collection<T>> {
collectionName: string const collections = await this.db.listCollections({ name: collectionName }).toArray();
): Promise<Collection<T>> {
const collections = await this.db
.listCollections({ name: collectionName })
.toArray();
const collection = collections.length const collection = collections.length
? (this.db.collection(collectionName) as Collection<T>) ? (this.db.collection(collectionName) as Collection<T>)
@ -51,19 +36,13 @@ export class MongoDB {
return collection; return collection;
} }
public async ensureIndex( public async ensureIndex(collectionName: string, fieldOrSpec: any, options?: CreateIndexesOptions): Promise<string> {
collectionName: string,
fieldOrSpec: any,
options?: CreateIndexesOptions
): Promise<string> {
const collection = await this.ensureCollection(collectionName); const collection = await this.ensureCollection(collectionName);
const ensured = await collection.createIndex(fieldOrSpec, options); const ensured = await collection.createIndex(fieldOrSpec, options);
return ensured; return ensured;
} }
public async getCollection<T>( public async getCollection<T>(collectionName: string): Promise<Collection<T>> {
collectionName: string
): Promise<Collection<T>> {
return this.ensureCollection<T>(collectionName); return this.ensureCollection<T>(collectionName);
} }
} }

View File

@ -1,25 +1,13 @@
import cors from "cors"; import cors from "cors";
import express, { Request, Response } from "express"; import express, { Request, Response } from "express";
import fs from "fs"; import fs from "fs";
import got from "got";
import { extension as toExtension } from "mime-types"; import { extension as toExtension } from "mime-types";
import { Collection } from "mongodb"; import { Collection } from "mongodb";
import { import { API_HOSTNAME, API_PORT, MONGO_CONNECTIONSTRING, MONGO_DBNAME, UPLOAD_PATH, IPFS_INTERNAL_API } from "./consts";
API_HOSTNAME,
API_PORT,
MONGO_CONNECTIONSTRING,
MONGO_DBNAME,
UPLOAD_PATH,
} from "./consts";
import { MongoDB } from "./mongodb"; import { MongoDB } from "./mongodb";
import { IRecord } from "./types"; import { IRecord } from "./types";
import { import { contentType, download, extractArchive, isDirectory, uploadDirectory, uploadFile } from "./utils";
contentType,
download,
extractArchive,
isDirectory,
uploadDirectory,
uploadFile,
} from "./utils";
require("dotenv").config(); require("dotenv").config();
@ -46,17 +34,17 @@ require("dotenv").config();
return handleGetLink(req, res, recordsDB); return handleGetLink(req, res, recordsDB);
}); });
app.get("/ipfs/name/resolve/:name", async (req: Request, res: Response) => {
return await got.post(`${IPFS_INTERNAL_API}/api/v0/name/resolve?arg=${req.params.name}`).json();
});
// start the server // start the server
app.listen(parseInt(API_PORT, 10), API_HOSTNAME, () => { app.listen(parseInt(API_PORT, 10), API_HOSTNAME, () => {
console.log(`IPFS to Skynet API listening at ${API_HOSTNAME}:${API_PORT}`); console.log(`IPFS to Skynet API listening at ${API_HOSTNAME}:${API_PORT}`);
}); });
})(); })();
async function handleGetLink( async function handleGetLink(req: Request, res: Response, recordsDB: Collection<IRecord>) {
req: Request,
res: Response,
recordsDB: Collection<IRecord>
) {
try { try {
const { cid } = req.params; const { cid } = req.params;
@ -84,10 +72,7 @@ async function handleGetLink(
} }
} }
async function reuploadFile( async function reuploadFile(cid: string, recordsDB: Collection<IRecord>): Promise<string> {
cid: string,
recordsDB: Collection<IRecord>
): Promise<string> {
// get the content type // get the content type
const ct = await contentType(cid); const ct = await contentType(cid);
const ext = toExtension(ct); const ext = toExtension(ct);

View File

@ -18,14 +18,8 @@ export async function isDirectory(cid: string): Promise<boolean> {
return Boolean(json["Links"].length); return Boolean(json["Links"].length);
} }
export async function download( export async function download(cid: string, destination: string, directory: boolean): Promise<boolean> {
cid: string, const url = directory ? `${IPFS_INFURA_API}/api/v0/get?arg=${cid}&archive=true` : `${IPFS_GATEWAY}/${cid}`;
destination: string,
directory: boolean
): Promise<boolean> {
const url = directory
? `${IPFS_INFURA_API}/api/v0/get?arg=${cid}&archive=true`
: `${IPFS_GATEWAY}/${cid}`;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const downloadStream = got.stream(url); const downloadStream = got.stream(url);
@ -50,10 +44,7 @@ export async function download(
export async function extractArchive(src: string, dst: string) { export async function extractArchive(src: string, dst: string) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
createReadStream(src) createReadStream(src).pipe(extract(dst)).on("finish", resolve).on("error", reject);
.pipe(extract(dst))
.on("finish", resolve)
.on("error", reject);
}); });
} }

View File

@ -1053,6 +1053,11 @@ post-me@^0.4.5:
resolved "https://registry.yarnpkg.com/post-me/-/post-me-0.4.5.tgz#6171b721c7b86230c51cfbe48ddea047ef8831ce" resolved "https://registry.yarnpkg.com/post-me/-/post-me-0.4.5.tgz#6171b721c7b86230c51cfbe48ddea047ef8831ce"
integrity sha512-XgPdktF/2M5jglgVDULr9NUb/QNv3bY3g6RG22iTb5MIMtB07/5FJB5fbVmu5Eaopowc6uZx7K3e7x1shPwnXw== integrity sha512-XgPdktF/2M5jglgVDULr9NUb/QNv3bY3g6RG22iTb5MIMtB07/5FJB5fbVmu5Eaopowc6uZx7K3e7x1shPwnXw==
prettier@^2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.4.1.tgz#671e11c89c14a4cfc876ce564106c4a6726c9f5c"
integrity sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==
proper-lockfile@^2.0.1: proper-lockfile@^2.0.1:
version "2.0.1" version "2.0.1"
resolved "https://registry.yarnpkg.com/proper-lockfile/-/proper-lockfile-2.0.1.tgz#159fb06193d32003f4b3691dd2ec1a634aa80d1d" resolved "https://registry.yarnpkg.com/proper-lockfile/-/proper-lockfile-2.0.1.tgz#159fb06193d32003f4b3691dd2ec1a634aa80d1d"