phi 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d24ffd5f95a41e7c888db90c75df8d576362222d
4
+ data.tar.gz: fcd9f3d45a1e7fbd0699ea6222a0402274be655c
5
+ SHA512:
6
+ metadata.gz: e003baf998d98f451f274f2191c6167a5481e7325934f0c9144ba981ef4d23d479f95f74c3cf5a50062c9df1c840335de380ca6902caefffe20fc2d9a19c1955
7
+ data.tar.gz: 21b169024c559bae6a0afec6d4600e4038b7374790c674a2508be170018ec62060759ea717d05cce2893f9429099a9830c3f07ab4b68d8864628ec158276dd03
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in phi.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 lwangenheim
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.
data/README.md ADDED
@@ -0,0 +1,30 @@
1
+ # Phi
2
+
3
+ TODO: Write a gem description
4
+ Note: The Philosophy Index of Philosophy is zero.
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'phi'
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install phi
19
+
20
+ ## Usage
21
+
22
+ TODO: Write usage instructions here
23
+
24
+ ## Contributing
25
+
26
+ 1. Fork it ( http://github.com/<my-github-username>/phi/fork )
27
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
28
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
29
+ 4. Push to the branch (`git push origin my-new-feature`)
30
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/phi ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.expand_path("../../lib", __FILE__)
4
+ require 'phi/cli'
5
+
6
+ Phi::Cli.run
data/lib/phi/cli.rb ADDED
@@ -0,0 +1,20 @@
1
+ require 'phi'
2
+
3
+ module Phi
4
+ module Cli
5
+ extend self
6
+
7
+ def term
8
+ ARGV.fetch(0) {
9
+ puts 'Must provide term to phi command. Usage: `phi term`'
10
+ exit 1
11
+ }
12
+ end
13
+
14
+ def run
15
+ i = Phi::Losophy.new(term).index
16
+ puts "The Philosophy Index of #{term} is #{i}."
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,38 @@
1
+ module Phi
2
+ class Losophy
3
+ class Page
4
+ class Node
5
+ attr_reader :parent
6
+ attr_accessor :in_parentheses
7
+
8
+ def initialize(parent)
9
+ @parent = parent
10
+ end
11
+
12
+ def anchor
13
+ parent.children.each do |child|
14
+ if child.name == 'text'
15
+ text(child)
16
+ elsif child.name == 'a' && out_of_parentheses?
17
+ return child
18
+ end
19
+ end
20
+ end
21
+
22
+ def text(node)
23
+ node.text.split('').each { |c|
24
+ if c == '('
25
+ self.in_parentheses = true
26
+ elsif c == ')'
27
+ self.in_parentheses = false
28
+ end
29
+ }
30
+ end
31
+
32
+ def out_of_parentheses?
33
+ !in_parentheses
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,53 @@
1
+ module Phi
2
+ class Losophy
3
+ class Page
4
+
5
+ attr_reader :term, :connection
6
+
7
+ def initialize(term, connection)
8
+ @term = term
9
+ @connection = connection
10
+ end
11
+
12
+ def philosophy?
13
+ term.downcase == "philosophy"
14
+ end
15
+
16
+ def next
17
+ @next ||= Page.new(next_term, connection)
18
+ end
19
+
20
+ def inspect
21
+ "#<#{self.class.name}:#{term}>"
22
+ end
23
+
24
+ private
25
+
26
+ def next_term
27
+ Node.new(html.css(selector)).anchor.attr("href")[6..-1]
28
+ end
29
+
30
+ def selector
31
+ %q{#mw-content-text > p:first}# > a:first[href^='/wiki']}
32
+ end
33
+
34
+ def html
35
+ @html ||= Nokogiri::HTML(page)
36
+ end
37
+
38
+ def page
39
+ @page ||= request.body
40
+ end
41
+
42
+ def request
43
+ sleep 0.25
44
+ connection.get(path: path)
45
+ end
46
+
47
+ def path
48
+ "/wiki/#{term}"
49
+ end
50
+
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,49 @@
1
+ module Phi
2
+ class Losophy
3
+ class Pages
4
+ include Enumerable
5
+ extend Forwardable
6
+
7
+ attr_reader :losophy, :pages
8
+
9
+ def initialize(losophy)
10
+ @losophy = losophy
11
+ @pages = []
12
+ end
13
+
14
+ def each
15
+ until current_page.philosophy?
16
+ guard_max_pages!
17
+ yield self.next
18
+ end
19
+ end
20
+
21
+ def current_page
22
+ @current_page || self.current_page = first_page
23
+ end
24
+
25
+ def next
26
+ self.current_page = current_page.next
27
+ end
28
+
29
+ private
30
+
31
+ def_delegators :losophy, :term, :connection
32
+
33
+ def first_page
34
+ @first_page ||= Page.new(term, connection)
35
+ end
36
+
37
+ def current_page=(page)
38
+ pages << @current_page = page
39
+ end
40
+
41
+ def guard_max_pages!
42
+ return if pages.count <= Phi.max
43
+ raise MaximumPages.new("max pages (#{pages.count}) have been crawled")
44
+ end
45
+
46
+ MaximumPages = Class.new(StandardError)
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,29 @@
1
+ module Phi
2
+ class Losophy
3
+
4
+ WIKI_URL = "http://en.wikipedia.org"
5
+
6
+ attr_reader :term
7
+
8
+ def initialize(term)
9
+ @term = term
10
+ end
11
+
12
+ def index
13
+ pages.count
14
+ end
15
+
16
+ def inspect
17
+ "#<#{self.class.name}:#{term}>"
18
+ end
19
+
20
+ def pages
21
+ @pages ||= Pages.new(self)
22
+ end
23
+
24
+ def connection
25
+ @connection ||= Excon.new(WIKI_URL, middlewares: Excon.defaults[:middlewares] + [Excon::Middleware::RedirectFollower])
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,3 @@
1
+ module Phi
2
+ VERSION = "1.0.0"
3
+ end
data/lib/phi.rb ADDED
@@ -0,0 +1,14 @@
1
+ require 'excon'
2
+ require 'nokogiri'
3
+
4
+ module Phi
5
+ def self.max
6
+ 50
7
+ end
8
+ end
9
+
10
+ require 'phi/losophy'
11
+ require 'phi/losophy/page'
12
+ require 'phi/losophy/page/node'
13
+ require 'phi/losophy/pages'
14
+ require 'phi/version'
data/phi.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'phi/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "phi"
8
+ spec.version = Phi::VERSION
9
+ spec.authors = ["Lee Wangenheim", "Rebecca Hunter", "Adam Hunter"]
10
+ spec.email = ["lwangenheim@gmail.com", "hrmrebecca@gmail.com", "adamhunter@me.com"]
11
+ spec.summary = %q{Command line function to output the Philosophy Index of a Wikipedia article.}
12
+ # spec.description = %q{TODO: Write a longer description. Optional.}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
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_dependency "excon", "~> 0.32"
22
+ spec.add_dependency "nokogiri", "~> 1.6.1"
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.5"
25
+ spec.add_development_dependency "pry", "~> 0.9"
26
+ spec.add_development_dependency "rake"
27
+ spec.add_development_dependency "rspec"
28
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe Phi::Losophy::Pages do
4
+ it "includes Enumerable" do
5
+ expect(described_class.ancestors).to include Enumerable
6
+ end
7
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ describe Phi::Losophy do
4
+ let(:term) { "hyperlink" }
5
+ let(:instance) { described_class.new(term) }
6
+
7
+ it "can calculate the index of 'philosophy'" do
8
+ expect(described_class.new("philosophy").index).to eq 0
9
+ end
10
+
11
+ it "can calculate the index" do
12
+ expect(instance.index).to eq 19
13
+ end
14
+
15
+ it "injects the term correctly" do
16
+ expect(instance.term).to eq term
17
+ end
18
+
19
+ it "looks fancy when inspected" do
20
+ expect(instance.inspect).to eq "#<Phi::Losophy:#{term}>"
21
+ end
22
+
23
+ it "has pages" do
24
+ expect(instance.pages).to be_a Phi::Losophy::Pages
25
+ end
26
+
27
+ it "has a connection" do
28
+ expect(instance.connection).to be_an Excon::Connection
29
+ end
30
+ end
data/spec/phi_spec.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe Phi do
4
+ it "is a Module" do
5
+ expect(Phi).to be_a Module
6
+ end
7
+ end
@@ -0,0 +1,20 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+ require 'phi'
8
+ require 'pry'
9
+
10
+ RSpec.configure do |config|
11
+ config.treat_symbols_as_metadata_keys_with_true_values = true
12
+ config.run_all_when_everything_filtered = true
13
+ config.filter_run :focus
14
+
15
+ # Run specs in random order to surface order dependencies. If you find an
16
+ # order dependency and want to debug it, you can fix the order by providing
17
+ # the seed, which is printed after each run.
18
+ # --seed 1234
19
+ config.order = 'random'
20
+ end
metadata ADDED
@@ -0,0 +1,156 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: phi
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Lee Wangenheim
8
+ - Rebecca Hunter
9
+ - Adam Hunter
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2014-03-28 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: excon
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '0.32'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ version: '0.32'
29
+ - !ruby/object:Gem::Dependency
30
+ name: nokogiri
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ~>
34
+ - !ruby/object:Gem::Version
35
+ version: 1.6.1
36
+ type: :runtime
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ~>
41
+ - !ruby/object:Gem::Version
42
+ version: 1.6.1
43
+ - !ruby/object:Gem::Dependency
44
+ name: bundler
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ~>
48
+ - !ruby/object:Gem::Version
49
+ version: '1.5'
50
+ type: :development
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ~>
55
+ - !ruby/object:Gem::Version
56
+ version: '1.5'
57
+ - !ruby/object:Gem::Dependency
58
+ name: pry
59
+ requirement: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ~>
62
+ - !ruby/object:Gem::Version
63
+ version: '0.9'
64
+ type: :development
65
+ prerelease: false
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ~>
69
+ - !ruby/object:Gem::Version
70
+ version: '0.9'
71
+ - !ruby/object:Gem::Dependency
72
+ name: rake
73
+ requirement: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ type: :development
79
+ prerelease: false
80
+ version_requirements: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - '>='
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ - !ruby/object:Gem::Dependency
86
+ name: rspec
87
+ requirement: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - '>='
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ type: :development
93
+ prerelease: false
94
+ version_requirements: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ description:
100
+ email:
101
+ - lwangenheim@gmail.com
102
+ - hrmrebecca@gmail.com
103
+ - adamhunter@me.com
104
+ executables:
105
+ - phi
106
+ extensions: []
107
+ extra_rdoc_files: []
108
+ files:
109
+ - .gitignore
110
+ - .rspec
111
+ - Gemfile
112
+ - LICENSE.txt
113
+ - README.md
114
+ - Rakefile
115
+ - bin/phi
116
+ - lib/phi.rb
117
+ - lib/phi/cli.rb
118
+ - lib/phi/losophy.rb
119
+ - lib/phi/losophy/page.rb
120
+ - lib/phi/losophy/page/node.rb
121
+ - lib/phi/losophy/pages.rb
122
+ - lib/phi/version.rb
123
+ - phi.gemspec
124
+ - spec/phi/losophy/pages_spec.rb
125
+ - spec/phi/losophy_spec.rb
126
+ - spec/phi_spec.rb
127
+ - spec/spec_helper.rb
128
+ homepage: ''
129
+ licenses:
130
+ - MIT
131
+ metadata: {}
132
+ post_install_message:
133
+ rdoc_options: []
134
+ require_paths:
135
+ - lib
136
+ required_ruby_version: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - '>='
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ required_rubygems_version: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - '>='
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ requirements: []
147
+ rubyforge_project:
148
+ rubygems_version: 2.2.0
149
+ signing_key:
150
+ specification_version: 4
151
+ summary: Command line function to output the Philosophy Index of a Wikipedia article.
152
+ test_files:
153
+ - spec/phi/losophy/pages_spec.rb
154
+ - spec/phi/losophy_spec.rb
155
+ - spec/phi_spec.rb
156
+ - spec/spec_helper.rb