awl_tags_twitter 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: 8b58a59a77672a9fbf26fa2a846beacb9d2dd611
4
+ data.tar.gz: 1565fae962838c8d4a0ea4f00345d1da49e48a17
5
+ SHA512:
6
+ metadata.gz: 1f7bf18d6dd160d79cf4c7bb463fb485deea48c611aa58248c2aa021472e750a111b2b2a8d7cd9f09f89ed1e19b68b5e1f0c0ec422c95dce03557ffa57b4b7f1
7
+ data.tar.gz: 22aba35c2a545919b2f8fc372958076db85e01e27c99bfffb15ca4bdab9e62ae59facbbc63f7395aa13fe8e52e3381b17b30e941a80f2c8a74028b534a4fb81b
@@ -0,0 +1,16 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ .quicktask
16
+ spec/vcr/*
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
@@ -0,0 +1,2 @@
1
+ Metrics/LineLength:
2
+ Max: 120
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in awl_tags_twitter.gemspec
4
+ gemspec
@@ -0,0 +1,18 @@
1
+ guard :rspec, cmd: 'bundle exec rspec' do
2
+ require 'guard/rspec/dsl'
3
+ dsl = Guard::RSpec::Dsl.new(self)
4
+
5
+ # RSpec files
6
+ rspec = dsl.rspec
7
+ watch(rspec.spec_helper) { rspec.spec_dir }
8
+ watch(rspec.spec_support) { rspec.spec_dir }
9
+ watch(rspec.spec_files)
10
+
11
+ # Ruby files
12
+ ruby = dsl.ruby
13
+ dsl.watch_spec_files_for(ruby.lib_files)
14
+
15
+ # Application Files
16
+ watch(%r{^lib/(.+)\.rb})
17
+ watch(%r{^bin/})
18
+ end
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Jack Ellis
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,45 @@
1
+ # AwlTagsTwitter
2
+
3
+ Grab tags from The Awl posts and tweet them out
4
+
5
+ ## Installation
6
+
7
+ $ gem install awl_tags_twitter
8
+
9
+ ## Usage
10
+
11
+ ```
12
+ $ awl_tags_twitter --config /path/to/config/file post
13
+ $ awl_tags_twitter --config /path/to/config/file list
14
+ $ awl_tags_twitter --config /path/to/config/file help
15
+ ```
16
+
17
+ ## Contributing
18
+
19
+ 1. Fork it ( https://github.com/ellisandy/awl_tags_twitter/fork )
20
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
21
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
22
+ 4. Push to the branch (`git push origin my-new-feature`)
23
+ 5. Create a new Pull Request
24
+
25
+ ## Archecture
26
+ 1. Scraper returns a list of URLs
27
+ * These URLs tie to a specific Article
28
+ * When the article is initialized it should only have the URL
29
+ * You can then call Builder which will poll the webservice and grab all the tags
30
+ 2. Article
31
+ * has a URL
32
+ * has a list of tags
33
+ * utilizes builder to actually poll teh article and return the tags
34
+ 3. Builder
35
+ * accepts a url
36
+ * returns an array of tags
37
+
38
+ ## Algorythm
39
+ * []
40
+ * Tweet.new(link)
41
+ * Tweet.add tag
42
+ * Tweet.add will check if the tweet will be too long with the new tag included
43
+ * next
44
+ * tweet add or Tweet.new again
45
+
@@ -0,0 +1,9 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake'
3
+ require 'rspec/core/rake_task'
4
+
5
+ task :test do
6
+ sh 'rspec'
7
+ sh 'yard '
8
+ sh 'bundle exec ruby -W0 -S rubocop'
9
+ end
@@ -0,0 +1,38 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'awl_tags_twitter/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'awl_tags_twitter'
8
+ spec.version = AwlTagsTwitter::VERSION
9
+ spec.authors = ['Jack Ellis']
10
+ spec.email = ['jack@mnmlst.cc']
11
+ spec.summary = 'Grab tags from The Awl posts and tweet them out'
12
+ spec.description = 'Grab tags from The Awl posts and tweet them out. This isn\'t anything crazy'
13
+ spec.homepage = 'https://github.com/ellisandy'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_runtime_dependency 'nokogiri', '~> 1.6'
22
+ spec.add_runtime_dependency 'commander', '~> 4.3'
23
+ spec.add_runtime_dependency 'contracts', '~> 0.12'
24
+ spec.add_runtime_dependency 'terminal-table', '~> 1.5'
25
+
26
+ spec.add_development_dependency 'bundler', '~> 1.7'
27
+ spec.add_development_dependency 'rspec', '~> 3.2'
28
+ spec.add_development_dependency 'rspec-mocks', '~> 3.2'
29
+ spec.add_development_dependency 'yard', '~> 0.8'
30
+ spec.add_development_dependency 'rubocop', '~> 0.8'
31
+ spec.add_development_dependency 'webmock', '~> 1.22'
32
+ spec.add_development_dependency 'vcr', '~> 2.9'
33
+ spec.add_development_dependency 'simplecov', '~> 0.10'
34
+ spec.add_development_dependency 'guard-rspec', '~> 4.5'
35
+ spec.add_development_dependency 'terminal-notifier-guard', '~> 1.6'
36
+ spec.add_development_dependency 'rake', '~> 10.0'
37
+ spec.add_development_dependency 'pry', '~> 0.10'
38
+ end
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'commander/import'
5
+ require 'scraper'
6
+ require 'terminal-table'
7
+ require 'awl_tags_twitter/version'
8
+
9
+ program :version, AwlTagsTwitter::VERSION
10
+ program :description, 'Grab tags from posts and tweet them out'
11
+
12
+ command :post do |c|
13
+ c.syntax = 'awl_tags_twitter post [options]'
14
+ c.summary = ''
15
+ c.description = ''
16
+ c.example 'description', 'command example'
17
+ c.option '--some-switch', 'Some switch that does something'
18
+ c.action do # |args, options|
19
+ scrapper = Scraper.new
20
+ scrapper.some = 'hello'
21
+
22
+ puts scrapper.what
23
+ end
24
+ end
25
+
26
+ command :list do |c|
27
+ c.syntax = 'awl_tags_twitter list'
28
+ c.summary = 'List current posts and their tags'
29
+ c.description = 'List current posts and their tags. Display them'\
30
+ ' in an ASCII table split as they would be tweeted'
31
+ c.example 'basic', 'awl_tags_twitter list --basic'
32
+ c.example 'complex', 'awl_tags_twitter list --complex'
33
+ c.option '--basic', 'Display posts with tags'
34
+ c.option '--complex', 'Display posts with tags split between posts'
35
+ c.action do |_args, options|
36
+ # Do something or c.when_called Awstags::Commands::List
37
+ if options.basic
38
+ scraper = Scraper.new
39
+ scraper.retrieve_posts
40
+ rows = scraper.articles.map { |a| [a.link, a.tags] }
41
+ table = Terminal::Table.new rows: rows
42
+ puts table
43
+ elsif options.complex
44
+ scraper = Scraper.new
45
+ scraper.retrieve_posts.map(&:build_tweets)
46
+ rows = scraper.articles.map { |a| [a.link, a.tags, a.tweets] }
47
+ table = Terminal::Table.new rows: rows
48
+ puts table
49
+ else
50
+ fail 'provide --basic or --complex'
51
+ end
52
+ end
53
+ end
54
+
55
+ command :'cache-all' do |c|
56
+ c.syntax = 'awl_tags_twitter cache-all [options]'
57
+ c.summary = ''
58
+ c.description = ''
59
+ c.example 'description', 'command example'
60
+ c.option '--some-switch', 'Some switch that does something'
61
+ c.action do |args, options|
62
+ # Do something or c.when_called Awstags::Commands::Cache-all
63
+ end
64
+ end
@@ -0,0 +1,59 @@
1
+ require 'nokogiri'
2
+ require 'open-uri'
3
+ require 'tweet'
4
+
5
+ # The Article class contains the links and tags for consumption by twitter
6
+ class Article
7
+ attr_accessor :tweets
8
+ attr_accessor :link, :tags
9
+
10
+ # CSS tag to pull the tags strings
11
+ TAG_CSS = '.tags a'
12
+
13
+ def initialize(link)
14
+ @link = link
15
+ @tweets = []
16
+ end
17
+
18
+ # Recursively build and populate tweets. This will catch any errors which
19
+ # are raised by Tweet#add and attempt to call it again
20
+ def build_tweets # rubocop:disable Metrics/MethodLength
21
+ tweet = Tweet.new(@link)
22
+ @tags.each do |tag|
23
+ begin
24
+ tweet.add(tag)
25
+ rescue Tweet::TagTooLong
26
+ @tweets.push tweet
27
+ raise StandardError if "#{tag} | #{@link}".length > 140
28
+ tweet = Tweet.new(@link)
29
+ end
30
+ end
31
+ @tweets.push tweet
32
+ end
33
+
34
+ def tweets
35
+ @tweets.map(&:to_s)
36
+ end
37
+
38
+ # sets @tags by calling the url, then filtering the document to find the
39
+ # tags.
40
+ def retrieve_tags
41
+ # get post
42
+ doc = request_url
43
+ @tags = filter_tags(doc)
44
+ self
45
+ end
46
+
47
+ # Filters finds the link inside the .g-tag-box div, pulls the name, then makes
48
+ # the resulting string uppercase.
49
+ def filter_tags(doc)
50
+ # Filter down and get the tags.
51
+ @tags = doc.css(TAG_CSS).map(&:children).map(&:text)
52
+ end
53
+
54
+ # Opens @link, then parses using Nokogiri
55
+ def request_url
56
+ # Get all data
57
+ Nokogiri::HTML(open(@link))
58
+ end
59
+ end
@@ -0,0 +1,5 @@
1
+ # Global Version for AwlTagsTwitter
2
+ class AwlTagsTwitter
3
+ # Global Version for AwlTagsTwitter
4
+ VERSION = '0.0.1'
5
+ end
@@ -0,0 +1,35 @@
1
+ require 'nokogiri'
2
+ require 'rss'
3
+ require 'article'
4
+ require 'contracts'
5
+
6
+ # Class for handling RSS feed to grab posts
7
+ class Scraper
8
+ include Contracts::Core
9
+
10
+ # Array of Hashes
11
+ attr_reader :articles
12
+
13
+ # URL to pull the initial feed
14
+ AWL_RSS_URL = 'http://feeds2.feedburner.com/TheAwl'
15
+ # Shortcut for contracts
16
+ C = Contracts
17
+
18
+ Contract C::None => C::ArrayOf[Article]
19
+ # Retrieve a list of posts and return array of short links
20
+ def retrieve_posts
21
+ # Get posts
22
+ rss = RSS::Parser.parse(AWL_RSS_URL)
23
+
24
+ # Grab shortened URLs
25
+ links = rss.items.map(&:guid).map(&:content)
26
+
27
+ @articles = []
28
+
29
+ links.each do |link|
30
+ @articles << Article.new(link)
31
+ end
32
+
33
+ @articles.map(&:retrieve_tags)
34
+ end
35
+ end
@@ -0,0 +1,36 @@
1
+ require 'contracts'
2
+ require 'tweet/tag_too_long'
3
+
4
+ # Building a post to tweet
5
+ class Tweet
6
+ include Contracts::Core
7
+
8
+ attr_accessor :link
9
+ attr_accessor :post
10
+
11
+ # Shortcut for Contracts
12
+ C = Contracts
13
+
14
+ Contract String => String
15
+ def initialize(link)
16
+ @link = link
17
+ @post = @link
18
+ end
19
+
20
+ Contract String => String
21
+ # Add tag to @post
22
+ def add(tag)
23
+ temp_post = "#{tag} | #{@post}"
24
+ if temp_post.length <= 140
25
+ @post = tag + ' | ' + @post
26
+ else
27
+ fail Tweet::TagTooLong
28
+ end
29
+ end
30
+
31
+ Contract C::None => String
32
+ # Output the post
33
+ def to_s
34
+ @post.to_s
35
+ end
36
+ end
@@ -0,0 +1,8 @@
1
+ require 'tweet'
2
+
3
+ # Extending lib/tweet
4
+ class Tweet
5
+ # Defining TagTooLong standard error
6
+ class TagTooLong < StandardError
7
+ end
8
+ end
@@ -0,0 +1,5 @@
1
+ require 'contracts'
2
+
3
+ # Recursively build tweets and returns a list of Tweets
4
+ class TweetBuilder
5
+ end
File without changes
@@ -0,0 +1,105 @@
1
+ require 'article'
2
+
3
+ RSpec.describe Article do
4
+ let(:link) { 'https://medium.com/p/1fe66319e7e0' }
5
+ let(:article) { Article.new(link) }
6
+ context '#initialize' do
7
+ it 'should raise ArgumentError' do
8
+ expect { Article.new }.to raise_error(ArgumentError)
9
+ end
10
+
11
+ it 'should not raise any errors' do
12
+ expect { article }.not_to raise_error
13
+ end
14
+ end
15
+
16
+ context '#tags' do
17
+ it 'should set @tags', :vcr do
18
+ article.retrieve_tags
19
+ expect(article.tags).to be_kind_of(Array)
20
+ end
21
+
22
+ it 'expects link to be set' do
23
+ expect(article.link).to eq(link)
24
+ end
25
+ end
26
+
27
+ context '#retrieve_tags' do
28
+ it 'should set @tags', :vcr do
29
+ expect(article.retrieve_tags).to be_truthy
30
+ end
31
+
32
+ it 'expects link to be set' do
33
+ expect(article.link).to eq(link)
34
+ end
35
+ end
36
+
37
+ context '#filter_tags' do
38
+ it 'should raise error without arguement' do
39
+ expect { article.filter_tags }.to raise_error(ArgumentError)
40
+ end
41
+
42
+ it 'should not raise an error with an arguement', :vcr do
43
+ doc = article.request_url
44
+ expect { article.filter_tags(doc) }.not_to raise_error
45
+ end
46
+
47
+ it 'returns array', :vcr do
48
+ doc = article.request_url
49
+ expect(article.filter_tags(doc)).to be_kind_of(Array)
50
+ end
51
+ end
52
+
53
+ context '#request_url' do
54
+ it 'returns doc', :vcr do
55
+ expect(article.request_url).to be_kind_of(Nokogiri::HTML::Document)
56
+ end
57
+ end
58
+
59
+ context '#build_tweets', :vcr do
60
+ let(:link) { 'http://domain.com' }
61
+
62
+ before do
63
+ article.tags = tags
64
+ article.link = link
65
+ end
66
+
67
+ context 'when there is only a few tags' do
68
+ let(:tags) { ['foo'] }
69
+
70
+ it 'returns an array of tweets' do
71
+ expect(article.build_tweets.first.post).to eq("#{tags.first} | #{link}")
72
+ end
73
+ it 'returns only one tweet' do
74
+ expect(article.build_tweets.count).to eq(1)
75
+ end
76
+ end
77
+
78
+ context 'when there are a lot of tags' do
79
+ let(:tags) { ['foo'] * 40 }
80
+
81
+ it 'returns more than 1 tweet' do
82
+ expect(article.build_tweets.count).to be > 1
83
+ end
84
+ end
85
+ end
86
+
87
+ context '#tweets' do
88
+ let(:article) { Article.new(link) }
89
+ let(:link) { 'http://domain.com' }
90
+ let(:tags) { ['foo'] }
91
+
92
+ before do
93
+ article.tags = tags
94
+ article.link = link
95
+ end
96
+
97
+ context 'when there are tweets' do
98
+ it 'returns the array of tweets' do
99
+ article.build_tweets
100
+
101
+ expect(article.tweets).to eq(["#{tags.first} | #{link}"])
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,27 @@
1
+ require 'scraper'
2
+
3
+ RSpec.describe Scraper do
4
+ context '#retrieve_posts' do
5
+ let(:scraper) { Scraper.new }
6
+
7
+ it 'responsed', :vcr do
8
+ expect(scraper).to respond_to(:retrieve_posts)
9
+ end
10
+
11
+ it 'returns an arrays', :vcr do
12
+ expect(scraper.retrieve_posts).to be_kind_of(Array)
13
+ end
14
+
15
+ it 'returns array with strings', :vcr do
16
+ expect(scraper.retrieve_posts.first).to be_instance_of(Article)
17
+ end
18
+
19
+ it 'returns array with strings', :vcr do
20
+ expect(scraper.retrieve_posts.first.link).to be_instance_of(String)
21
+ end
22
+ end
23
+
24
+ context '#posts' do
25
+ it { should respond_to(:articles) }
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ require 'simplecov'
2
+ require 'webmock/rspec'
3
+ require 'vcr'
4
+
5
+ SimpleCov.start
6
+
7
+ VCR.configure do |c|
8
+ c.cassette_library_dir = 'spec/vcr'
9
+ c.hook_into :webmock
10
+ c.configure_rspec_metadata!
11
+ end
12
+ WebMock.disable_net_connect!(allow_localhost: true)
13
+ RSpec.configure do |config|
14
+ config.expect_with :rspec do |expectations|
15
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
16
+ end
17
+
18
+ config.mock_with :rspec do |mocks|
19
+ mocks.verify_partial_doubles = true
20
+ end
21
+
22
+ config.disable_monkey_patching!
23
+
24
+ config.warnings = false
25
+
26
+ config.order = :random
27
+ end
@@ -0,0 +1,27 @@
1
+ require 'tweet'
2
+
3
+ RSpec.describe Tweet do
4
+ let(:link) { 'https://someurl.com/' }
5
+ let(:tweet) { Tweet.new(link) }
6
+
7
+ context '#to_s' do
8
+ it 'returns a string shorter than 140' do
9
+ expect(tweet.to_s.length).to be < 140
10
+ end
11
+ end
12
+
13
+ context '#add' do
14
+ context 'when the tag + @post is < 140' do
15
+ let(:tag) { 'foo' }
16
+ it 'is added' do
17
+ expect(tweet.add(tag)).to eq("#{tag} | #{link}")
18
+ end
19
+ end
20
+ context 'when the tag + @post is > 140' do
21
+ let(:tag) { 'a' * 140 }
22
+ it 'is not added' do
23
+ expect { tweet.add(tag) }.to raise_error Tweet::TagTooLong
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,9 @@
1
+ require 'awl_tags_twitter/version'
2
+
3
+ RSpec.describe AwlTagsTwitter do
4
+ context '#Version' do
5
+ it 'has a version' do
6
+ expect(AwlTagsTwitter::VERSION).to be_kind_of(String)
7
+ end
8
+ end
9
+ end
metadata ADDED
@@ -0,0 +1,299 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: awl_tags_twitter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Jack Ellis
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-10-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: nokogiri
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: commander
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '4.3'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '4.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: contracts
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.12'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.12'
55
+ - !ruby/object:Gem::Dependency
56
+ name: terminal-table
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.5'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.5'
69
+ - !ruby/object:Gem::Dependency
70
+ name: bundler
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.7'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.7'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.2'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.2'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec-mocks
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '3.2'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '3.2'
111
+ - !ruby/object:Gem::Dependency
112
+ name: yard
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '0.8'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '0.8'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rubocop
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '0.8'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '0.8'
139
+ - !ruby/object:Gem::Dependency
140
+ name: webmock
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '1.22'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '1.22'
153
+ - !ruby/object:Gem::Dependency
154
+ name: vcr
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '2.9'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '2.9'
167
+ - !ruby/object:Gem::Dependency
168
+ name: simplecov
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: '0.10'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: '0.10'
181
+ - !ruby/object:Gem::Dependency
182
+ name: guard-rspec
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: '4.5'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: '4.5'
195
+ - !ruby/object:Gem::Dependency
196
+ name: terminal-notifier-guard
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - "~>"
200
+ - !ruby/object:Gem::Version
201
+ version: '1.6'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - "~>"
207
+ - !ruby/object:Gem::Version
208
+ version: '1.6'
209
+ - !ruby/object:Gem::Dependency
210
+ name: rake
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - "~>"
214
+ - !ruby/object:Gem::Version
215
+ version: '10.0'
216
+ type: :development
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - "~>"
221
+ - !ruby/object:Gem::Version
222
+ version: '10.0'
223
+ - !ruby/object:Gem::Dependency
224
+ name: pry
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - "~>"
228
+ - !ruby/object:Gem::Version
229
+ version: '0.10'
230
+ type: :development
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - "~>"
235
+ - !ruby/object:Gem::Version
236
+ version: '0.10'
237
+ description: Grab tags from The Awl posts and tweet them out. This isn't anything
238
+ crazy
239
+ email:
240
+ - jack@mnmlst.cc
241
+ executables:
242
+ - awl_tags_twitter
243
+ extensions: []
244
+ extra_rdoc_files: []
245
+ files:
246
+ - ".gitignore"
247
+ - ".rspec"
248
+ - ".rubocop.yml"
249
+ - Gemfile
250
+ - Guardfile
251
+ - LICENSE.txt
252
+ - README.md
253
+ - Rakefile
254
+ - awl_tags_twitter.gemspec
255
+ - bin/awl_tags_twitter
256
+ - lib/article.rb
257
+ - lib/awl_tags_twitter/version.rb
258
+ - lib/scraper.rb
259
+ - lib/tweet.rb
260
+ - lib/tweet/tag_too_long.rb
261
+ - lib/tweet_builder.rb
262
+ - spec/.txt
263
+ - spec/article_spec.rb
264
+ - spec/scraper_spec.rb
265
+ - spec/spec_helper.rb
266
+ - spec/tweet_spec.rb
267
+ - spec/version_spec.rb
268
+ homepage: https://github.com/ellisandy
269
+ licenses:
270
+ - MIT
271
+ metadata: {}
272
+ post_install_message:
273
+ rdoc_options: []
274
+ require_paths:
275
+ - lib
276
+ required_ruby_version: !ruby/object:Gem::Requirement
277
+ requirements:
278
+ - - ">="
279
+ - !ruby/object:Gem::Version
280
+ version: '0'
281
+ required_rubygems_version: !ruby/object:Gem::Requirement
282
+ requirements:
283
+ - - ">="
284
+ - !ruby/object:Gem::Version
285
+ version: '0'
286
+ requirements: []
287
+ rubyforge_project:
288
+ rubygems_version: 2.4.5
289
+ signing_key:
290
+ specification_version: 4
291
+ summary: Grab tags from The Awl posts and tweet them out
292
+ test_files:
293
+ - spec/.txt
294
+ - spec/article_spec.rb
295
+ - spec/scraper_spec.rb
296
+ - spec/spec_helper.rb
297
+ - spec/tweet_spec.rb
298
+ - spec/version_spec.rb
299
+ has_rdoc: