Skip to content

Instantly share code, notes, and snippets.

@joshwand
Last active June 28, 2024 14:24
Show Gist options
  • Save joshwand/5402126 to your computer and use it in GitHub Desktop.
Save joshwand/5402126 to your computer and use it in GitHub Desktop.
download your liked photos from tumblr
require 'tumblr_client'
require 'mechanize'
require 'date'
require 'yaml'
require 'uri'
Tumblr.configure do |config|
config.consumer_key = "consumer_key"
config.consumer_secret = "consumer_secret"
config.oauth_token = "oath_token"
config.oauth_token_secret = "token_secret"
end
THREADPOOL_SIZE = 4
SEGMENT_SIZE = 25
HISTORY_FILE = File.join(File.dirname(__FILE__), "previous.yml")
previous_dled_ids = YAML.load(File.open(HISTORY_FILE)) rescue []
directory = "tumblr-likes"
client = Tumblr::Client.new
likes = client.likes
liked_count = likes["liked_count"]
puts liked_count
likes = []
(0...liked_count).each do |i|
if i==0 or i%SEGMENT_SIZE==0
p "getting #{SEGMENT_SIZE} more likes starting at #{i}: #{likes.count} thus far"
client.likes({:limit => SEGMENT_SIZE, :offset => i})["liked_posts"].each do |like|
likes << like if like['type'] == 'photo' and !previous_dled_ids.include?(like['id'])
end
end
end
if likes.empty?
p "no new likes!"
exit 0
end
puts "#{likes.count} new likes!"
# some of this code comes from https://github.com/jamiew/tumblr-photo-downloader
already_had = 0
threads = []
likes.each_slice(likes.count / THREADPOOL_SIZE ).each do |group|
threads << Thread.new {
begin
p "launching thread #{threads.size + 1}"
group.each do |like|
i = 0
like["photos"].each do |photo|
url = photo["original_size"]["url"]
filename = "#{like["blog_name"]}-#{like["slug"]}-"
filename += "#{i}-" if i > 0
filename += File.basename(URI.parse(url).path.split('?')[0])
if File.exists?("#{directory}/#{filename}")
puts "Already have #{url}"
already_had += 1
else
begin
puts "Saving photo #{url}"
file = Mechanize.new.get(url)
file.save_as("#{directory}/#{filename}")
rescue Mechanize::ResponseCodeError => e
puts "Error #{e.response_code} getting file for #{url}"
end
end
i += 1
previous_dled_ids << like['id']
end
end
rescue Exception => e
puts "unhandled exception:, #{$!}"
end
p "closing thread"
}
end
threads.each{|t| t.join }
YAML.dump(previous_dled_ids, File.open(HISTORY_FILE, "w"))
@chufucious
Copy link

@joshwand, thanks for this marvelous script. It successfully collected all the likes I have but then after it began downloading the files, I ran into an issue:

tumblr-likes-downloader.rb:52:in `block (3 levels) in <main>': undefined method `each' for nil:NilClass (NoMethodError)
    from tumblr-likes-downloader.rb:49:in `each'
    from tumblr-likes-downloader.rb:49:in `block (2 levels) in <main>'

Have any idea what this might be? Thanks.

@dannberg
Copy link

I got the same error as chufuchious

@miaoski
Copy link

miaoski commented Jan 12, 2014

tumblr seems to have changed their API. Glad there seems no impact on this downloader :)

@nazzeth
Copy link

nazzeth commented Jan 13, 2014

I'm not a programmer, nor familuar with Ruby.

I've managed to eventually get ruby and the scripts dependencies installed but have received an error I cannot understand.

