#!/usr/bin/env ruby # print new follows/unfollows to stdout require 'json' require 'net/http' require 'date' channel = "bungmonkey" unless ARGV.empty? channel = ARGV[0] end # this is technically data but we'll shove it in .config because i am a bad person DATAPATH=Dir.home+'/.config/twitch/' def difftime(seconds) units = [60,60,24].reduce([seconds]) { |m,o| m.unshift(m.shift.divmod(o)).flatten } # [days, hours, minutes, seconds] result = Array.new units[3] > 0 && result.unshift(units[3].to_s + " seconds") units[2] > 0 && result.unshift(units[2].to_s + " minutes") units[1] > 0 && result.unshift(units[1].to_s + " hours") units[0] > 0 && result.unshift(units[0].to_s + " days") result.length > 1 && result[-1]="and "+result[-1] return result.join(', ') end unless File.exists?(DATAPATH+channel+'/follows') unless File.exists?(DATAPATH+channel) unless File.exists?(DATAPATH) unless File.exists?(Dir.home+'/.config') Dir.mkdir(Dir.home+'/.config') end Dir.mkdir(DATAPATH) end Dir.mkdir(DATAPATH+channel) end Dir.mkdir(DATAPATH+channel+'/follows') end unless File.exists?(DATAPATH+channel+'/unfollows') Dir.mkdir(DATAPATH+channel+'/unfollows') end http = Net::HTTP.new('api.twitch.tv', 443) http.use_ssl = true http.read_timeout = 500 offset = 0 total = 1 twitchfollows = Array.new localfollows = Array.new localunfollows = Array.new while offset < total begin response = JSON.parse(http.request(Net::HTTP::Get.new("/kraken/channels/#{channel}/follows?offset=#{offset}&limit=100")).body) rescue exit 2 # if twitch is broken, give up for now and wait until later # very occasionally the API spits out blank json. it would be nice to detect this, but i have not caught it in debugging. end total = response['_total'] for follow in response['follows'] name = follow['user']['name'].gsub('/','slash') # sterilize followtime = DateTime.iso8601(follow["created_at"]).strftime(format='%s') followpath = DATAPATH+channel+'/follows/'+name unfollowpath = DATAPATH+channel+'/unfollows/'+name unless File.exists?(followpath) File.write(followpath, followtime) if File.exists?(unfollowpath) print name + ' refollowed after ' + difftime( followtime.to_i - File.read(unfollowpath).to_i ) + "!\n" else print name + " is now following!\n" end end twitchfollows << name end offset += 95 end localfollows = Dir.entries(DATAPATH+channel+'/follows/') - [".", ".."] localunfollows = Dir.entries(DATAPATH+channel+'/unfollows/') - [".", ".."] for unfollow in localfollows - twitchfollows unfollowpath = DATAPATH+channel+'/unfollows/'+unfollow followpath = DATAPATH+channel+'/follows/'+unfollow unless File.exists?(unfollowpath) unfollowtime = DateTime.now.strftime(format='%s') File.write(unfollowpath, unfollowtime) print unfollow + ' unfollowed after ' + difftime(unfollowtime.to_i - File.read(followpath).to_i) + "!\n" File.unlink(followpath) end end