diff --git a/README.md b/README.md index 2ea3ad4..a00bd6b 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ don't code? [use the web version](https://product-hunt-upvotes.herokuapp.com/). 1. ```$ gem install hunting_season``` ## how it works -1. run the script (```$ ruby producthunt.rb```) +1. run the script (```$ ruby client.rb```) 2. input your [Developer Token](https://www.producthunt.com/v1/oauth/applications) 2. input a featured product's URL -3. csv file of upvoters will save in the same directory as the script file +3. CSV file of upvoters will save in the same directory as the script file diff --git a/client.rb b/client.rb new file mode 100644 index 0000000..b26fbbc --- /dev/null +++ b/client.rb @@ -0,0 +1,51 @@ +require 'hunting_season' # product hunt api +require 'csv' # write to CSV + +class UpvoteDownloader + + def initialize + puts "what's your product hunt developer token?" + @client = ProductHunt::Client.new(gets.chomp) + clear + + puts "enter a product hunt URL, ie 'https://www.producthunt.com/posts/fomo-3'" + @slug = gets.chomp.split("/posts/")[1] + clear + end + + def clear + system 'clear' + end + + def run + puts "looking for post..." + post = @client.all_posts("search[slug]" => @slug)[0] + + abort "post with slug '#{@slug}' not found, please try again." if post.nil? + puts "found post..." + + get_and_show_voters(post) + end + + def get_and_show_voters(post, voters = []) + vote_count = post['votes_count'] + puts "processing #{vote_count} votes..." + + pages = (vote_count.to_f / 50).ceil + pages.times do |page| + voters << post.votes(per_page: 50, page: page+1, order: 'asc') + voters.flatten! + puts "finished #{voters.count} votes..." + end + + output = voters.flatten.uniq.map {|v| v['user']['twitter_username']}.compact.each_slice(1).map {|x| p x} # split users into rows + File.open("#{post['name'].downcase}_voters.csv", "w") {|f| f.write(output.inject([]) { |csv, row| csv << CSV.generate_line(row) }.join(""))} + clear + + puts "done!\nyour CSV export is in the same folder as this file.\npowered by: www.ryanckulp.com" + end + +end + +# run +UpvoteDownloader.new.run diff --git a/producthunt.rb b/producthunt.rb deleted file mode 100644 index 07238d1..0000000 --- a/producthunt.rb +++ /dev/null @@ -1,51 +0,0 @@ -require 'hunting_season' # product hunt api -require 'csv' # write to CSV - -def initialize_api - puts "Enter your Developer Token:" - dev_token = gets.chomp - ProductHunt::Client.new(dev_token) -end - -def request_domain - puts "Enter a product URL, ie: http://generator.persistiq.com" - gets.chomp -end - -def get_post(client, product) - client.all_posts("search[url]" => product)[0] # return first posted project with this URL -end - -# hack that works but does not intelligently iterate through pages -def get_voters(post, voters = [], voters_raw = []) - page_1 = post.votes(per_page: 50, order: 'asc') - page_2 = post.votes(per_page: 50, order: 'asc', newer: page_1.last['id']) - page_3 = post.votes(per_page: 50, order: 'asc', newer: page_2.last['id']) - page_4 = post.votes(per_page: 50, order: 'asc', newer: page_3.last['id']) unless page_3.count < 50 - page_5 = post.votes(per_page: 50, order: 'asc', newer: page_4.last['id']) if page_4 && page_4.count == 50 - page_6 = post.votes(per_page: 50, order: 'asc', newer: page_5.last['id']) if page_5 && page_5.count == 50 - page_7 = post.votes(per_page: 50, order: 'asc', newer: page_6.last['id']) if page_6 && page_6.count == 50 - - voters_raw << page_1 - voters_raw << page_2 - voters_raw << page_3 if page_3 - voters_raw << page_4 if page_4 - voters_raw << page_5 if page_5 - voters_raw << page_6 if page_6 - voters_raw << page_7 if page_7 - - voters << voters_raw.flatten.uniq.map {|v| v['user']['twitter_username']} - voters.flatten.uniq # remove dupes if hard-coded pagination goes too far -end - -############ -# GAMEPLAY # -############ - -client = initialize_api -product = request_domain -post = get_post(client, product) -voters = get_voters(post) - -output = voters.each_slice(1).map {|x| p x} # split users into rows -File.open("#{post['name'].downcase}_voters.csv", "w") {|f| f.write(output.inject([]) { |csv, row| csv << CSV.generate_line(row) }.join(""))}