I come from a C background and need help refactoring the following imgur image uploader script I wrote.
It checks if a token_file
with access_token
and refresh_token
exists. If not, it instructs the user to go to a webpage, allow access to my app and enter the PIN generated from the site back to my program so that I can exchange it with access and refresh tokens.
I upload the picture taken with the 'scrot' utility to the users album, put the direct link on clipboard, and show a system notification. I'm not using the libnotify gem because it segfaults.
If the upload failed because the access_token
is expired, which lasts only 60 minutes, I use the refresh token I got from the first authorization step, get a new one and update the token_file
as well.
I know I should be using a class to keep things more organized.
I just don't know what's the best way to deal with info like client_id
and token_file
. Should they be instance or class methods? Also what should I put in the initialize
method, the reading of tokens from the file or launch scrot?
I know I don't error check for everything yet.
#!/usr/bin/env ruby
require 'httparty'
require 'json'
require 'clipboard'
$client_id = 'xxxxxxxxxxx'
$client_secret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
$token_file = '.imgur_token'
def auth_app
puts 'Follow the link to allow the application access to your account and enter the pin',
"https://api.imgur.com/oauth2/authorize?client_id=#{$client_id}&response_type=pin"
print 'Pin: '
pin = STDIN.gets.chomp
response = HTTParty.post 'https://api.imgur.com/oauth2/token',
:body => { 'client_id' => $client_id,
'client_secret' => $client_secret,
'grant_type' => 'pin',
'pin' => pin }
if response['access_token'] == nil
puts 'Authorization failed'
else
tokens = { 'access_token' => response['access_token'],
'refresh_token' => response['refresh_token'] }
File.write($token_file, tokens.to_json)
end
tokens
end
def refresh_token(refresh_token)
response = HTTParty.post 'https://api.imgur.com/oauth2/token',
:body => { 'refresh_token' => refresh_token,
'client_id' => $client_id,
'client_secret' => $client_secret,
'grant_type' => 'refresh_token' }
response['access_token']
end
def upload_image(access_token)
response = HTTParty.post 'https://api.imgur.com/3/upload.json',
:headers => { 'Authorization' => "Bearer #{access_token}" },
:body => { 'image' => Base64.encode64(File.read('imgur.png')) }
response['data']['link']
end
abort('scrot not found') unless system('scrot -s imgur.png')
tokens = File.exists?($token_file) ? JSON.parse(File.read($token_file)) : auth_app
if (link = upload_image(tokens['access_token'])) == nil
tokens['access_token'] = refresh_token(tokens['refresh_token'])
link = upload_image(tokens['access_token'])
File.write($token_file, tokens.to_json)
end
if link != nil
Clipboard.copy link
system('notify-send Upload complete')
else
system('notify-send Upload error')
end
File.delete('imgur.png')
$
global variables is a first sign something is awry. CONSTANTS are a better choice usually, or pass the value in as a parameter to the method. – the Tin Man Jul 2 '13 at 18:23