butterfli 0.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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e7b692e5c348c92eaf1fae64a84cedd5de808121
4
+ data.tar.gz: e0b34c538cd18011042e6cbf0a38b30b09855147
5
+ SHA512:
6
+ metadata.gz: cc7bcc3c5e460da640c6c0233fb0bed38c911222682f080de498bf5ef3f921ce2def330f3152fef65a583f8ad8e47c5b83a9367216d2f594e1f21a75921c8c7e
7
+ data.tar.gz: 146d25c23e15a486de99015a97faf9ae43c98164822f399985790d811422270a368e1e1bf192e5105a3918509b9118af7d87fdc8afef25a6e8b6229d8c5b5b3a
@@ -0,0 +1,34 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /test/tmp/
9
+ /test/version_tmp/
10
+ /tmp/
11
+
12
+ ## Specific to RubyMotion:
13
+ .dat*
14
+ .repl_history
15
+ build/
16
+
17
+ ## Documentation cache and generated files:
18
+ /.yardoc/
19
+ /_yardoc/
20
+ /doc/
21
+ /rdoc/
22
+
23
+ ## Environment normalisation:
24
+ /.bundle/
25
+ /lib/bundler/man/
26
+
27
+ # for a library or gem, you might want to ignore these files since the code is
28
+ # intended to run in multiple environments; otherwise, check them in:
29
+ Gemfile.lock
30
+ .ruby-version
31
+ .ruby-gemset
32
+
33
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
34
+ .rvmrc
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ matrix:
3
+ allow_failures:
4
+ - rvm: ruby-head
5
+ rvm:
6
+ - 1.9.3
7
+ - 2.0.0
8
+ - 2.1.0
9
+ - ruby-head
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in butterfli.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 David Elner
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,25 @@
1
+ Olfactory
2
+ ==========
3
+
4
+ [![Build Status](https://travis-ci.org/delner/butterfli.svg?branch=master)](https://travis-ci.org/delner/butterfli) ![Gem Version](https://badge.fury.io/rb/butterfli.svg)
5
+ ###### *For Ruby 1.9.3, 2.0.0, 2.1.0*
6
+
7
+ ### Introduction
8
+
9
+ `butterfli` is a gem that provides a common container for social media objects and other "stories" from around the web. It takes data (typically retrieved via API) and converts them into a Story object.
10
+
11
+ It is the base for its sister gem, `butterfli-rails` which adds API enpoints for public APIs via Rails engines.
12
+
13
+ ### Installation
14
+
15
+ (To be written.)
16
+
17
+ ### Usage
18
+
19
+ (To be written.)
20
+
21
+ ### Changelog
22
+
23
+ #### Version 0.0.1
24
+
25
+ - Initial version of Butterfli (defines Story common container)
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new
6
+ task :default => :spec
7
+ task :test => :spec
8
+
9
+ namespace :doc do
10
+ begin
11
+ require 'yard'
12
+ rescue LoadError
13
+ # ignore
14
+ else
15
+ YARD::Rake::YardocTask.new do |task|
16
+ task.files = ['lib/**/*.rb']
17
+ task.options = [
18
+ '--protected',
19
+ '--output-dir', 'doc/yard',
20
+ '--tag', 'format:Supported formats',
21
+ '--markup', 'markdown',
22
+ ]
23
+ end
24
+ end
25
+ end
26
+
27
+ desc "Open an irb session preloaded with this library"
28
+ task :console do
29
+ sh "irb -rubygems -I lib -r butterfli.rb"
30
+ end
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ $LOAD_PATH << File.expand_path("../lib", __FILE__)
3
+ require 'butterfli/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "butterfli"
7
+ s.version = Butterfli::VERSION
8
+ s.authors = ["David Elner"]
9
+ s.email = ["david@davidelner.com"]
10
+ s.summary = %q{Processes data from the web into a common container.}
11
+ s.description = %q{Processes data from the web into a common container, typically from social media.}
12
+ s.homepage = "http://github.com/delner/butterfli"
13
+ s.license = "MIT"
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ s.test_files = `git ls-files -- {spec,features,gemfiles}/*`.split("\n")
18
+
19
+ s.require_paths = ["lib"]
20
+ s.required_ruby_version = Gem::Requirement.new(">= 1.9.2")
21
+
22
+ # Future dependencies:
23
+ # s.add_dependency "instagram"
24
+ # s.add_dependency "httparty"
25
+
26
+ s.add_development_dependency "bundler", "~> 1.7"
27
+ s.add_development_dependency "rake", "~> 10.0"
28
+ s.add_development_dependency "rspec", "~> 3.3"
29
+ s.add_development_dependency "pry"
30
+ s.add_development_dependency("pry-stack_explorer", "~> 0.4.9")
31
+ end
@@ -0,0 +1,14 @@
1
+ require "butterfli/version"
2
+
3
+ require 'butterfli/story/schemable'
4
+ require 'butterfli/story/authorable'
5
+ require 'butterfli/story/taggable'
6
+ require 'butterfli/story/likeable'
7
+ require 'butterfli/story/commentable'
8
+ require 'butterfli/story/shareable'
9
+ require 'butterfli/story/attributable'
10
+ require 'butterfli/story/describable'
11
+ require 'butterfli/story/imageable'
12
+ require 'butterfli/story/mappable'
13
+ require 'butterfli/story'
14
+
@@ -0,0 +1,16 @@
1
+ class Butterfli::Story < Hash
2
+ include Butterfli::Schemable
3
+ include Butterfli::Attributable
4
+ include Butterfli::Describable
5
+ include Butterfli::Authorable # NEW
6
+ include Butterfli::Taggable # NEW
7
+ include Butterfli::Commentable # NEW
8
+ include Butterfli::Shareable # NEW
9
+ include Butterfli::Likeable # NEW
10
+ include Butterfli::Imageable
11
+ include Butterfli::Mappable
12
+
13
+ field :type # The kind of story (e.g. 'tweet', 'post', 'photo', 'video')
14
+ field :source # Name of the source it came from ('twitter', 'facebook')
15
+ field :date # Time the story occurred
16
+ end
@@ -0,0 +1,11 @@
1
+ module Butterfli::Attributable
2
+ def self.included(base)
3
+ base.field :references, default: References.new
4
+ end
5
+
6
+ class References < Hash
7
+ include Butterfli::Schemable
8
+
9
+ field :source_uri # A URI to the original story
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ module Butterfli::Authorable
2
+ def self.included(base)
3
+ base.field :author, default: Author.new
4
+ end
5
+
6
+ class Author < Hash
7
+ include Butterfli::Schemable
8
+
9
+ field :username # The author's username
10
+ field :name # The author's real name
11
+ end
12
+ end
@@ -0,0 +1,18 @@
1
+ module Butterfli::Commentable
2
+ def self.included(base)
3
+ base.array :comments, default: Comments.new
4
+ end
5
+
6
+ class Comments < Array
7
+ include Butterfli::Schemable
8
+
9
+ item :comment
10
+ end
11
+ class Comment < Hash
12
+ include Butterfli::Schemable
13
+ include Butterfli::Authorable
14
+ include Butterfli::Likeable
15
+
16
+ field :body
17
+ end
18
+ end
@@ -0,0 +1,12 @@
1
+ module Butterfli::Describable
2
+ def self.included(base)
3
+ base.field :text, default: Text.new
4
+ end
5
+
6
+ class Text < Hash
7
+ include Butterfli::Schemable
8
+
9
+ field :title # A short title describing the story
10
+ field :body # The story content
11
+ end
12
+ end
@@ -0,0 +1,19 @@
1
+ module Butterfli::Imageable
2
+ def self.included(base)
3
+ base.field :images, default: Images.new
4
+ end
5
+
6
+ class Images < Hash
7
+ include Butterfli::Schemable
8
+
9
+ array :thumbnails # A URI to the original story
10
+ end
11
+
12
+ class Image < Hash
13
+ include Butterfli::Schemable
14
+
15
+ field :uri
16
+ field :height
17
+ field :width
18
+ end
19
+ end
@@ -0,0 +1,15 @@
1
+ module Butterfli::Likeable
2
+ def self.included(base)
3
+ base.array :likes, default: Likes.new
4
+ end
5
+
6
+ class Likes < Array
7
+ include Butterfli::Schemable
8
+
9
+ item :like
10
+ end
11
+ class Like < Hash
12
+ include Butterfli::Schemable
13
+ include Butterfli::Authorable
14
+ end
15
+ end
@@ -0,0 +1,12 @@
1
+ module Butterfli::Mappable
2
+ def self.included(base)
3
+ base.field :location, default: Location.new
4
+ end
5
+
6
+ class Location < Hash
7
+ include Butterfli::Schemable
8
+
9
+ field :lat # The latitude of where the story took place
10
+ field :lng # The longitude of where the story took place
11
+ end
12
+ end
@@ -0,0 +1,64 @@
1
+ module Butterfli::Schemable
2
+ def self.included(base)
3
+ base.extend(ClassMethods)
4
+ end
5
+
6
+ module ClassMethods
7
+ def schema
8
+ (@schema ||= {})
9
+ end
10
+
11
+ # Adds a field to the schema and defines getter/setters
12
+ def field(name, options = {})
13
+ self.define_field(:field, name, options)
14
+ end
15
+
16
+ def item(name, options = {})
17
+ self.schema[name.to_sym] = { field_type: :item }.merge(options)
18
+ # We don't need to define helper methods here...
19
+ end
20
+
21
+ def array(name, options = {})
22
+ self.define_field(:array, name, options)
23
+ end
24
+
25
+ protected
26
+ def define_field(field_type, name, options = {})
27
+ self.schema[name.to_sym] = { field_type: field_type }.merge(options)
28
+ self.send :define_method, name do
29
+ self[name]
30
+ end
31
+ self.send :define_method, "#{name}=" do |value|
32
+ self[name] = value
33
+ end
34
+ end
35
+ end
36
+
37
+ def initialize
38
+ initialize_with_defaults
39
+ end
40
+
41
+ def initialize_with_defaults
42
+ self.class.schema.each do |name, attributes|
43
+ if self.class <= Hash
44
+ if attributes[:field_type] == :array
45
+ if attributes[:default].nil?
46
+ default_value = []
47
+ else
48
+ default_value = attributes[:default].clone
49
+ end
50
+ else
51
+ # This sort of sucks, but we can't tell what's cloneable...
52
+ begin
53
+ default_value = attributes[:default] && attributes[:default].clone
54
+ rescue
55
+ default_value = attributes[:default]
56
+ end
57
+ end
58
+
59
+ # Set default value for field
60
+ self[name] = default_value
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,15 @@
1
+ module Butterfli::Shareable
2
+ def self.included(base)
3
+ base.array :shares, default: Shares.new
4
+ end
5
+
6
+ class Shares < Array
7
+ include Butterfli::Schemable
8
+
9
+ item :share
10
+ end
11
+ class Share < Hash
12
+ include Butterfli::Schemable
13
+ include Butterfli::Authorable
14
+ end
15
+ end
@@ -0,0 +1,5 @@
1
+ module Butterfli::Taggable
2
+ def self.included(base)
3
+ base.array :tags
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module Butterfli
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe Butterfli do
4
+ # TODO: Add examples
5
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples "attributable" do
4
+ describe "#references" do
5
+ it_behaves_like "it has a field", "references"
6
+
7
+ context do
8
+ subject { super().references }
9
+ it_behaves_like "it has a field", "source_uri"
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples "authorable" do
4
+ describe "#author" do
5
+ it_behaves_like "it has a field", "author"
6
+
7
+ context do
8
+ subject { super().author }
9
+ it_behaves_like "it has a field", "username"
10
+ it_behaves_like "it has a field", "name"
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples "commentable" do
4
+ describe "#comments" do
5
+ it_behaves_like "it has a field", "comments"
6
+ end
7
+
8
+ # TODO: Add coverage for Comment
9
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples "describable" do
4
+ describe "#text" do
5
+ it_behaves_like "it has a field", "text"
6
+ end
7
+
8
+ context do
9
+ subject { super().text }
10
+ it_behaves_like "it has a field", "title"
11
+ it_behaves_like "it has a field", "body"
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples "imageable" do
4
+ describe "#images" do
5
+ it_behaves_like "it has a field", "images"
6
+ end
7
+
8
+ context do
9
+ subject { super().images }
10
+ it_behaves_like "it has a field", "thumbnails"
11
+ end
12
+
13
+ # TODO: Add coverage for Image
14
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples "likeable" do
4
+ describe "#likes" do
5
+ it_behaves_like "it has a field", "likes"
6
+ end
7
+
8
+ # TODO: Add coverage for Like
9
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples "mappable" do
4
+ describe "#location" do
5
+ it_behaves_like "it has a field", "location"
6
+ end
7
+
8
+ context do
9
+ subject { super().location }
10
+ it_behaves_like "it has a field", "lat"
11
+ it_behaves_like "it has a field", "lng"
12
+ end
13
+ end
@@ -0,0 +1,101 @@
1
+ require 'spec_helper'
2
+
3
+ describe Butterfli::Schemable do
4
+ describe "#schema" do
5
+ subject { schemable_class.schema }
6
+ context "with no fields defined" do
7
+ let(:schemable_class) do
8
+ stub_const 'Widget', Class.new(Hash)
9
+ Widget.class_eval { include Butterfli::Schemable }
10
+ Widget
11
+ end
12
+ it { expect(subject).to be_a(Hash) }
13
+ end
14
+ context "with fields defined" do
15
+ let(:schemable_class) do
16
+ stub_const 'Widget', Class.new(Hash)
17
+ Widget.class_eval do
18
+ include Butterfli::Schemable
19
+ field :gizmo
20
+ end
21
+ Widget
22
+ end
23
+ it do
24
+ expect(subject).to be_a(Hash)
25
+ expect(subject).to include(:gizmo)
26
+ end
27
+ end
28
+ end
29
+ describe "#field" do
30
+ subject { schemable_class.new }
31
+ context "with no default" do
32
+ let(:schemable_class) do
33
+ stub_const 'Widget', Class.new(Hash)
34
+ Widget.class_eval do
35
+ include Butterfli::Schemable
36
+ field :gizmo
37
+ end
38
+ Widget
39
+ end
40
+ it { expect(subject).to include(gizmo: nil) }
41
+ end
42
+
43
+ context "with a default" do
44
+ context "that isn't cloneable" do
45
+ [nil, false, true, 1, -2.15].each do |default_value|
46
+ let(:schemable_class) do
47
+ stub_const 'Widget', Class.new(Hash)
48
+ Widget.class_eval { include Butterfli::Schemable }
49
+ Widget
50
+ end
51
+ it do
52
+ schemable_class.class_eval { field :gizmo, default: default_value }
53
+ expect(subject).to include(gizmo: default_value)
54
+ expect(subject[:gizmo].object_id).to eq(default_value.object_id)
55
+ end
56
+ end
57
+ end
58
+ context "that is cloneable" do
59
+ # Because let blocks and class evals are stupid
60
+ default_value = "default"
61
+
62
+ let(:schemable_class) do
63
+ stub_const 'Widget', Class.new(Hash)
64
+ Widget.class_eval do
65
+ include Butterfli::Schemable
66
+ field :gizmo, default: default_value
67
+ end
68
+ Widget
69
+ end
70
+ it do
71
+ expect(subject).to include(gizmo: default_value)
72
+ expect(subject[:gizmo].object_id).not_to be(default_value.object_id)
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+ shared_examples "schemable" do
80
+ describe "#schema" do
81
+ subject { base_class.schema }
82
+ it { expect(base_class).to respond_to(:schema) }
83
+ end
84
+ describe "#field" do
85
+ subject { base_class.field }
86
+ it { expect(base_class).to respond_to(:field) }
87
+ end
88
+ describe "#array" do
89
+ subject { base_class.array }
90
+ it { expect(base_class).to respond_to(:array) }
91
+ end
92
+ describe "#item" do
93
+ subject { base_class.item }
94
+ it { expect(base_class).to respond_to(:item) }
95
+ end
96
+ end
97
+
98
+ shared_examples "it has a field" do |name|
99
+ it { expect(subject).to respond_to(name) }
100
+ it { expect(subject).to respond_to("#{name}=") }
101
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples "shareable" do
4
+ describe "#shares" do
5
+ it_behaves_like "it has a field", "shares"
6
+ end
7
+
8
+ # TODO: Add coverage for Share
9
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ shared_examples "taggable" do
4
+ describe "#tags" do
5
+ it_behaves_like "it has a field", "tags"
6
+ end
7
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe Butterfli::Story do
4
+ let(:base_class) { Butterfli::Story }
5
+ it_behaves_like "schemable"
6
+
7
+ context "instance" do
8
+ subject { base_class.new }
9
+ it_behaves_like "authorable"
10
+ it_behaves_like "attributable"
11
+ it_behaves_like "commentable"
12
+ it_behaves_like "describable"
13
+ it_behaves_like "imageable"
14
+ it_behaves_like "likeable"
15
+ it_behaves_like "mappable"
16
+ it_behaves_like "shareable"
17
+ it_behaves_like "taggable"
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+
2
+ $LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
3
+ $LOAD_PATH << File.join(File.dirname(__FILE__))
4
+
5
+ require 'rubygems'
6
+ require 'pry'
7
+
8
+ require 'butterfli'
9
+
10
+ Dir["spec/support/**/*.rb"].each { |f| require File.expand_path(f) }
11
+
12
+ RSpec.configure do |config|
13
+ config.expect_with :rspec do |expectations|
14
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
15
+ end
16
+ config.mock_with :rspec do |mocks|
17
+ mocks.verify_partial_doubles = true
18
+ end
19
+ end
metadata ADDED
@@ -0,0 +1,150 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: butterfli
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - David Elner
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-06-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry-stack_explorer
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.4.9
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.4.9
83
+ description: Processes data from the web into a common container, typically from social
84
+ media.
85
+ email:
86
+ - david@davidelner.com
87
+ executables: []
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - ".gitignore"
92
+ - ".rspec"
93
+ - ".travis.yml"
94
+ - Gemfile
95
+ - LICENSE.txt
96
+ - README.md
97
+ - Rakefile
98
+ - butterfli.gemspec
99
+ - lib/butterfli.rb
100
+ - lib/butterfli/story.rb
101
+ - lib/butterfli/story/attributable.rb
102
+ - lib/butterfli/story/authorable.rb
103
+ - lib/butterfli/story/commentable.rb
104
+ - lib/butterfli/story/describable.rb
105
+ - lib/butterfli/story/imageable.rb
106
+ - lib/butterfli/story/likeable.rb
107
+ - lib/butterfli/story/mappable.rb
108
+ - lib/butterfli/story/schemable.rb
109
+ - lib/butterfli/story/shareable.rb
110
+ - lib/butterfli/story/taggable.rb
111
+ - lib/butterfli/version.rb
112
+ - spec/butterfli/buttefli_spec.rb
113
+ - spec/butterfli/story/attributable_spec.rb
114
+ - spec/butterfli/story/authorable_spec.rb
115
+ - spec/butterfli/story/commentable_spec.rb
116
+ - spec/butterfli/story/describable_spec.rb
117
+ - spec/butterfli/story/imageable_spec.rb
118
+ - spec/butterfli/story/likeable_spec.rb
119
+ - spec/butterfli/story/mappable_spec.rb
120
+ - spec/butterfli/story/schemable_spec.rb
121
+ - spec/butterfli/story/shareable_spec.rb
122
+ - spec/butterfli/story/taggable_spec.rb
123
+ - spec/butterfli/story_spec.rb
124
+ - spec/spec_helper.rb
125
+ homepage: http://github.com/delner/butterfli
126
+ licenses:
127
+ - MIT
128
+ metadata: {}
129
+ post_install_message:
130
+ rdoc_options: []
131
+ require_paths:
132
+ - lib
133
+ required_ruby_version: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: 1.9.2
138
+ required_rubygems_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ requirements: []
144
+ rubyforge_project:
145
+ rubygems_version: 2.4.3
146
+ signing_key:
147
+ specification_version: 4
148
+ summary: Processes data from the web into a common container.
149
+ test_files: []
150
+ has_rdoc: