diff --git a/hunted.js b/hunted.js index 07d79c4..3c63bd6 100644 --- a/hunted.js +++ b/hunted.js @@ -1,47 +1,100 @@ 'use strict'; +const path = require('path'); +const fs = require('fs'); +const https = require('https'); const alfy = require('alfy'); +const normalizeUrl = require('normalize-url'); +const media = path.join(__dirname, 'media'); const token = alfy.config.get('token') || process.env.TOKEN; - -if (!token) { - return alfy.error(new Error(`Please add a Product Hunt token as a variable`)); -} - -const query = `query { posts(url: "${alfy.input}", order: VOTES) { +const input = normalizeUrl(alfy.input); +const query = `query { posts(url: "${input}", order: VOTES) { edges{ node{ + id name url + thumbnail { + url(height: 120, width: 120) + } }}}}`; +function ensureDirectoryExistence(filePath) { + var dirname = path.dirname(filePath); + if (fs.existsSync(dirname)) { + return true; + } + ensureDirectoryExistence(dirname); + fs.mkdirSync(dirname); +} + +function download(filename, url, callback) { + ensureDirectoryExistence(filename) + let file = fs.createWriteStream(filename); + + https.get(url, function (response) { + if (callback !== undefined) { + response.pipe(file).on('finish', () => { + callback(file); + }); + } + }); +} + +if (!token) { + return alfy.error(new Error(`Please add a Product Hunt token as a variable`)); +} + alfy .fetch('https://api.producthunt.com/v2/api/graphql', { method: 'POST', - // json: true, - json: false, + json: true, headers: { "Authorization": `Bearer ${token}`, "Content-Type": "application/json" }, - // body: { query } - body: JSON.stringify({ query }) + body: { query } }) .then((json) => { const data = json.data; + const edges = data.posts.edges; + const hasResults = (Array.isArray(edges) && edges.length) if (!data) { return alfy.log(json.errors ? json.errors : 'Unknown GraphQL Error'); } - alfy.log('All good!'); - alfy.log(data.viewer.repositories.nodes); + const noResults = [{ + title: 'Looks like this URL hasn’t been hunted!', + subtitle: 'Submit to Product Hunt', + arg: 'https://www.producthunt.com/posts/new' + }]; + + const results = edges.map(({node}) => { + const iconPath = path.join(media, `${node.id}`); + + fs.exists(iconPath, exists => { + if (!exists) { + download(iconPath, node.thumbnail.url, () => { + return true; + }); + } + }); - const results = data.body.posts.edges.map((node) => { return { - title: node.name, - arg: node.url + title: 'This URL has already been hunted!', + subtitle: `Open ${node.name} on Product Hunt`, + arg: node.url, + icon: { + path: iconPath + }, }; }); - alfy.output(results); + if (hasResults) { + alfy.output(results) + } + else{ + alfy.output(noResults) + } }); diff --git a/index.js b/index.js index 2409947..1824abb 100644 --- a/index.js +++ b/index.js @@ -72,7 +72,7 @@ function download(filename, url, callback) { hits.forEach(hit => { const iconPath = path.join(media, `${hit.id}`); - const iconUrl = `https://ph-files.imgix.net/${hit.thumbnail.image_uuid}?auto=format&fit=crop&h=128&w=128`; + const iconUrl = `https://ph-files.imgix.net/${hit.thumbnail.image_uuid}?auto=format&fit=crop&h=120&w=120`; fs.exists(iconPath, exists => { if (!exists) { diff --git a/info.plist b/info.plist index d0a7a08..f5c34cb 100644 --- a/info.plist +++ b/info.plist @@ -330,7 +330,8 @@ fi readme Search Product Hunt posts from Alfred -Token is only needed for the `hunted` method, which is currently broken. +The developer token is only needed for the `hunted` method, which is currently broken. +Locate yours by visiting https://api.producthunt.com/v2/docs and clicking “API Dashboard” uidata 1ACB45A9-A438-4781-8FD8-159A129D08ED diff --git a/package.json b/package.json index b903216..31c210b 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "@algolia/cache-in-memory": "^4.5.1", "alfy": "^0.10.0", "algoliasearch": "^3.34.0", - "dotenv": "^8.2.0" + "dotenv": "^8.2.0", + "normalize-url": "^5.3.0" } }