tumblrb 1.0.6 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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