class SmugmugAPI
Constants
- ACCESS_TOKEN_URL
- API_ENDPOINT
- AUTHORIZE_URL
- OAUTH_ORIGIN
- REQUEST_TOKEN_URL
- UPLOAD_ENDPOINT
Attributes
http[RW]
uploader[RW]
Public Class Methods
new(ejson_file = '~/.photo_helper.ejson')
click to toggle source
# File lib/helpers/smugmug_api.rb, line 19 def initialize(ejson_file = '~/.photo_helper.ejson') ejson_file = File.expand_path(ejson_file) @secrets = Secrets.new(ejson_file, %i[api_key api_secret]) request_access_token if !@secrets['access_token'] || !@secrets['access_secret'] @http = get_access_token @uploader = get_access_token(UPLOAD_ENDPOINT) user_resp = user @user = user_resp['NickName'] @root_node = File.basename(user_resp['Uris']['Node']['Uri']) end
Public Instance Methods
albums()
click to toggle source
# File lib/helpers/smugmug_api.rb, line 31 def albums albums_list = [] start = 1 count = 100 loop do resp = get("/api/v2/user/#{@user}!albums", start: start, count: count) resp['Album'].each do |album| albums_list.push(album_parser(album)) end break if (start + count) > resp['Pages']['Total'].to_i start += count end albums_list end
albums_long(path = '', node_id = @root_node)
click to toggle source
# File lib/helpers/smugmug_api.rb, line 47 def albums_long(path = '', node_id = @root_node) album_list = [] node_children(node_id)['Node'].each do |node| node_path = path.empty? ? node['Name'] : File.join(path, node['Name']) case node['Type'] when 'Folder' album_list.concat(albums_long(node_path, node['NodeID'])) when 'Album' album_list.push(path: node_path, name: node['Name'], web_uri: node['WebUri'], node_uri: node['Uri'], id: File.basename(node['Uris']['Album']['Uri']), type: 'node') end end album_list end
collect_images(images, album_id)
click to toggle source
# File lib/helpers/smugmug_api.rb, line 232 def collect_images(images, album_id) return if images.empty? images = images.join(',') if images.is_a? Array post("/api/v2/album/#{album_id}!collectimages", 'CollectUris' => images) end
delete_images(images)
click to toggle source
# File lib/helpers/smugmug_api.rb, line 163 def delete_images(images) images = [images] unless images.is_a? Array images.each do |image| http(:delete, image[:uri]) end end
folders()
click to toggle source
# File lib/helpers/smugmug_api.rb, line 74 def folders folder_list = [] resp = get('/api/v2/folder/user/bcaldwell!folderlist') resp['FolderList'].each do |folder| folder_list.push(folder_parser(folder)) end folder_list end
get(url, params = nil, headers = {})
click to toggle source
# File lib/helpers/smugmug_api.rb, line 181 def get(url, params = nil, headers = {}) url = url.tr(' ', '-') uri = URI.parse(url) uri.query = URI.encode_www_form(params) if params http(:get, uri.to_s, headers) end
get_or_create_album(path, album_url: nil)
click to toggle source
path is the full path with spaces
# File lib/helpers/smugmug_api.rb, line 84 def get_or_create_album(path, album_url: nil) folder_path = File.dirname(path).split('/').map(&:capitalize).join('/') album_name = File.basename(path).split(' ').map(&:capitalize).join(' ') album = nil folder = get_or_create_folder(folder_path) resp = get(folder[:albums_url]) albums = get(folder[:albums_url])['Album'] if resp.key? 'Album' albums ||= [] albums.each do |album_raw| next unless album_raw['Name'] == album_name album = album_parser(album_raw) end if album.nil? url = "/api/v2/folder/user/#{@user}" url += "/#{folder_path}" unless folder_path.empty? url += '!albums' album_url = album_name if album_url.nil? resp = post(url, Name: album_name, UrlName: album_url.tr(' ', '-').capitalize, Privacy: 'Unlisted', SmugSearchable: 'No', SortMethod: 'Date Taken', LargestSize: 'X4Large', SortDirection: 'Ascending', WorldSearchable: false, EXIF: false, Printable: false, Filenames: true) album_raw = resp['Album'] album = album_parser(album_raw) end album end
get_or_create_folder(path)
click to toggle source
# File lib/helpers/smugmug_api.rb, line 120 def get_or_create_folder(path) parts = path.split('/') current_path = '' folder = nil parts.each do |part| part = part.capitalize new_path = current_path.empty? ? part : File.join(current_path, part) resp = http_raw(:get, "/api/v2/folder/user/#{@user}/#{new_path}") if resp.is_a? Net::HTTPSuccess folder_raw = JSON.parse(resp.body)['Response']['Folder'] folder = folder_parser(folder_raw) else url = "/api/v2/folder/user/#{@user}" url += "/#{current_path}" unless current_path.empty? url += '!folders' resp = post(url, Name: part.capitalize, UrlName: part.tr(' ', '-').capitalize, Privacy: 'Unlisted') folder = folder_parser(resp['Folder']) end current_path = new_path end folder end
image_list(album_id)
click to toggle source
# File lib/helpers/smugmug_api.rb, line 170 def image_list(album_id) @images = images(album_id) @images.map { |i| i[:filename] } end
images(album_id)
click to toggle source
# File lib/helpers/smugmug_api.rb, line 147 def images(album_id) images = [] start = 1 count = 100 loop do images_raw = get("/api/v2/album/#{album_id}!images", start: start, count: count) return [] unless images_raw.key? 'AlbumImage' images_raw['AlbumImage'].each do |image| images.push(imager_parser(image)) end break if (start + count) > images_raw['Pages']['Total'].to_i start += count end images end
move_images(images, album_id)
click to toggle source
# File lib/helpers/smugmug_api.rb, line 238 def move_images(images, album_id) return if images.empty? images = images.join(',') if images.is_a? Array post("/api/v2/album/#{album_id}!moveimages", 'MoveUris' => images) end
node_children(id)
click to toggle source
# File lib/helpers/smugmug_api.rb, line 66 def node_children(id) get("/api/v2/node/#{id}!children", count: 100) end
post(url, body = {}, headers = {})
click to toggle source
# File lib/helpers/smugmug_api.rb, line 188 def post(url, body = {}, headers = {}) url = url.tr(' ', '-') headers['Accept'] = 'application/json' headers['Content-Type'] = 'application/json' headers['Connection'] = 'keep-alive' response = @http.post(url, body, headers) raise "Request failed\n#{URI.unescape(response.body)}" unless response.is_a? Net::HTTPSuccess JSON.parse(response.body)['Response'] end
request_access_token()
click to toggle source
# File lib/helpers/smugmug_api.rb, line 252 def request_access_token @consumer = OAuth::Consumer.new(@secrets.api_key, @secrets.api_secret, site: OAUTH_ORIGIN, name: 'photo-helper', request_token_path: REQUEST_TOKEN_URL, authorize_path: AUTHORIZE_URL, access_token_path: ACCESS_TOKEN_URL) # Generate request token @request_token = @consumer.get_request_token # Get authorize URL @request_token.authorize_url url = add_auth_params(@request_token.authorize_url, 'Access' => 'Full', 'Permissions' => 'Modify') puts "Go to #{url} and enter shown 6 digit number:" verifier = STDIN.gets.strip # Now go to that url and when you're done authorization you can run the # following command where you put in the value for oauth_verifier that you got # from completely the above URL request: access_token = @request_token.get_access_token(oauth_verifier: verifier) puts "Add the following to your ejson file #{@secrets.ejson_config_file}:" puts "\"access_token\": \"#{access_token.token}\"," puts "\"access_secret\": \"#{access_token.secret}\"" exit 0 end
update_images(images, album_id, headers = {}, workers: 4, filename_as_title: false)
click to toggle source
# File lib/helpers/smugmug_api.rb, line 223 def update_images(images, album_id, headers = {}, workers: 4, filename_as_title: false) Parallel.each(images, in_processes: workers, progress: 'Updating images') do |image| # replace not working, delete then upload http(:delete, image[:uri]) upload(image[:file], album_id, headers, filename_as_title: filename_as_title) puts "Done #{image[:file]}\n" end end
update_keywords(image, keywords, overwrite = false)
click to toggle source
# File lib/helpers/smugmug_api.rb, line 244 def update_keywords(image, keywords, overwrite = false) return if image.nil? keywords = (image[:keywords] + keywords).uniq unless overwrite # inspect need outwise it isnt encoded right post("#{image[:image_uri]}?_method=PATCH", KeywordArray: keywords.inspect) end
upload(image_path, album_id, headers = {}, filename_as_title: false)
click to toggle source
# File lib/helpers/smugmug_api.rb, line 198 def upload(image_path, album_id, headers = {}, filename_as_title: false) image = File.open(image_path) headers.merge!('Content-Type' => MimeMagic.by_path(image_path).type, 'X-Smug-AlbumUri' => "/api/v2/album/#{album_id}", 'X-Smug-ResponseType' => 'JSON', 'X-Smug-Version' => 'v2', 'charset' => 'UTF-8', 'Accept' => 'JSON', 'X-Smug-FileName' => File.basename(image_path), 'Content-MD5' => Digest::MD5.file(image_path).hexdigest) headers['X-Smug-Title'] = File.basename(image_path, '.*') if filename_as_title resp = @uploader.post('/', image, headers) resp.body end
upload_images(images, album_id, headers = {}, workers: 4, filename_as_title: false)
click to toggle source
# File lib/helpers/smugmug_api.rb, line 216 def upload_images(images, album_id, headers = {}, workers: 4, filename_as_title: false) Parallel.each(images, in_processes: workers, progress: 'Uploading images') do |image| upload(image, album_id, headers, filename_as_title: filename_as_title) puts "Done #{image}\n" end end
user()
click to toggle source
# File lib/helpers/smugmug_api.rb, line 70 def user get('/api/v2!authuser')['User'] end
Private Instance Methods
add_auth_params(url, params)
click to toggle source
# File lib/helpers/smugmug_api.rb, line 334 def add_auth_params(url, params) uri = URI.parse(url) new_query_ar = URI.decode_www_form(uri.query || '') params.to_a.each { |el| new_query_ar << el } uri.query = URI.encode_www_form(new_query_ar) uri.to_s end
album_parser(album)
click to toggle source
# File lib/helpers/smugmug_api.rb, line 311 def album_parser(album) { name: album['Name'], id: album['AlbumKey'], web_uri: album['WebUri'], images_uri: album['Uris']['AlbumImages']['Uri'], type: 'album' } end
folder_parser(folder)
click to toggle source
# File lib/helpers/smugmug_api.rb, line 300 def folder_parser(folder) { name: folder['Name'], url_name: folder['UrlName'], web_uri: folder['UrlPath'], uri: folder['Uri'], albums_url: folder['Uris']['FolderAlbums']['Uri'], type: 'folder' } end
get_access_token(endpoint = API_ENDPOINT)
click to toggle source
# File lib/helpers/smugmug_api.rb, line 290 def get_access_token(endpoint = API_ENDPOINT) @consumer = OAuth::Consumer.new( @secrets.api_key, @secrets.api_secret, site: endpoint ) # # Create the access_token for all traffic OAuth::AccessToken.new(@consumer, @secrets.access_token, @secrets.access_secret) end
http_raw(method, url, headers = {}, _body = nil)
click to toggle source
# File lib/helpers/smugmug_api.rb, line 284 def http_raw(method, url, headers = {}, _body = nil) url = url.tr(' ', '-') headers['Accept'] = 'application/json' @http.request(method, url, headers) end
imager_parser(image)
click to toggle source
# File lib/helpers/smugmug_api.rb, line 319 def imager_parser(image) { title: image['Title'], filename: image['FileName'], caption: image['Caption'], keywords: image['KeywordArray'], id: image['ImageKey'], md5: image['ArchivedMD5'], uri: image['Uri'], image_uri: image['Uris']['Image']['Uri'], web_uri: image['WebUri'], type: 'image' } end