ruby tld.rb
/usr/local/rvm/gems/ruby-2.0.0-p353/gems/faraday-0.9.0.rc7/lib/faraday/options.rb:30:in block in update': undefined methodclient=' for #Faraday::ConnectionOptions:0x00000000e23d08 (NoMethodError)
from /usr/local/rvm/gems/ruby-2.0.0-p353/gems/faraday-0.9.0.rc7/lib/faraday/options.rb:19:in each' from /usr/local/rvm/gems/ruby-2.0.0-p353/gems/faraday-0.9.0.rc7/lib/faraday/options.rb:19:inupdate'
from /usr/local/rvm/gems/ruby-2.0.0-p353/gems/faraday-0.9.0.rc7/lib/faraday/options.rb:46:in merge' from /usr/local/rvm/gems/ruby-2.0.0-p353/gems/faraday-0.9.0.rc7/lib/faraday.rb:69:innew'
from /usr/local/rvm/gems/ruby-2.0.0-p353/gems/tumblr_client-0.8.2/lib/tumblr/connection.rb:19:in connection' from /usr/local/rvm/gems/ruby-2.0.0-p353/gems/tumblr_client-0.8.2/lib/tumblr/request.rb:8:inget_response'
from /usr/local/rvm/gems/ruby-2.0.0-p353/gems/tumblr_client-0.8.2/lib/tumblr/request.rb:26:in get' from /usr/local/rvm/gems/ruby-2.0.0-p353/gems/tumblr_client-0.8.2/lib/tumblr/user.rb:16:inlikes'
from tld.rb:18:in `

'

If anyone can shed some light on this, I'd be appreciative.

@danicra
Copy link

danicra commented Jan 14, 2014

Same problem (as chufuchious and as dannberg) after downloading 280 pics

tumblr-likes-downloader.rb:52:in block (3 levels) in <main>': undefined methodeach' for nil:NilClass (NoMethodError)
from ../tumblr-likes-downloader.rb:49:in each' from ../tumblr-likes-downloader.rb:49:inblock (2 levels) in

'

@drchris1502
Copy link

Ok, here's my theory to the above problem. I think the program crashes if a particular "like" is not of type "photo". So by adding a test for the type of post, I have my version working. This is a section of the above code with the new test applied. Good luck!

if (like["type"]=="photo")

      like["photos"].each do |photo|
        url = photo["original_size"]["url"]
        file = Mechanize.new.get(url)
        filename = "#{like["blog_name"]}-#{like["slug"]}-"
        filename += "#{i}-" if i > 0
        filename += File.basename(file.uri.to_s.split('?')[0])


        if File.exists?("#{directory}/#{filename}")
          puts "Already have #{url}"
          already_had += 1
        else
          puts "Saving photo #{url}"
          file.save_as("#{directory}/#{filename}")
        end
  end

@danicra
Copy link

danicra commented Jan 22, 2014

It worked! Thanks drchris1502!

Now I have other problem that stops ruby script. I think because fav photo has been deleted... I get a 403 error. Is there an easy way to skip 403 errors?

 Error getting file, 403 => Net::HTTPForbidden for http://25.media.tumblr.com/a99241d46e71eeccb9e1b9ac0c2543ac/tumblr_mnsdf_500.jpg -- unhandled response
"closing thread"

@berylthere
Copy link

Hello. I'm having trouble with the following, forgive me, I am also a newbie w/ Ruby. I'm on a Mac.

"irb(main):001:0> load '/Users/b/TMBLRLIKES/tumblr-likes-downloader.rb'
LoadError: cannot load such file -- tumblr_client
from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:45:in require' from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:45:inrequire'
from /Users/b/TMBLRLIKES/tumblr-likes-downloader.rb:1:in <top (required)>' from (irb):1:inload'
from (irb):1
from /usr/bin/irb:12:in `

'
irb(main):002:0> "

Assuming it may be something about rubygems files not being in the correct directory, but, not certain.

Any advice on how to proceed in detail would be very appreciated.

Thank you!

@whywontidie
Copy link

Hello, I'm a Windows user (though I'm unsure if that matters) and I've installed Ruby 1.9.x along with the DevKit and necessary dependencies (tumblr_client, mechanize, multipart-post, etc) but when I try to run the script I encounter an error

 '<main>': bad value for range <ArgumentError>

My gem list is as follows:

bigdecimal (1.1.0)
domain_name (0.5.16)
faraday (0.8.9)
faraday_middleware (0.9.0)
http-cookie (1.0.2)
io-console (0.3)
json (1.5.5)
mechanize (2.7.3)
mime-types (2.1)
mini_portile (0.5.2)
minitest (2.5.1)
multipart-post (2.0.0, 1.2.0)
net-http-digest_auth (1.4)
net-http-persistent (2.9.4)
nokogiri (1.6.1 x86-mingw32)
ntlm-http (0.1.1)
oauth (0.4.7)
rake (0.9.2.2)
rdoc (3.9.5)
simple_oauth (0.2.0)
tumblr_client (0.8.2)
unf (0.1.3)
unf_ext (0.0.6 x86-mingw32)
webrobots (0.1.1)

@m1lner
Copy link

m1lner commented Mar 31, 2014

I'm having the same problem as nazzeth. I've installed tumblr_client and mechanize. for the others required (date, yaml, uri), I get an error "could not find a valid gem ... in any repository". Then when I try to run I get:

$ ruby tumblr-likes-downloader4.rb
/Users/user/.rvm/gems/ruby-2.1.1/gems/faraday-0.9.0.rc7/lib/faraday/options.rb:30:in 'block in update': undefined method 'client=' for #Faraday::ConnectionOptions:0x00000101ae63a0 (NoMethodError)
from /Users/user/.rvm/gems/ruby-2.1.1/gems/faraday-0.9.0.rc7/lib/faraday/options.rb:19:in 'each'
from /Users/user/.rvm/gems/ruby-2.1.1/gems/faraday-0.9.0.rc7/lib/faraday/options.rb:19:in 'update'
from /Users/user/.rvm/gems/ruby-2.1.1/gems/faraday-0.9.0.rc7/lib/faraday/options.rb:46:in 'merge'
from /Users/user/.rvm/gems/ruby-2.1.1/gems/faraday-0.9.0.rc7/lib/faraday.rb:69:in 'new'
from /Users/user/.rvm/gems/ruby-2.1.1/gems/tumblr_client-0.8.2/lib/tumblr/connection.rb:19:in 'connection'
from /Users/user/.rvm/gems/ruby-2.1.1/gems/tumblr_client-0.8.2/lib/tumblr/request.rb:8:in 'get_response'
from /Users/user/.rvm/gems/ruby-2.1.1/gems/tumblr_client-0.8.2/lib/tumblr/request.rb:26:in 'get'
from /Users/user/.rvm/gems/ruby-2.1.1/gems/tumblr_client-0.8.2/lib/tumblr/user.rb:16:in 'likes'
from tumblr-likes-downloader4.rb:18:in '

'

Any advice gratefully received.

