tumblr-sync 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- N2E1Yjc4NTJmNjVmY2U4ZTNjZDAyYWU3MjdmYzJjN2M3ZjMzMTc0NA==
5
- data.tar.gz: !binary |-
6
- ODFlMWVjOTdmNTc0NzgyNGFmZDU1Y2VjMzljZmNhYjBhMDU5ZWUxNA==
7
- !binary "U0hBNTEy":
8
- metadata.gz: !binary |-
9
- YWUzMzk5ZDQ2ZDNiZjIzNGEwOThmOGUxMWY3ZmI0YTAwZTgwY2ZkODQwN2Zk
10
- NTkyOTY4ZjdiMGI4ZDhjY2ZjOTNlNmM5Yzc1NzdmYWQ3MjJiNDZhOWQwYzc5
11
- ZWM2OWUxMzEzYjcyMWFhZTJmNmJlYzk4YzEyYTMyMmNkODU4MGQ=
12
- data.tar.gz: !binary |-
13
- MTM4YmEwM2IwYjg4YTZhZmMyZGRmYmU2MDg5M2IyOWQ0ODk1OWZlNmExYjJj
14
- OTI3NmRmMDU2OWVhZTc5MWM4YjUwYmZmZTk3MTllNzA1N2Y5ZDRiNzQ0ZDFi
15
- YzYxNWM3ZmY3YzVhMDdlNzE4ZWIzNWI0NjBiZjBmNzg2ZGM2ZDg=
2
+ SHA1:
3
+ metadata.gz: 4c7ca6b3b3e4b62a67f38becef728495e1669df1
4
+ data.tar.gz: a559f845a2bebabeec7efaadb019300ddf642f1d
5
+ SHA512:
6
+ metadata.gz: 5e3eb49cc10633af64c5b1425ff2a04c5c3d0872efbbfb241d31f290221802d1678dd7d76c123eff344f47f6cdcd4d8cf2e5e0b60c8c6169f5deaa479138328c
7
+ data.tar.gz: 13b4a9f16319db3406525bc31b584008fee41c8b2ac96a36415c3c62e76c5a82a8d16106b8f30fa41466db8210b8108aedf738a57b52fca24d1a5a6dc3e7f6f7
checksums.yaml.gz.sig ADDED
@@ -0,0 +1,2 @@
1
+  8�ŭO�)fz�c[��\���\uw�ƕ�e���_l�H�5�� 5��ӗ�,��.�*0�q33&�\ �}aH��u�^�jQ�ó��O� &���#L#�j~�_��XG���ά�
2
+ ?�()��RK/� ����
data.tar.gz.sig ADDED
Binary file
data/.gitignore CHANGED
@@ -14,4 +14,4 @@ rdoc
14
14
  spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
- tmp
17
+ tmp
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
data/Gemfile CHANGED
@@ -1,4 +1,3 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in default_bundler_gem.gemspec
4
3
  gemspec
data/README.md CHANGED
@@ -1,26 +1,16 @@
1
- # tumblr-sync
1
+ # TumblrSync
2
2
 
3
3
  MultiThread Tumblr Synchronization
4
4
 
5
- You like download and fill your hard drive with tons of funny pictures, this is the tool for you!
5
+ You like download and fill your hard drive with tons of funny pictures, this tool is for you!
6
6
 
7
- ## Installation
7
+ ## Install
8
8
 
9
- Add this line to your application's Gemfile:
10
-
11
- gem 'tumblr-sync'
12
-
13
- And then execute:
14
-
15
- $ bundle
16
-
17
- Or install it yourself as:
18
-
19
- $ gem install tumblr-sync
9
+ gem install tumblr-sync
20
10
 
21
11
  ## Usage
22
12
 
23
- Synchronize some funny Tumblr with a lot of so cute catz !
13
+ Synchronize some funny tumblr with a lot of so cute catz!
24
14
 
25
15
  tumblr-sync socutecatz.tumblr.com
26
16
 
@@ -28,11 +18,6 @@ Synchronize some funny Tumblr with a lot of so cute catz !
28
18
 
29
19
  Ruby Multithreading and Queue testing for fun
30
20
 
31
- ## Todo
32
-
33
- * Improve multithreading
34
- * Add some tests (han! there's no tests! so wrong…)
35
-
36
21
  ## Contributing
37
22
 
38
23
  1. Fork it
@@ -40,7 +25,3 @@ Ruby Multithreading and Queue testing for fun
40
25
  3. Commit your changes (`git commit -am 'Add some feature'`)
41
26
  4. Push to the branch (`git push origin my-new-feature`)
42
27
  5. Create new Pull Request
43
-
44
- ## Copyright
45
-
46
- Copyright (c) 2013 Vincent Durand. See LICENSE.txt for further details.
data/Rakefile CHANGED
@@ -1,8 +1,8 @@
1
- require "bundler/gem_tasks"
2
- require "rake/testtask"
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
3
 
4
4
  Rake::TestTask.new(:test) do |t|
5
5
  t.libs << "test"
6
6
  end
7
7
 
8
- task :default => :test
8
+ task default: :test
data/bin/tumblr-sync CHANGED
@@ -1,12 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
4
-
3
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "/../lib"))
5
4
  require 'tumblr-sync'
6
5
 
7
- begin
8
- runner = TumblrSync::Runner.new(ARGV)
9
- runner.run
10
- rescue Mechanize::ResponseCodeError, SocketError
11
- puts "Tumblr API not found !"
12
- end
6
+ runner = TumblrSync::Runner.new(ARGV)
7
+ runner.run
data/lib/tumblr-sync.rb CHANGED
@@ -1,6 +1,9 @@
1
- require 'mechanize'
1
+ require 'tumblr-sync/version'
2
+ require 'net/http'
3
+ require 'uri'
2
4
 
3
5
  module TumblrSync
4
- autoload :Runner, 'tumblr-sync/runner'
5
- autoload :Site, 'tumblr-sync/site'
6
- end
6
+ autoload :Tumblr, 'tumblr-sync/tumblr'
7
+ autoload :Runner, 'tumblr-sync/runner'
8
+ autoload :PhotoFetcher, 'tumblr-sync/photo_fetcher'
9
+ end
@@ -0,0 +1,18 @@
1
+ require 'mechanize'
2
+
3
+ module TumblrSync
4
+ class PhotoFetcher
5
+ def initialize(directory = ".")
6
+ @directory = directory
7
+ end
8
+
9
+ def fetch(url)
10
+ return if File.exists? File.join(@directory, Mechanize::File.new(URI(url)).filename)
11
+ http = Mechanize.new
12
+ http.get(url) do |page|
13
+ return if File.exists? filename = File.join(@directory, File.basename(page.uri.path))
14
+ page.save filename
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,75 +1,69 @@
1
1
  require 'optparse'
2
- require 'thread'
2
+ require 'fileutils'
3
3
  require 'ruby-progressbar'
4
+ require 'thread'
4
5
 
5
6
  module TumblrSync
6
7
  class Runner
7
- CONCURRENCY = 12
8
-
9
8
  def initialize(arguments)
9
+ @options = OptionParser.new
10
10
  @arguments = arguments
11
11
  end
12
-
12
+
13
13
  def run
14
- parse_options
15
-
16
- @concurrency ||= CONCURRENCY
17
- @tumblr = TumblrSync::Site.new(@arguments.last)
18
- @progress = ProgressBar.create(:format => '%a |%B| %c/%C - %p%%', :starting_at => 0, :total => @tumblr.total)
19
-
20
- FileUtils.mkdir_p(@tumblr.host)
21
-
14
+ parse_options!
15
+
16
+ tumblr = TumblrSync::Tumblr.new @arguments.last
17
+ progress_bar = ProgressBar.create format: '%a |%B| %c/%C - %p%%', starting_at: 0, total: tumblr.total
18
+ photo_fetcher = PhotoFetcher.new tumblr.host
19
+
20
+ FileUtils.mkdir_p tumblr.host
21
+
22
22
  queue = Queue.new
23
- @tumblr.times do |i|
24
- Thread.new { queue << @tumblr.images(i*MAX, MAX) }
23
+ tumblr.times do |i|
24
+ Thread.new { queue << tumblr.images(i*MAX, MAX) }
25
25
  end
26
-
26
+
27
27
  downloader = Thread.new do
28
- @tumblr.times do
28
+ tumblr.times do
29
29
  images = queue.pop
30
- images.each_slice(@concurrency).each do |group|
30
+ images.each_slice(10).each do |group|
31
31
  threads = []
32
32
  group.each do |url|
33
33
  threads << Thread.new {
34
34
  begin
35
- file = Mechanize::File.new(URI(url))
36
- unless File.exists?("#{@tumblr.host}/#{file.filename}")
37
- http = Mechanize.new
38
- http.get(url) do |page|
39
- filename = page.uri.path.split(/\//).last
40
- next if File.exists?("#{@tumblr.host}/#{filename}")
41
- page.save("#{@tumblr.host}/#{filename}")
42
- end
43
- end
35
+ photo_fetcher.fetch url
44
36
  rescue Mechanize::ResponseCodeError
45
37
  ensure
46
- @progress.increment
38
+ progress_bar.increment
47
39
  end
48
40
  }
49
41
  end
50
- threads.each{ |thread| thread.join }
42
+ threads.each(&:join)
51
43
  end
52
44
  end
53
45
  end
54
-
46
+
55
47
  downloader.join
48
+ rescue SocketError
49
+ puts "Tumblr API not found!"
50
+ puts @options
51
+ exit
56
52
  end
57
-
53
+
58
54
  private
59
-
60
- def parse_options
61
- options = OptionParser.new
62
- options.banner = "Usage: #{$0} [options] [tumblr]"
63
- options.on('-c', '--concurrency NUMBER', "Specify concurrency option (Default: #{CONCURRENCY})") { |concurrency| @concurrency = concurrency.to_i }
64
- options.on('-h', '--help', "Show this message") { puts(options); exit }
55
+
56
+ def parse_options!
57
+ @options.banner = "Usage: #{$0} [tumblr]"
58
+ @options.on('-h', '--help', "Show this message") { puts(@options); exit }
65
59
  begin
66
- raise "Missing argument tumblr website" if ARGV.empty?
67
- options.parse!(@arguments)
60
+ raise "Missing argument tumblr url" if @arguments.empty?
61
+ @options.parse! @arguments
68
62
  rescue => ex
69
63
  puts ex.message
70
- puts options
64
+ puts @options
71
65
  exit
72
66
  end
73
67
  end
74
68
  end
75
- end
69
+ end
@@ -0,0 +1,45 @@
1
+ require 'forwardable'
2
+ require 'nokogiri'
3
+
4
+ module TumblrSync
5
+ MAX = 50
6
+
7
+ class Tumblr
8
+ extend Forwardable
9
+
10
+ attr_accessor :host
11
+
12
+ def initialize(host)
13
+ @host = host
14
+ end
15
+
16
+ def images(start, number = MAX)
17
+ response = Net::HTTP.get_response uri_endpoint(type: :photo, start: start, num: number)
18
+ doc = Nokogiri::XML.parse response.body
19
+ doc.xpath("//posts/post/photo-url[@max-width='1280']").map { |url| url.text.strip }
20
+ end
21
+
22
+ def total
23
+ response = Net::HTTP.get_response uri_endpoint(type: :photo)
24
+ doc = Nokogiri::XML.parse response.body
25
+ doc.xpath("//posts/@total").text.to_i
26
+ end
27
+
28
+ def times(&block)
29
+ (total.to_f / MAX + 0.5).round.times(&block)
30
+ end
31
+ def_delegator :times, :count
32
+
33
+ private
34
+
35
+ def endpoint
36
+ "http://#{host}/api/read"
37
+ end
38
+
39
+ def uri_endpoint(params = {})
40
+ URI.parse(endpoint).tap do |uri|
41
+ uri.query = URI.encode_www_form params
42
+ end
43
+ end
44
+ end
45
+ end
@@ -1,3 +1,3 @@
1
1
  module TumblrSync
2
- VERSION = "0.1.3"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -0,0 +1,63 @@
1
+ <tumblr version="1.0">
2
+ <tumblelog name="citieslight" timezone="Europe/Kiev" title="My cute & fashion blog"/>
3
+ <posts type="photo" start="0" total="2721">
4
+ <post id="36979072885" url="http://citieslight.tumblr.com/post/36979072885" url-with-slug="http://citieslight.tumblr.com/post/36979072885/adv-up-to-50-on-sleepwear-on-amazon" type="photo" date-gmt="2012-12-01 21:43:00 GMT" date="Sat, 01 Dec 2012 23:43:00" unix-timestamp="1354398180" format="html" reblog-key="N0IpSA7d" slug="adv-up-to-50-on-sleepwear-on-amazon" width="500" height="667">
5
+ <photo-caption>
6
+ <p><em>Adv</em><br/><strong><a target="_blank" href="http://www.amazon.com/b/?_encoding=UTF8&amp;camp=1789&amp;creative=9325&amp;linkCode=ur2&amp;node=6064498011&amp;pf_rd_i=49957011&amp;pf_rd_m=ATVPDKIKX0DER&amp;pf_rd_p=1429511462&amp;pf_rd_r=079Q8S9ETS7W48XA7XCP&amp;pf_rd_s=center-2&amp;pf_rd_t=101&amp;tag=amazingamaz06-20">Up to 50% on sleepwear on AMAZON!</a></strong> </p>
7
+ </photo-caption>
8
+ <photo-link-url>http://citieslight.tumblr.com/</photo-link-url>
9
+ <photo-url max-width="1280">
10
+ http://24.media.tumblr.com/tumblr_mebokdGrmq1rjwt7po1_500.jpg
11
+ </photo-url>
12
+ <photo-url max-width="500">
13
+ http://24.media.tumblr.com/tumblr_mebokdGrmq1rjwt7po1_500.jpg
14
+ </photo-url>
15
+ <photo-url max-width="400">
16
+ http://25.media.tumblr.com/tumblr_mebokdGrmq1rjwt7po1_400.jpg
17
+ </photo-url>
18
+ <photo-url max-width="250">
19
+ http://25.media.tumblr.com/tumblr_mebokdGrmq1rjwt7po1_250.jpg
20
+ </photo-url>
21
+ <photo-url max-width="100">
22
+ http://25.media.tumblr.com/tumblr_mebokdGrmq1rjwt7po1_100.jpg
23
+ </photo-url>
24
+ <photo-url max-width="75">
25
+ http://31.media.tumblr.com/tumblr_mebokdGrmq1rjwt7po1_75sq.jpg
26
+ </photo-url>
27
+ <tag>girl</tag>
28
+ <tag>teen</tag>
29
+ <tag>hipster</tag>
30
+ <tag>look</tag>
31
+ <tag>clothes</tag>
32
+ </post>
33
+ <post id="36977835193" url="http://citieslight.tumblr.com/post/36977835193" url-with-slug="http://citieslight.tumblr.com/post/36977835193/adv-sign-up-now-and-find-out-what-is-your-shoe" type="photo" date-gmt="2012-12-01 21:25:32 GMT" date="Sat, 01 Dec 2012 23:25:32" unix-timestamp="1354397132" format="html" reblog-key="T02PpdOt" slug="adv-sign-up-now-and-find-out-what-is-your-shoe" width="498" height="750">
34
+ <photo-caption>
35
+ <p><em>Adv</em><br/><strong><a href="http://citieslight.tumblr.com/post/36902464817/sign-up-now-and-find-out-what-is-your-shoe-style" target="_blank">Sign up now and find out what is your shoe style now&#160;»</a></strong> </p>
36
+ </photo-caption>
37
+ <photo-link-url>http://citieslight.tumblr.com/</photo-link-url>
38
+ <photo-url max-width="1280">
39
+ http://25.media.tumblr.com/tumblr_mebojvwCIb1rjwt7po1_500.jpg
40
+ </photo-url>
41
+ <photo-url max-width="500">
42
+ http://25.media.tumblr.com/tumblr_mebojvwCIb1rjwt7po1_500.jpg
43
+ </photo-url>
44
+ <photo-url max-width="400">
45
+ http://24.media.tumblr.com/tumblr_mebojvwCIb1rjwt7po1_400.jpg
46
+ </photo-url>
47
+ <photo-url max-width="250">
48
+ http://25.media.tumblr.com/tumblr_mebojvwCIb1rjwt7po1_250.jpg
49
+ </photo-url>
50
+ <photo-url max-width="100">
51
+ http://31.media.tumblr.com/tumblr_mebojvwCIb1rjwt7po1_100.jpg
52
+ </photo-url>
53
+ <photo-url max-width="75">
54
+ http://24.media.tumblr.com/tumblr_mebojvwCIb1rjwt7po1_75sq.jpg
55
+ </photo-url>
56
+ <tag>girl</tag>
57
+ <tag>sexy</tag>
58
+ <tag>hipster</tag>
59
+ <tag>look</tag>
60
+ <tag>clothes</tag>
61
+ </post>
62
+ </posts>
63
+ </tumblr>
Binary file
@@ -1,4 +1,6 @@
1
1
  $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
-
3
2
  require 'tumblr-sync'
4
3
  require 'minitest/autorun'
4
+ require 'webmock/minitest'
5
+
6
+ WebMock.disable_net_connect!
@@ -0,0 +1,44 @@
1
+ require 'minitest_helper'
2
+
3
+ describe TumblrSync::Tumblr do
4
+ let(:fetcher) { TumblrSync::PhotoFetcher.new "tmp" }
5
+
6
+ after { FileUtils.rm_rf "tmp" }
7
+
8
+ describe "without redirect" do
9
+ before do
10
+ stub_request(:get, "foo.tumblr.com/tumblr.png").to_return(body: File.new('test/fixtures/tumblr.png'), status: 200)
11
+ fetcher.fetch("http://foo.tumblr.com/tumblr.png")
12
+ end
13
+
14
+ it { fetcher.instance_variable_get('@directory').must_equal "tmp" }
15
+
16
+ it "should fetch url" do
17
+ File.read('test/fixtures/tumblr.png').must_equal File.read('tmp/tumblr.png')
18
+ assert_requested :get, "http://foo.tumblr.com/tumblr.png", times: 1
19
+ end
20
+
21
+ it "should not fetch existing file" do
22
+ fetcher.fetch("http://foo.tumblr.com/tumblr.png").must_be_nil
23
+ assert_requested :get, "http://foo.tumblr.com/tumblr.png", times: 1
24
+ end
25
+ end
26
+
27
+ describe "with redirect" do
28
+ before do
29
+ stub_request(:get, "foo.tumblr.com/picture-1234").to_return(headers: { 'Location' => 'http://foo.tumblr.com/tumblr.png' }, status: 301)
30
+ stub_request(:get, "foo.tumblr.com/tumblr.png").to_return(body: File.new('test/fixtures/tumblr.png'), status: 200)
31
+ fetcher.fetch("http://foo.tumblr.com/picture-1234")
32
+ end
33
+
34
+ it "should fetch url" do
35
+ File.read('test/fixtures/tumblr.png').must_equal File.read('tmp/tumblr.png')
36
+ assert_requested :get, "http://foo.tumblr.com/picture-1234", times: 1
37
+ assert_requested :get, "http://foo.tumblr.com/tumblr.png", times: 1
38
+ end
39
+
40
+ it "should not save existing file" do
41
+ fetcher.fetch("http://foo.tumblr.com/picture-1234").must_be_nil
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,46 @@
1
+ require 'minitest_helper'
2
+
3
+ describe TumblrSync::Tumblr do
4
+ let(:tumblr) { TumblrSync::Tumblr.new "foo.tumblr.com" }
5
+
6
+ it { TumblrSync::MAX.must_equal 50 }
7
+
8
+ it "should get host" do
9
+ tumblr.host.must_equal "foo.tumblr.com"
10
+ end
11
+
12
+ it "should get endpoint" do
13
+ tumblr.send(:endpoint).must_equal "http://foo.tumblr.com/api/read"
14
+ end
15
+
16
+ it "should update host" do
17
+ tumblr.host = "bar.tumblr.com"
18
+ tumblr.host.must_equal "bar.tumblr.com"
19
+ end
20
+
21
+ it "should update endpoint" do
22
+ tumblr.host = "bar.tumblr.com"
23
+ tumblr.send(:endpoint).must_equal "http://bar.tumblr.com/api/read"
24
+ end
25
+
26
+ it "should get array of images" do
27
+ stub_request(:get, "foo.tumblr.com/api/read").with(query: { type: :photo, start: 0, num: 2 }).to_return(body: File.new('test/fixtures/api.xml'), status: 200)
28
+ tumblr.images(0, 2).must_equal ["http://24.media.tumblr.com/tumblr_mebokdGrmq1rjwt7po1_500.jpg", "http://25.media.tumblr.com/tumblr_mebojvwCIb1rjwt7po1_500.jpg"]
29
+ end
30
+
31
+ it "should get total of images" do
32
+ stub_request(:get, "foo.tumblr.com/api/read").with(query: { type: :photo }).to_return(body: File.new('test/fixtures/api.xml'), status: 200)
33
+ tumblr.total.must_equal 2721
34
+ end
35
+
36
+ it "should get cycles to retrieve all pictures" do
37
+ stub_request(:get, "foo.tumblr.com/api/read").with(query: { type: :photo }).to_return(body: File.new('test/fixtures/api.xml'), status: 200)
38
+ tumblr.times.must_be_instance_of Enumerator
39
+ tumblr.count.must_equal 55
40
+ end
41
+
42
+ it "should get the uri endpoint" do
43
+ tumblr.send(:uri_endpoint).must_equal URI("http://foo.tumblr.com/api/read?")
44
+ tumblr.send(:uri_endpoint, { type: :photo }).must_equal URI("http://foo.tumblr.com/api/read?type=photo")
45
+ end
46
+ end
data/tumblr-sync.gemspec CHANGED
@@ -1,15 +1,14 @@
1
1
  # coding: utf-8
2
2
  lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
-
5
4
  require 'tumblr-sync/version'
6
5
 
7
6
  Gem::Specification.new do |spec|
8
7
  spec.name = "tumblr-sync"
9
8
  spec.version = TumblrSync::VERSION
10
- spec.authors = ["Vincent Durand"]
11
- spec.email = ["vincent.durand@madwork.org"]
12
- spec.description = "Synchronize pictures from a Tumblr blog, with multithreading"
9
+ spec.author = "Vincent Durand"
10
+ spec.email = "vincent.durand@madwork.org"
11
+ spec.description = "Synchronize pictures from a Tumblr blog with ease and faster than ever!"
13
12
  spec.summary = "Synchronize pictures from a Tumblr blog"
14
13
  spec.license = "MIT"
15
14
 
@@ -18,10 +17,12 @@ Gem::Specification.new do |spec|
18
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
18
  spec.require_paths = ["lib"]
20
19
 
21
- spec.add_runtime_dependency "mechanize", "~> 2.7.2"
22
- spec.add_runtime_dependency "ruby-progressbar", "~> 1.2.0"
23
-
24
- spec.add_development_dependency "bundler", ">= 1.3"
20
+ spec.add_development_dependency "bundler", "~> 1.3"
25
21
  spec.add_development_dependency "rake"
26
22
  spec.add_development_dependency "minitest"
23
+ spec.add_development_dependency "webmock"
24
+
25
+ spec.add_runtime_dependency "nokogiri", "~> 1.6.0"
26
+ spec.add_runtime_dependency "mechanize", "~> 2.7.0"
27
+ spec.add_runtime_dependency "ruby-progressbar", "~> 1.2.0"
27
28
  end
metadata CHANGED
@@ -1,106 +1,160 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tumblr-sync
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vincent Durand
8
8
  autorequire:
9
9
  bindir: bin
10
- cert_chain: []
11
- date: 2013-09-18 00:00:00.000000000 Z
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIIDkjCCAnqgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMRcwFQYDVQQDDA52aW5j
14
+ ZW50LmR1cmFuZDEXMBUGCgmSJomT8ixkARkWB21hZHdvcmsxEzARBgoJkiaJk/Is
15
+ ZAEZFgNvcmcwHhcNMTMwOTE4MTY0MDEwWhcNMTQwOTE4MTY0MDEwWjBHMRcwFQYD
16
+ VQQDDA52aW5jZW50LmR1cmFuZDEXMBUGCgmSJomT8ixkARkWB21hZHdvcmsxEzAR
17
+ BgoJkiaJk/IsZAEZFgNvcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
18
+ AQDzlsghBvfbH4yPzi3dXyfkmxjy/uksOkYwzqwbZ6z/TvJdIjY9Xqi/gLe2AxGF
19
+ kuVxDuxih84WDG8qxCnAfUxt2nDGAVEspmTXHBAsyZqLLDRiP5LvmH/eAKsJY+rU
20
+ ERSJOaLAotMqHHqXiWnpRgFnzE6RM3Cnqq8LH0jIGF9F8gZVLZeRD+VXK4IX1Vyd
21
+ HgZKgTPL15k92u7bzqBw7niPCBa9LfYxID6E1bnSHw/kb+7hWarVd/sxpgeH0jgb
22
+ f8ieDs8S9+bL/TfzEDAOALAqMDgPXPX1mDKESDZ/wBGW/tP3NSbVKsSZFK8b0e00
23
+ Au/fVbAe+P7+T8po/a5UhjMbAgMBAAGjgYgwgYUwCQYDVR0TBAIwADALBgNVHQ8E
24
+ BAMCBLAwHQYDVR0OBBYEFKne49vGKR3nRMYhyEbJDI2BVQikMCUGA1UdEQQeMByB
25
+ GnZpbmNlbnQuZHVyYW5kQG1hZHdvcmsub3JnMCUGA1UdEgQeMByBGnZpbmNlbnQu
26
+ ZHVyYW5kQG1hZHdvcmsub3JnMA0GCSqGSIb3DQEBBQUAA4IBAQB0EDvvwy8uol26
27
+ Xm4O1iYcfgkTTX11UwgI6XIbS+1AzUwhl4BdWWFFxcy7v2/UMcx4QaJm+tL2B05V
28
+ CcVFS8tOMaGk6s7fPdhFswRp+HE9Ex5aiCMAhoIdUbrR5LCJTWyiEBLJhforT+3R
29
+ RARQ4FabsVVHevPHxzEAUGGGdWzbG4BcvKpWxbsOz/6yVgy3dpscmanMPH6pBpNH
30
+ XD6+HDD0HP0RBeQtHV2LIhLpiJLmNWRmJ9/Cfry72diEnM7173RAelpJNj0kRYjJ
31
+ xDr7hfCTJQsNosd7V5q7Uz+SYPK9ALyONt5t3KKYEWS/mBCStEuQXwjIsWG/bqwr
32
+ vqfQstIS
33
+ -----END CERTIFICATE-----
34
+ date: 2013-12-17 00:00:00.000000000 Z
12
35
  dependencies:
13
36
  - !ruby/object:Gem::Dependency
14
- name: mechanize
37
+ name: bundler
15
38
  requirement: !ruby/object:Gem::Requirement
16
39
  requirements:
17
40
  - - ~>
18
41
  - !ruby/object:Gem::Version
19
- version: 2.7.2
20
- type: :runtime
42
+ version: '1.3'
43
+ type: :development
21
44
  prerelease: false
22
45
  version_requirements: !ruby/object:Gem::Requirement
23
46
  requirements:
24
47
  - - ~>
25
48
  - !ruby/object:Gem::Version
26
- version: 2.7.2
49
+ version: '1.3'
27
50
  - !ruby/object:Gem::Dependency
28
- name: ruby-progressbar
51
+ name: rake
29
52
  requirement: !ruby/object:Gem::Requirement
30
53
  requirements:
31
- - - ~>
54
+ - - '>='
32
55
  - !ruby/object:Gem::Version
33
- version: 1.2.0
34
- type: :runtime
56
+ version: '0'
57
+ type: :development
35
58
  prerelease: false
36
59
  version_requirements: !ruby/object:Gem::Requirement
37
60
  requirements:
38
- - - ~>
61
+ - - '>='
39
62
  - !ruby/object:Gem::Version
40
- version: 1.2.0
63
+ version: '0'
41
64
  - !ruby/object:Gem::Dependency
42
- name: bundler
65
+ name: minitest
43
66
  requirement: !ruby/object:Gem::Requirement
44
67
  requirements:
45
- - - ! '>='
68
+ - - '>='
46
69
  - !ruby/object:Gem::Version
47
- version: '1.3'
70
+ version: '0'
48
71
  type: :development
49
72
  prerelease: false
50
73
  version_requirements: !ruby/object:Gem::Requirement
51
74
  requirements:
52
- - - ! '>='
75
+ - - '>='
53
76
  - !ruby/object:Gem::Version
54
- version: '1.3'
77
+ version: '0'
55
78
  - !ruby/object:Gem::Dependency
56
- name: rake
79
+ name: webmock
57
80
  requirement: !ruby/object:Gem::Requirement
58
81
  requirements:
59
- - - ! '>='
82
+ - - '>='
60
83
  - !ruby/object:Gem::Version
61
84
  version: '0'
62
85
  type: :development
63
86
  prerelease: false
64
87
  version_requirements: !ruby/object:Gem::Requirement
65
88
  requirements:
66
- - - ! '>='
89
+ - - '>='
67
90
  - !ruby/object:Gem::Version
68
91
  version: '0'
69
92
  - !ruby/object:Gem::Dependency
70
- name: minitest
93
+ name: nokogiri
71
94
  requirement: !ruby/object:Gem::Requirement
72
95
  requirements:
73
- - - ! '>='
96
+ - - ~>
74
97
  - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
98
+ version: 1.6.0
99
+ type: :runtime
77
100
  prerelease: false
78
101
  version_requirements: !ruby/object:Gem::Requirement
79
102
  requirements:
80
- - - ! '>='
103
+ - - ~>
81
104
  - !ruby/object:Gem::Version
82
- version: '0'
83
- description: Synchronize pictures from a Tumblr blog, with multithreading
84
- email:
85
- - vincent.durand@madwork.org
105
+ version: 1.6.0
106
+ - !ruby/object:Gem::Dependency
107
+ name: mechanize
108
+ requirement: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ~>
111
+ - !ruby/object:Gem::Version
112
+ version: 2.7.0
113
+ type: :runtime
114
+ prerelease: false
115
+ version_requirements: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ~>
118
+ - !ruby/object:Gem::Version
119
+ version: 2.7.0
120
+ - !ruby/object:Gem::Dependency
121
+ name: ruby-progressbar
122
+ requirement: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ~>
125
+ - !ruby/object:Gem::Version
126
+ version: 1.2.0
127
+ type: :runtime
128
+ prerelease: false
129
+ version_requirements: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ~>
132
+ - !ruby/object:Gem::Version
133
+ version: 1.2.0
134
+ description: Synchronize pictures from a Tumblr blog with ease and faster than ever!
135
+ email: vincent.durand@madwork.org
86
136
  executables:
87
137
  - tumblr-sync
88
138
  extensions: []
89
139
  extra_rdoc_files: []
90
140
  files:
91
141
  - .gitignore
92
- - .ruby-version
142
+ - .travis.yml
93
143
  - Gemfile
94
144
  - LICENSE.txt
95
145
  - README.md
96
146
  - Rakefile
97
147
  - bin/tumblr-sync
98
148
  - lib/tumblr-sync.rb
149
+ - lib/tumblr-sync/photo_fetcher.rb
99
150
  - lib/tumblr-sync/runner.rb
100
- - lib/tumblr-sync/site.rb
151
+ - lib/tumblr-sync/tumblr.rb
101
152
  - lib/tumblr-sync/version.rb
153
+ - test/fixtures/api.xml
154
+ - test/fixtures/tumblr.png
102
155
  - test/minitest_helper.rb
103
- - test/test_tumblr-sync.rb
156
+ - test/test_photo_fetcher.rb
157
+ - test/test_tumblr.rb
104
158
  - tumblr-sync.gemspec
105
159
  homepage:
106
160
  licenses:
@@ -112,21 +166,23 @@ require_paths:
112
166
  - lib
113
167
  required_ruby_version: !ruby/object:Gem::Requirement
114
168
  requirements:
115
- - - ! '>='
169
+ - - '>='
116
170
  - !ruby/object:Gem::Version
117
171
  version: '0'
118
172
  required_rubygems_version: !ruby/object:Gem::Requirement
119
173
  requirements:
120
- - - ! '>='
174
+ - - '>='
121
175
  - !ruby/object:Gem::Version
122
176
  version: '0'
123
177
  requirements: []
124
178
  rubyforge_project:
125
- rubygems_version: 2.0.8
179
+ rubygems_version: 2.1.11
126
180
  signing_key:
127
181
  specification_version: 4
128
182
  summary: Synchronize pictures from a Tumblr blog
129
183
  test_files:
184
+ - test/fixtures/api.xml
185
+ - test/fixtures/tumblr.png
130
186
  - test/minitest_helper.rb
131
- - test/test_tumblr-sync.rb
132
- has_rdoc:
187
+ - test/test_photo_fetcher.rb
188
+ - test/test_tumblr.rb
metadata.gz.sig ADDED
@@ -0,0 +1 @@
1
+ <1?��~6
data/.ruby-version DELETED
@@ -1 +0,0 @@
1
- jruby
@@ -1,41 +0,0 @@
1
- module TumblrSync
2
- MAX = 50
3
-
4
- class Site
5
- extend Forwardable
6
-
7
- attr_reader :host
8
-
9
- # Example:
10
- #
11
- # t = TumblrSync::Site.new("citieslight.tumblr.com") { |a| a.user_agent_alias = 'Mac Safari' }
12
- #
13
- def initialize(host, &block)
14
- @host = host
15
- @endpoint = "http://#{host}/api/read?type=photo"
16
- @mechaconf = block
17
- end
18
-
19
- def images(start, number = MAX)
20
- http = Mechanize.new(&@mechaconf)
21
- http.get("#@endpoint&start=#{start}&num=#{number}")
22
- doc = Nokogiri::XML.parse(http.page.body)
23
- doc.xpath("//posts/post/photo-url[@max-width='1280']").map(&:text)
24
- end
25
-
26
- def total
27
- @total ||= begin
28
- http = Mechanize.new(&@mechaconf)
29
- http.get(@endpoint)
30
- doc = Nokogiri::XML.parse(http.page.body)
31
- doc.xpath("//posts/@total").text.to_i
32
- end
33
- end
34
-
35
- def times(&block)
36
- (total.to_f / MAX + 0.5).round.times(&block)
37
- end
38
-
39
- def_delegator :times, :count
40
- end
41
- end
@@ -1,7 +0,0 @@
1
- require 'minitest_helper'
2
-
3
- class TestTumblrSync < Minitest::Test
4
- def test_that_it_has_a_version_number
5
- refute_nil ::TumblrSync::VERSION
6
- end
7
- end