1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
#!/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
|