rawnly / splash-cli

A simple, CLI to download Unsplash wallpapers. Nothing fancy — it just works.
http://splash-cli.app?ref=github
546 stars 28 forks source link

Photos Upload #47

Closed rawnly closed 4 years ago

rawnly commented 5 years ago

I've wrote the following script to upload photos to unsplash via nodejs but doesn't seems to work correctly.

The process is:

  1. Get a signed url from S3
  2. Make a put with the binary of the image (the upload process)
  3. Then finally add the image to the current user.

Link to the gist

rawnly commented 5 years ago

Gist Code

/*
* READ BEFORE COPY-PASTING THIS FILE
* - The following script is buggy
* - This will not work, it has been tested on May 14th 2019 and the server response is 403.
* - PR are welcome if someone has any workaround/solution.
*/

const fs = require("fs");
const fetch = require("isomorphic-fetch");
const path = require("path");
const os = require("os");
const { URL } = require("url");
const getImageSize = require("image-size");

const BEAERER_TOKEN = process.env.BEARER_TOKEN || "hardcoded-token"

const getSignedURL = async () => {
    console.log("Getting signed URL");
    const url = new URL("https://unsplash.com/napi/photos/presigned_url");

    try {
        const response = await fetch(url.href, {
            method: "GET",
        });

        if (!response.ok) {
            console.error(response.status);
            return false;
        }

        const data = await response.json();

        return data.presigned_url;
    } catch (error) {
        console.error(error);
        return false;
    }
};

const uploadToS3 = async (pathToFile, presigned_url) => {
    console.log("Uploading to S3");
    const url = new URL(presigned_url);
    const file = fs.readFileSync(pathToFile);
    const filesize = fs.statSync(pathToFile).size;
    const { width, height, type } = getImageSize(file);
    const filepath = url.pathname;
    const filetype = `image/${type}`;
    const binaryData = file.toString("binary");

    const API_DATA = {
        width,
        height,
        filepath,
        filetype,
        filesize,
    };

    try {
        const response = await fetch(url.href, {
            method: "PUT",
            body: binaryData,
            headers: {
                Refer: "https://unsplash.com/",
                Origin: "https://unsplash.com/",
                "User-Aagent":
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36",
                DNT: 1,
                "Content-Type": filetype,
            },
        });

        if (!response.ok) {
            console.clear();
            console.table({ operation: "Upload", status: response.status, message: response.statusText });

            return {
                status: false,
                data: {},
            };
        }

        return {
            status: response.ok,
            data: API_DATA,
        };
    } catch (error) {
        console.error(error);
        return false;
    }
};

const interfaceWithAPI = async (data) => {
    console.log("Interfacing with API....");
    const url = new URL("https://unsplash.com/napi/photos");
    const query = {};

    Object.keys(query).map((k) => url.searchParams.set(k, query[k]));

    try {
        const response = await fetch(url.href, {
            method: "POST",
            body: JSON.stringify({ photo: data }, null, 2),
            headers: {
                Authorization: `Bearer ${BEAERER_TOKEN}`
                origin: "https://unsplash.com",
                "accept-encoding": "gzip, deflate, br",
                "accept-language": "it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7",
                cookie:
                    "_ga=GA1.2.1702173825.1537532910; uuid=d932a120-bd99-11e8-afe9-bbf0b2793133; xpos=%7B%7D; __utmz=167807461.1537780602.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); xp-search-cervantes-v1=control; ugid=9378b40282227cb486bd2318801618965144820; __utma=167807461.1702173825.1537532910.1537780602.1545334217.2; auth_user_id=392403; stream_user_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyZXNvdXJjZSI6IioiLCJhY3Rpb24iOiIqIiwiZmVlZF9pZCI6Im5vdGlmaWNhdGlvbjM5MjQwMyJ9.jNiFkDqZ8oIm4gNud9uJ84xbAON9jcSKkreo6weml-4; intercom-id-njw7pl12=cbe1bc7a-b884-4657-a326-e488a5ece036; _sp_id.7efb=a0740315-d098-4c92-8d7c-a050e458f7e2.1556841546.6.1557137271.1557134957.2ae41df1-f71c-4c6f-a878-28fbb8e5f2b9; _gid=GA1.2.1980213034.1557785829; _sp_ses.0295=*; xp-search-no-idf=excluded; lux_uid=155778609108149235; un_sesh=L1p5cE0vTWJQaHVuQmlJcUlrUHJERGI3VGhoNDlJTHFtY2IxZ1lGM2xkZWZvTS8xVW1EazJZdkVicHNFSnZ6TGtsdEg1VndsaTlZS1YvbEdsLzFUd1pMVkFoclh4QURtL1EyREY0cmxDVFNsYWllRHBXd0l0TmxnbW00WEVxZDJqZUZLd3o4eXJuckNWbGEwOHFJL1NGcldyYnZ4UnVHU0tqR1RBaGlJQmdCUmlUT28xMFQ1QitmaXJoOEhkY1J3OWpiWDdReW1wZEVYTkgwZVJhQ0VXUFNrdFNObXJvUGlPK3lwRzdnWGFuREJmcGRlRFBIVDJ6SzgrdXY3cXJ5VlNnOWxjeDI1TStxRlRvYnpYK0I1Mk56dWNpRXRzdlRjVEhUUUo1OXRMbWFMNkFGdjQrUnRHM0g2aExReU5UU1I2cmdGUE55YjdiRWZhRnRWUDN6Snorb2xCM2xJamRWc0U5aHlGa2NVdXlweUtISWtCYVY0WS9PMG9uOEhpdVZKanZ5UStiV3NGT055aFJSS0ZKRXB5UT09LS1aazlzUWh2dDJJZmZCQlZyKzJVNTF3PT0%3D--2f8cef780fc0863e6a9f55cd4237b62dce936eec; _sp_id.0295=b9861be3-38cd-4105-b3d1-436e85807667.1537532910.104.1557786161.1557303173.a5fa8f55-4fd7-46fb-838b-abd564311d31",
                dpr: "1",
                pragma: "no-cache",
                "user-agent":
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36",
                "viewport-width": "2532",
                "content-type": "application/json",
                accept: "*/*",
                "cache-control": "no-cache",
                referer: "https://unsplash.com/",
                dnt: "1",
            },
        });

        if (!response.ok) {
            console.clear();
            console.table({ operation: "Api interface", status: response.status, message: response.statusText });
            return false;
        }

        return await response.json();
    } catch (error) {
        console.error(error);
        return false;
    }
};

const picture = path.join(os.homedir(), "Desktop", "file.jpg");

getSignedURL()
    .then((presigned_url) => {
        uploadToS3(picture, presigned_url)
            .then(({ status, data }) => {
                if (!status) return false;
                interfaceWithAPI(data)
                    .then(console.log)
                    .catch(console.error);
            })
            .catch(console.error);
    })
    .catch(console.error);