As a second issue (which I've yet to come up against), I have no idea how to specify the parameters for Tumblr.configure, namely:
config.consumer_key = "consumer_key"
config.consumer_secret = "consumer_secret"
config.oauth_token = "oath_token"
config.oauth_token_secret = "token_secret"

Again, thanks in advance

@vasyugan
Copy link

Same error here as with m1lner & nazzeth:

/home/xxx/.gem/ruby/2.1.0/gems/faraday-0.9.0/lib/faraday/options.rb:31:in block in update': undefined methodclient=' for #Faraday::ConnectionOptions:0x00000001ad5740 (NoMethodError)
from /home/xxx/.gem/ruby/2.1.0/gems/faraday-0.9.0/lib/faraday/options.rb:20:in each' from /home/xx/.gem/ruby/2.1.0/gems/faraday-0.9.0/lib/faraday/options.rb:20:inupdate'
from /home/xxx/.gem/ruby/2.1.0/gems/faraday-0.9.0/lib/faraday/options.rb:52:in merge' from /home/xxx/.gem/ruby/2.1.0/gems/faraday-0.9.0/lib/faraday.rb:69:innew'
from /home/xxx/.gem/ruby/2.1.0/gems/tumblr_client-0.8.2/lib/tumblr/connection.rb:19:in connection' from /home/xxx/.gem/ruby/2.1.0/gems/tumblr_client-0.8.2/lib/tumblr/request.rb:8:inget_response'
from /home/xxx/.gem/ruby/2.1.0/gems/tumblr_client-0.8.2/lib/tumblr/request.rb:26:in get' from /home/xxx/.gem/ruby/2.1.0/gems/tumblr_client-0.8.2/lib/tumblr/user.rb:16:inlikes'
from /home/xxx/bin/tumblr-likes-downloader.rb:26:in `

'

@thelowlypeon
Copy link

anyone find a solution to the NoMethodError: undefined method client='? i'm getting the same error when only using the tumblr_client`, which depends on faraday. it was working for me without issues until very recently, and now all my tests are failing.

@chufucious
Copy link

Thanks @drchris1502 - that little fix worked. Great!

@ragekit
Copy link

ragekit commented Nov 24, 2014

Maybe it could be checked if there is a ~/.tumblr file and use those credential if there is ? I have no idea on how to do it, just a suggestion.

@ragekit
Copy link

ragekit commented Nov 24, 2014

(or maybe run the tumblr command if no credential is set, then use the ~/.tumblr file, that way, everything is automatized)

@Teshka
Copy link

Teshka commented Dec 3, 2014

When I run this, I get a Faraday::SSLError (Read server certificate B: Certificate verify failed). Does anyone know how to fix this? Thanks!

@d4ni31
Copy link

d4ni31 commented Feb 4, 2015

sorry but how do i get the "require"d scripts?

@TyrantRex
Copy link

Works great, it's a shame that you can only get the last 1000 likes from tumblr though.

If you are having SSL connect errors then visit https://github.com/jnunemaker/httparty/wiki/Troubleshooting-on-Windows and follow the instructions.

@d4ni31 type this into the command line:

gem install tumblr_client
gem install mechanize

@noclue1
Copy link

noclue1 commented Oct 2, 2015

I don't have any idea at all about anything. i just installed ruby now what do i do to get this working

@zbas
Copy link

zbas commented Nov 5, 2015

You can get all your likes (that tumblr still knows about) by using the 'after' request parameter https://www.tumblr.com/docs/en/api/v2#blog-likes, you can store how far you've gone back so far by inspecting the 'liked_timestamp' fields in the return object. I made a working hack as a fork.

@JoelOkimoto
Copy link

I get the error:

tumblr-likes-downloader.rb:32:in `<main>': bad value for range (ArgumentError)

Does anybody know how to solve this?

Copy link

ghost commented Dec 25, 2015

Hello sir, I get an error.
///
C:/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/specification.rb:2283:in raise_if_conflicts': Unable to activate mechanize-2.7.3, because mime-types-3.0 conflicts with mime-types (~> 2.0) (Gem::ConflictError) from C:/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/specification.rb:1406:inactivate'
from C:/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems.rb:195:in rescue in try_activate' from C:/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems.rb:192:intry_activate'
from C:/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:124:in rescue in require' from C:/Ruby22/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:39:inrequire'
from tumblr-likes-downloader.rb:2:in `

'

///
Okay, so i deleted mimetypes 3.0 and installed 2.0
Now i get this :
///
C:/Ruby22/lib/ruby/2.2.0/net/http.rb:923:in connect': SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (Faraday::SSLError) from C:/Ruby22/lib/ruby/2.2.0/net/http.rb:923:inblock in connect'
from C:/Ruby22/lib/ruby/2.2.0/timeout.rb:73:in timeout' from C:/Ruby22/lib/ruby/2.2.0/net/http.rb:923:inconnect'
from C:/Ruby22/lib/ruby/2.2.0/net/http.rb:863:in do_start' from C:/Ruby22/lib/ruby/2.2.0/net/http.rb:852:instart'
from C:/Ruby22/lib/ruby/2.2.0/net/http.rb:1375:in request' from C:/Ruby22/lib/ruby/2.2.0/net/http.rb:1133:inget'
from C:/Ruby22/lib/ruby/gems/2.2.0/gems/faraday-0.9.2/lib/faraday/adapter/net_http.rb:80:in perform_request' from C:/Ruby22/lib/ruby/gems/2.2.0/gems/faraday-0.9.2/lib/faraday/adapter/net_http.rb:40:inblock in call'
from C:/Ruby22/lib/ruby/gems/2.2.0/gems/faraday-0.9.2/lib/faraday/adapter/net_http.rb:87:in with_net_http_connection' from C:/Ruby22/lib/ruby/gems/2.2.0/gems/faraday-0.9.2/lib/faraday/adapter/net_http.rb:32:incall'
from C:/Ruby22/lib/ruby/gems/2.2.0/gems/faraday_middleware-0.9.2/lib/faraday_middleware/response_middleware.rb:30:in call' from C:/Ruby22/lib/ruby/gems/2.2.0/gems/faraday-0.9.2/lib/faraday/request/url_encoded.rb:15:incall'
from C:/Ruby22/lib/ruby/gems/2.2.0/gems/faraday-0.9.2/lib/faraday/request/multipart.rb:14:in call' from C:/Ruby22/lib/ruby/gems/2.2.0/gems/faraday_middleware-0.9.2/lib/faraday_middleware/request/oauth.rb:42:incall'
from C:/Ruby22/lib/ruby/gems/2.2.0/gems/faraday-0.9.2/lib/faraday/rack_builder.rb:139:in build_response' from C:/Ruby22/lib/ruby/gems/2.2.0/gems/faraday-0.9.2/lib/faraday/connection.rb:377:inrun_request'
from C:/Ruby22/lib/ruby/gems/2.2.0/gems/faraday-0.9.2/lib/faraday/connection.rb:140:in get' from C:/Ruby22/lib/ruby/gems/2.2.0/gems/tumblr_client-0.8.5/lib/tumblr/request.rb:8:inget_response'
from C:/Ruby22/lib/ruby/gems/2.2.0/gems/tumblr_client-0.8.5/lib/tumblr/request.rb:26:in get' from C:/Ruby22/lib/ruby/gems/2.2.0/gems/tumblr_client-0.8.5/lib/tumblr/user.rb:16:inlikes'
from tumblr-likes-downloader.rb:25:in `

'

///
please help, i've been trying to get it to work for the last 3 days.
This is my first experience with ruby and programming,
Not getting much out of it so far.

@yurijmi
Copy link

yurijmi commented Feb 17, 2016

Kudos for using Ruby

@Neofaucheur
Copy link

@pfoax as far as I can tell it's because tumblr no longer support SSLv3 (which is normal, since it was definitively dropped and replaced by TLS) and tumblr_client still try to use it.

@andrscrrn
Copy link

I created a javascript version of this and it's called tumblr-lks-downldr.You can use it as an NPM module (https://www.npmjs.com/package/tumblr-lks-downldr) or as a CLI tool (https://www.npmjs.com/package/tumblr-lks-downldr-cli). I would suggest the second one if you just one to download the liked posts without writing any code.

Please let me know if that works.

@digudc
Copy link

digudc commented Sep 6, 2016

hello geeks,
i am don't know nothing about ruby and programming in windows. could anybody please help me with step by step instructions to get my liked photos
i have downloaded ruby and notepate++ and saved this above script . as ruby format and run from admin cmd console .. after i get this error message

c:>"Users\xxxxx\Desktop\tumblr-likes-downloader.rb"
C:/Ruby23-x64/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in require' : cannot load such file -- tumblr_client (LoadError) from C:/Ruby23-x64/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55 :inrequire'
from C:/Users/xxxxxx/Desktop/tumblr-likes-downloader.rb:1:in `

'

Many thanks ..

@martinoskam
Copy link

martinoskam commented Jan 8, 2017

Not pretending to have any major knowledge about ruby or programming in general. However, some questions above are pretty basic so i’ll write down the steps i took to make this work on my mac. I used the fork zbas made since i had more than 1000 likes to download.

  • Register a tumblr app to get the consumer_key and the consumer_secret.
    You can do this here: www.tumblr.com/oauth/apps
  • Use the in browser tumblr_api console tumblr provides to get the oauth_token and oath_token_secret for my tumblr account.
    This can be had here: https://api.tumblr.com/console/
  • Paste all of the above in the script fork of zbas.
  • install the latest version of ruby using homebrew
    Command in terminal in iMac: brew install ruby
  • Clone the git repository for the required gem tumblr_client to get the before functionality since this is only contained in the master version.
    Command in terminal on iMac: git clone https://github.com/tumblr/tumblr_client.git
  • Build the tumblr_client gem from the cloned repository.
    Command in terminal on iMac(in the repository directory): gem build tumblr_client.gemspec
  • Install both the generated tumblr_client gem and the required mechanize gem.
    Commands in terminal on iMac(in the repository directory to pick the correct client):
    gem install tumblr_client-0.8.5.gem
    gem install mechanize
  • run the ruby script in terminal using the command:
    ruby tumblr-likes-downloader.rb

Many thanks to all who contributed and mbas for his fork.

Copy link

ghost commented Jan 13, 2017

I am getting this error (Mac OS Sierra):

tumblr-likes-downloader.rb:37:in <main>': undefined method each' for nil:NilClass (NoMethodError)

Any advice?

@neuro-sys
Copy link

If you are not able to run this, here I made one as well:

https://github.com/neuro-sys/tumblr-downloader-client

@gonejack
Copy link

If any one like node.js, I made one too https://github.com/gonejack/tumblr-likes-downloader

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment