tumblrb 1.0.6 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,172 @@
1
+ module Tumblr
2
+ class Object
3
+ class << self
4
+ attr_accessor :page_size
5
+
6
+ def page_size
7
+ @page_size ||= 20
8
+ end
9
+
10
+ def unserialize(value)
11
+ value = JSON.parse(value)
12
+ systematize(value.first).build(value.last)
13
+ end
14
+
15
+ def systematize(string)
16
+ string = string.to_s.gsub(/^Tumblr::/, '')
17
+ "Tumblr::#{string.singularize.classify}".constantize rescue nil
18
+ end
19
+
20
+ def objectify(hash)
21
+ objectified = {}
22
+ hash.keys.each do |key|
23
+ klass = systematize(key)
24
+ if klass
25
+ if hash[key].kind_of?(Array)
26
+ objectified[key] = hash[key].collect { |value| klass.build(value) }
27
+ else
28
+ objectified[key] = klass.build(hash[key])
29
+ end
30
+ else
31
+ objectified[key] = hash[key]
32
+ end
33
+ end
34
+ objectified
35
+ end
36
+
37
+ def build(attributes)
38
+ object = new
39
+ attributes.each do |attribute, value|
40
+ if object.respond_to?("#{attribute}=")
41
+ object.send("#{attribute}=", value)
42
+ end
43
+ end
44
+ object
45
+ end
46
+
47
+ def attributes
48
+ @attributes ||= Set.new
49
+ end
50
+
51
+ def string_attribute(*args)
52
+ attr_reader *args
53
+ args.each do |arg|
54
+ attributes << arg
55
+ define_method "#{arg}=" do |value|
56
+ set_attribute_value(arg, value.to_s)
57
+ end
58
+ end
59
+ end
60
+
61
+ def array_attribute(*args)
62
+ options = args.extract_options!
63
+ attr_reader *args
64
+ klass = systematize(options[:object]) if options[:object]
65
+ args.each do |arg|
66
+ attributes << arg
67
+ define_method "#{arg}=" do |value|
68
+ if klass
69
+ set_attribute_value(arg, value.to_a.collect { |params| klass.build(params) })
70
+ else
71
+ set_attribute_value(arg, value.to_a)
72
+ end
73
+ end
74
+ end
75
+ end
76
+
77
+ def boolean_attribute(*args)
78
+ attr_reader *args
79
+ args.each do |arg|
80
+ attributes << arg
81
+ define_method "#{arg}=" do |value|
82
+ set_attribute_value(arg, !!value)
83
+ end
84
+ end
85
+ end
86
+
87
+ def numeric_attribute(*args)
88
+ attr_reader *args
89
+ args.each do |arg|
90
+ attributes << arg
91
+ define_method "#{arg}=" do |value|
92
+ value = (value.to_i == value.to_f) ? value.to_i : value.to_f
93
+ set_attribute_value(arg, value)
94
+ end
95
+ end
96
+ end
97
+
98
+ def date_attribute(*args)
99
+ attr_reader *args
100
+ args.each do |arg|
101
+ attributes << arg
102
+ define_method "#{arg}=" do |value|
103
+ value = Time.at(value) if value.kind_of?(Fixnum)
104
+ value = Date.parse(value) rescue nil if value.kind_of?(String)
105
+ value ||= value
106
+ set_attribute_value(arg, value)
107
+ end
108
+ end
109
+ end
110
+
111
+ def object_attribute(*args)
112
+ attr_reader *args
113
+ options = args.extract_options!
114
+ klass = systematize(options[:object]) if options[:object]
115
+ args.each do |arg|
116
+ attributes << arg
117
+ define_method "#{arg}=" do |value|
118
+ set_attribute_value(arg, klass.build(value))
119
+ end
120
+ end
121
+ end
122
+ end
123
+
124
+ def serialize
125
+ [self.class.to_s, as_json].to_json
126
+ end
127
+
128
+ def storage
129
+ @_storage ||= Redis::Value.new("#{Blog::STORAGE_KEY}:#{slug}", Tumblr.config.redis)
130
+ end
131
+
132
+ def commit
133
+ storage.value = serialize
134
+ end
135
+
136
+ def dom_class
137
+ self.class.to_s.split("::").last.underscore
138
+ end
139
+
140
+ def etag
141
+ Digest::SHA1.hexdigest(to_json)
142
+ end
143
+
144
+ def as_json
145
+ json = {}
146
+ self.class.attributes.each do |key|
147
+ json[key] = send(key)
148
+ end
149
+ json
150
+ end
151
+
152
+ def to_json(force=false)
153
+ @json = nil if force
154
+ @json ||= JSON.generate(as_json)
155
+ end
156
+
157
+ private
158
+
159
+ def set_attribute_value(key, value)
160
+ self.instance_variable_set("@#{key}", value)
161
+ end
162
+ end
163
+ end
164
+
165
+ require 'tumblr/objects/user'
166
+ require 'tumblr/objects/post'
167
+ require 'tumblr/objects/audio'
168
+ require 'tumblr/objects/chat'
169
+ require 'tumblr/objects/link'
170
+ require 'tumblr/objects/photo'
171
+ require 'tumblr/objects/text'
172
+ require 'tumblr/objects/video'
@@ -0,0 +1,5 @@
1
+ module Tumblr
2
+ class Answer < Post
3
+ string_attribute :asking_name, :asking_url, :question, :answer
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ module Tumblr
2
+ class Audio < Post
3
+ string_attribute :caption, :player, :album_art, :artist, :album, :track_name
4
+ numeric_attribute :plays, :track_number, :year
5
+ end
6
+ end
@@ -0,0 +1,10 @@
1
+ module Tumblr
2
+ class Chat < Post
3
+ string_attribute :title, :body
4
+ array_attribute :dialogue, :object => "chat/dialogue"
5
+
6
+ class Dialogue < Object
7
+ string_attribute :name, :label, :phrase
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,5 @@
1
+ module Tumblr
2
+ class Link < Post
3
+ string_attribute :title, :url, :description
4
+ end
5
+ end
@@ -0,0 +1,22 @@
1
+ module Tumblr
2
+ class Photo < Post
3
+ array_attribute :photos
4
+ array_attribute :sizes
5
+ string_attribute :caption
6
+ numeric_attribute :width, :height
7
+
8
+ class Size < Object
9
+ string_attribute :url
10
+ numeric_attribute :width, :height
11
+ end
12
+
13
+ def photos=(value)
14
+ photos = value.collect do |value|
15
+ object = Tumblr::Photo.new
16
+ object.caption = value["caption"]
17
+ object.sizes = value["alt_sizes"].collect { |size| Size.build(size) }
18
+ end
19
+ set_attribute_value(:photos, photos)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,89 @@
1
+ module Tumblr
2
+ class Post < Object
3
+ extend Query::DelegateMethods
4
+ numeric_attribute :id
5
+ date_attribute :date, :timestamp
6
+ string_attribute :slug, :blog_name, :post_url, :source_url, :source_title, :format
7
+ array_attribute :tags
8
+ boolean_attribute :mobile, :bookmarklet
9
+
10
+ def self.build(attributes)
11
+ klass = attributes["type"] ? Object.systematize(attributes["type"]) : self
12
+ if klass && klass != self
13
+ klass.build(attributes)
14
+ else
15
+ super
16
+ end
17
+ end
18
+
19
+ def self.page(n)
20
+ query.page([1, n.to_i].max)
21
+ end
22
+
23
+ def self.per_page(n)
24
+ query.per_page(n)
25
+ end
26
+
27
+ def self.type(type)
28
+ query.type(type)
29
+ end
30
+
31
+ def self.tagged_with(tag)
32
+ query.tag(tag)
33
+ end
34
+
35
+ def self.find(id)
36
+ query.id(id).first
37
+ end
38
+
39
+ def commit
40
+ super
41
+ tags.each do |tag|
42
+ Redis::Set.new("#{Blog::STORAGE_KEY}:tags", Tumblr.config.redis) << tag
43
+ Redis::List.new("#{Blog::STORAGE_KEY}:tags:#{tag.downcase.underscore}", Tumblr.config.redis) << slug
44
+ end
45
+ end
46
+
47
+ def html?
48
+ format == "html"
49
+ end
50
+
51
+ def markdown?
52
+ format == "markdown"
53
+ end
54
+
55
+ def slug
56
+ @slug ||= title.parameterize
57
+ end
58
+
59
+ def to_param
60
+ slug
61
+ end
62
+
63
+ private
64
+
65
+ def self.query
66
+ @query ||= Query.new(:page, :per_page, :type, :id, :tag) do |params|
67
+ page_size = params[:per_page] || self.page_size
68
+ page = [1, params[:page].to_i].max
69
+ req_params = {
70
+ :limit => page_size,
71
+ :offset => page_size * (page - 1)
72
+ }
73
+ [:type, :id, :tag].each do |key|
74
+ req_params[key] = params[key] if params[key]
75
+ end
76
+
77
+ if params.key?(:per_page) || params.key?(:page)
78
+ results = Api.get('posts', req_params)
79
+ WillPaginate::Collection.create(page, page_size, results.body["total_posts"]) do |pager|
80
+ pager.replace results.body["posts"]
81
+ end
82
+ else
83
+ results = Api.get('posts', :limit => req_params)
84
+ results.body["posts"]
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,5 @@
1
+ module Tumblr
2
+ class Text < Post
3
+ string_attribute :title, :body
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ module Tumblr
2
+ class User < Object
3
+ numeric_attribute :following
4
+ string_attribute :default_post_format, :name
5
+ array_attribute :blogs, :object => :blog
6
+ end
7
+ end
@@ -0,0 +1,11 @@
1
+ module Tumblr
2
+ class Video < Post
3
+ string_attribute :caption
4
+ array_attribute :player, :object => "video/player"
5
+
6
+ class Player < Object
7
+ numeric_attribute :width
8
+ string_attribute :embed_code
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,48 @@
1
+ module Tumblr
2
+ class Query
3
+ module DelegateMethods
4
+ [:first, :last, :all, :length].each do |method|
5
+ define_method method do
6
+ query.send(method)
7
+ end
8
+ end
9
+ end
10
+
11
+ def initialize(*parameters, &block)
12
+ @params = {}
13
+ @param_keys = parameters.to_a
14
+ @fetch_block = block
15
+ end
16
+
17
+ [:first, :last, :count, :to_xml, :to_yaml, :length, :collect, :map, :each, :all?, :include?].each do |method|
18
+ define_method method do |*args, &block|
19
+ to_a.send(method, *args, &block)
20
+ end
21
+ end
22
+
23
+ def all
24
+ to_a
25
+ end
26
+
27
+ def to_a
28
+ if @array && @array.length > 0
29
+ @array
30
+ else
31
+ @array = @fetch_block.call(@params)
32
+ end
33
+ end
34
+
35
+ def method_missing(method, *args, &block)
36
+ if @param_keys.include?(method.to_sym)
37
+ value = args.length == 1 ? args.first : args
38
+ @array = nil if value != @params[method.to_sym]
39
+ @params[method.to_sym] = value
40
+ self
41
+ elsif to_a.respond_to?(method)
42
+ to_a.send(method, *args, &block)
43
+ else
44
+ super(method, *args, &block)
45
+ end
46
+ end
47
+ end
48
+ end
data/lib/tumblr/quote.rb CHANGED
@@ -1,21 +1,5 @@
1
1
  module Tumblr
2
- class Quote < Item
3
- attr_accessor :text, :source
4
-
5
- def as_json
6
- super.merge!({
7
- :text => text,
8
- :source => source
9
- })
10
- end
11
-
12
- private
13
-
14
- def parse_xml_node(node)
15
- super(node)
16
- self.text = node.css('quote-text').first.try(:content)
17
- self.source = node.css('quote-source').first.try(:content)
18
- self
19
- end
2
+ class Quote < Post
3
+ string_attribute :text, :source
20
4
  end
21
5
  end
@@ -1,4 +1,4 @@
1
1
  module Tumblr
2
2
  # The version of the gem
3
- VERSION = '1.0.6'.freeze unless defined?(::Twitter::VERSION)
3
+ VERSION = '2.0.1'.freeze unless defined?(::Twitter::VERSION)
4
4
  end
data/tumblrb.gemspec CHANGED
@@ -3,37 +3,25 @@ require File.expand_path('../lib/tumblr/version', __FILE__)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.add_dependency('activesupport', '~> 3.0')
6
- s.add_dependency('nokogiri', '~> 1.4.4')
7
- s.add_dependency('curb', '~> 0.7.15')
8
- s.add_dependency('addressable')
9
- s.authors = ["Jesse Reiss"]
10
- s.description = %q{A Ruby wrapper for the Tumblr XML API}
6
+ s.add_dependency('json', '~> 1.6.0')
7
+ s.add_dependency('faraday', '~> 0.7.5')
8
+ s.add_dependency('addressable', '~> 2.2.0')
9
+ s.add_dependency('redis-objects', '~> 0.5.0')
10
+ s.add_dependency('will_paginate', '~> 3.0.0')
11
+ s.authors = ["thegorgon"]
12
+ s.description = %q{A simple blogging platform built on Tumblr and Redis}
11
13
  s.email = ['jessereiss@gmail.com']
12
14
  s.homepage = 'https://github.com/thegorgon/tumblrb'
13
15
  s.name = 'tumblrb'
14
16
  s.platform = Gem::Platform::RUBY
15
- s.require_paths << 'lib'
16
17
  s.required_rubygems_version = Gem::Requirement.new('>= 1.3.6') if s.respond_to? :required_rubygems_version=
17
18
  s.rubyforge_project = s.name
18
19
  s.summary = %q{Ruby wrapper for the Tumblr API}
19
- s.files = [
20
- "README.mkd",
21
- "LICENSE.mkd",
22
- "Gemfile",
23
- "tumblrb.gemspec",
24
- "lib/tumblr.rb",
25
- "lib/tumblr/answer.rb",
26
- "lib/tumblr/audio.rb",
27
- "lib/tumblr/conversation.rb",
28
- "lib/tumblr/item.rb",
29
- "lib/tumblr/link.rb",
30
- "lib/tumblr/page.rb",
31
- "lib/tumblr/photo.rb",
32
- "lib/tumblr/quote.rb",
33
- "lib/tumblr/regular.rb",
34
- "lib/tumblr/user.rb",
35
- "lib/tumblr/version.rb",
36
- "lib/tumblr/video.rb"
37
- ]
20
+
21
+ s.files = `git ls-files`.split("\n")
22
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
23
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
24
+ s.require_paths = ["lib"]
25
+
38
26
  s.version = Tumblr::VERSION.dup
39
27
  end