oldness 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.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ .idea
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source :rubygems
2
+
3
+ gem 'rspec'
4
+ gem 'thor'
data/bin/oldness ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__)) + '/../lib/')
4
+
5
+ require 'oldness'
6
+
7
+ # todo: detect pluralization?
8
+ Oldness::CLI.start
9
+
data/config.ru ADDED
@@ -0,0 +1,2 @@
1
+ require './api'
2
+ run Sinatra::Application
@@ -0,0 +1,37 @@
1
+ require 'thor'
2
+
3
+ module Oldness
4
+
5
+ class CLI < Thor
6
+
7
+ desc "rate MEDIUM DATE", "give a star rating of oldness for a work in MEDIUM made on DATE"
8
+ def rate(medium, date)
9
+ print "#{get_class(medium).rate(date, :formatted => true)}\n"
10
+ end
11
+ map "rating" => "rate"
12
+
13
+ desc "ranges MEDIUM", "show what dates fall under what star ratings for a work in MEDIUM"
14
+ def ranges(medium)
15
+ print "#{get_class(medium).ranges(:formatted=>true)}\n"
16
+ end
17
+ map "range" => "ranges"
18
+
19
+ desc "first MEDIUM", "print the first work in MEDIUM"
20
+ def first(medium)
21
+ print "#{get_class(medium).first}\n"
22
+ end
23
+
24
+ desc "media", "List what mediums can be used in other commands"
25
+ def media
26
+ print Oldness::media.collect(&:to_s).sort.inject("") { |l, c| l + c.sub("Oldness::", "")+"\n"}.downcase
27
+ end
28
+ map "mediums" => "media"
29
+ map "list" => "media"
30
+
31
+ no_tasks do
32
+ def get_class(medium)
33
+ eval("Oldness::" + medium.split('-').collect(&:capitalize).inject(:+))
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,119 @@
1
+ require 'date'
2
+ require 'oldness/work'
3
+
4
+ module Oldness
5
+ def self.media
6
+ list = []
7
+ ObjectSpace.each_object(Class) do |c|
8
+ next unless c.superclass == Medium
9
+ list << c
10
+ end
11
+ list
12
+ end
13
+
14
+ class Medium
15
+ def self.ranges(args={})
16
+ current_date = args[:when] ? args[:when] : Date.today
17
+ span = (current_date-first.date)
18
+ unit = span/81
19
+ ranges = {5 => (first.date..current_date-27*unit),
20
+ 4 => (current_date-27*unit..current_date-9*unit),
21
+ 3 => (current_date-9*unit..current_date-3*unit),
22
+ 2 => (current_date-3*unit..current_date-unit),
23
+ 1 => (current_date-unit..current_date)}
24
+ if args[:formatted]
25
+ f_ranges = ""
26
+ ranges.each do |stars, range|
27
+ f_ranges += ("*" * stars) + (" " * (5-stars)) + ": #{range}\n"
28
+ end
29
+ f_ranges.chomp
30
+ else
31
+ ranges
32
+ end
33
+ end
34
+
35
+ def self.rate(work_date, args={})
36
+ work_date = parse_date(work_date)
37
+
38
+ formatted = args[:formatted]
39
+ args[:formatted] = nil
40
+ rating = ranges(args).find {|key, range| range.cover?(work_date)}[0]
41
+
42
+ if formatted
43
+ "*" * rating
44
+ else
45
+ rating
46
+ end
47
+ end
48
+
49
+ def self.began(date, args={})
50
+ @first = Work.new(date, :title => args[:with], :by => args[:by])
51
+ def self.first
52
+ @first
53
+ end
54
+ end
55
+
56
+ private
57
+ def self.parse_date(date)
58
+ begin
59
+ date_info = date.split("-")
60
+ rescue NoMethodError
61
+ return date
62
+ end
63
+
64
+ if date_info[0].downcase.end_with?('bc')
65
+ date_info[0][-2..-1] = ""
66
+ date_info[0].insert(0,'-')
67
+ end
68
+
69
+ Date.new(*date_info.map {|v| v.to_i})
70
+ end
71
+ end
72
+
73
+ class Literature < Medium
74
+ began Date.new(-1300), :with => "The Epic of Gilgamesh"
75
+ end
76
+
77
+ class Philosophy < Medium
78
+ began Date.new(-800), :with => "The Upanishads"
79
+ end
80
+ Religion = Philosophy # now that's what I call opinionated software
81
+
82
+ class SciFi < Medium
83
+ began Date.new(1620), :with => "Somnium", :by => "Johannes Kepler"
84
+ end
85
+
86
+ class Novel < Medium
87
+ began Date.new(1010), :with => "Tale of Genji", :by => "Murasaki Shikibu"
88
+ end
89
+ Book = Novel
90
+
91
+ class Film < Medium
92
+ began Date.new(1894, 2, 5), :by => "Jean Le Roy"
93
+ end
94
+ Movie = Film
95
+
96
+ class Comic < Medium
97
+ began Date.new(1837), :with => "Histoire de M. Vieux Bois", :by => "Rodolphe Topffer" # todo: Töpffer
98
+ end
99
+ Manga = Comic
100
+
101
+ class Videogame < Medium
102
+ began Date.new(1951, 5, 4), :with => "Nimrod", :by => "Ferranti International plc"
103
+ end
104
+
105
+ class History < Medium
106
+ began Date.new(-411), :with => "History of the Pelopnnesian War", :by => "Thucydides"
107
+ end
108
+
109
+ class Animation < Medium
110
+ began Date.new(1906, 4, 6), :with => "Humorous Phases of Funny Faces", :by => "J. Stuart Blackton"
111
+ end
112
+ Cartoon = Animation
113
+ Anime = Animation
114
+
115
+ class Rpg < Medium
116
+ began Date.new(1974), :with => "Dungeons & Dragons", :by => "Gary Gygax and David Arneson"
117
+ end
118
+
119
+ end
@@ -0,0 +1,3 @@
1
+ module Oldness
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,32 @@
1
+ module Oldness
2
+ class Work
3
+ def by
4
+ @by ? @by : "Unknown"
5
+ end
6
+ def title
7
+ @title ? @title : "Untitled"
8
+ end
9
+ attr_accessor :date
10
+ def initialize(date, args={})
11
+ @date, @title, @by = date, args[:title], args[:by]
12
+ end
13
+ def to_s
14
+ if date.yday == 1
15
+ if date.year < 0
16
+ f_date = (date.year * -1).to_s + "BC"
17
+ else
18
+ f_date = "#{date.year}"
19
+ end
20
+ elsif date.mday == 1
21
+ f_date = date.strftime("%B %Y")
22
+ else
23
+ f_date = date.strftime("%B %-d, %Y")
24
+ end
25
+ str = "#{title} (#{f_date})"
26
+ if @by
27
+ str += ", by #{@by}"
28
+ end
29
+ str
30
+ end
31
+ end
32
+ end
data/lib/oldness.rb ADDED
@@ -0,0 +1,2 @@
1
+ require_relative 'oldness/cli'
2
+ require_relative 'oldness/medium'
data/oldness.gemspec ADDED
@@ -0,0 +1,29 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+ require 'oldness/version'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'oldness'
6
+ s.version = Oldness::VERSION
7
+ s.platform = Gem::Platform::RUBY
8
+ s.date = '2011-12-20'
9
+ s.authors = ['Nick Novitski']
10
+ s.email = 'nicknovitski@gmail.com'
11
+ s.homepage = 'http://github.com/njay/oldness'
12
+ s.summary = 'Instant historical perspective'
13
+ s.description = 'A library and shell command that rates the age of different types of things on a five-star system'
14
+
15
+ s.required_rubygems_version = '>= 1.3.7'
16
+ s.specification_version = 3
17
+
18
+ ignores = File.readlines(".gitignore").grep(/\S+/).map {|s| s.chomp }
19
+ dotfiles = [".gitignore"]
20
+
21
+ s.files = Dir["**/*"].reject {|f| File.directory?(f) || ignores.any? {|i| File.fnmatch(i, f) } } + dotfiles
22
+ s.test_files = s.files.grep(/^spec\//)
23
+ s.require_paths = ['lib']
24
+ s.executables = ['oldness']
25
+
26
+ s.add_development_dependency 'rspec'
27
+ s.add_development_dependency 'bundler'
28
+ s.add_dependency 'thor', '~> 0.14'
29
+ end
Binary file
data/readme.markdown ADDED
@@ -0,0 +1,65 @@
1
+ # oldness
2
+
3
+ Oldness is a library and shell command that places the age of a published work on a semi-arbitrary five-star scale.
4
+
5
+ ## Installation
6
+
7
+ gem install oldness
8
+
9
+ require 'oldness'
10
+
11
+ ## Usage
12
+
13
+ ### CLI
14
+
15
+ $ oldness list
16
+ animation
17
+ comic
18
+ film
19
+ history
20
+ literature
21
+ novel
22
+ philosophy
23
+ rpg
24
+ scifi
25
+ videogame
26
+ $ oldness rate comic 1987-10
27
+ ****
28
+ $ oldness ranges movie
29
+ *****: 1894-02-05..1972-09-14
30
+ **** : 1972-09-14..1998-11-27
31
+ *** : 1998-11-27..2007-08-22
32
+ ** : 2007-08-22..2010-07-21
33
+ * : 2010-07-21..2012-01-04
34
+ $ oldness first philosophy
35
+ Tale of Genji (1010), by Murasaki Shikibu
36
+
37
+ ### Library
38
+
39
+ Declaring the existence of a medium is easy; you don't need a national reputation as a culture critic or scholar.
40
+
41
+ class Rubies < Medium
42
+ began Date.new(1979)
43
+ end
44
+
45
+ Although of course it would be better if you could point to a particular work that you saw as kicking things off.
46
+
47
+ class RockNRoll < Medium
48
+ began Date.new(1944), :with => "Strange Things Happen Every Day", :by => "Sister Rosetta Tharpe"
49
+ end
50
+
51
+ Mediums know how to rate by date.
52
+
53
+ Rubies.rate(Date.new(2010, 8, 29)) # => 3
54
+ Rubies.rate("2012-1-4") # => 1
55
+
56
+ They also know what dates fall under what ratings.
57
+
58
+ Rubies.ranges[5] #=> #<Date: 1979-01-01>..#<Date: 2001-01-02>
59
+
60
+ And, if you've told them, they remember their roots.
61
+
62
+ RockNRoll.first.title #=> "Strange Things Happen Every Day"
63
+ Rubies.first.by #=> "Unknown"
64
+
65
+ Just a reminder: mediums are timeless, so they never need to be instantiated.
data/spec/cli_spec.rb ADDED
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ module Oldness
4
+ describe "oldness" do
5
+ before :all do
6
+ Dir.chdir("../bin")
7
+ end
8
+
9
+ describe "rating" do
10
+ it "calls the rating method of the named Medium class with :formatted=>true"
11
+ end
12
+
13
+ describe "range" do
14
+ it "calls the range method of the named Medium class with :formatted=>true"
15
+ end
16
+
17
+ describe "first" do
18
+ it "prints the string formatting of the Work object stored under the first method of the appropriate Medium class"
19
+ end
20
+
21
+ describe "media" do
22
+ it "lists all subclasses of Medium in the object space" do
23
+ list = []
24
+ ObjectSpace.each_object(Class) do |c|
25
+ next unless c.superclass == Medium
26
+ list << c
27
+ end
28
+ `./oldness media`.should == list.collect(&:to_s).sort.inject("") { |l, c| l + c.downcase.sub("oldness::", "")+"\n" }
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+
3
+ module Oldness
4
+ describe Medium do
5
+ def ranges_for(start_date, current_date = Date.today)
6
+ span = (current_date-start_date)
7
+ unit = span/81
8
+ {5 => (start_date..current_date-27*unit),
9
+ 4 => (current_date-27*unit..current_date-9*unit),
10
+ 3 => (current_date-9*unit..current_date-3*unit),
11
+ 2 => (current_date-3*unit..current_date-unit),
12
+ 1 => (current_date-unit..current_date)}
13
+ end
14
+ def rating_for(start_date, work_date, current_date = Date.today)
15
+ ranges_for(start_date, current_date).find {|key, range| range.cover?(work_date)}[0]
16
+ end
17
+ before :all do
18
+ class RubyPrograms < Medium
19
+ began Date.new(1979), :with=>"Hello World", :by => "Matz"
20
+ end
21
+ @ruby_ranges = ranges_for(Date.new(1979))
22
+ end
23
+ describe ".ranges" do
24
+ it "returns a particular kind of hash" do
25
+ RubyPrograms.ranges.should == @ruby_ranges
26
+ end
27
+ it "can take an argument for a particular date" do
28
+ RubyPrograms.ranges(:when => Date.new(2009)).should == ranges_for(Date.new(1979), Date.new(2009))
29
+ end
30
+ it "can have formatted output instead" do
31
+ RubyPrograms.ranges(:formatted => true).should == "*****: #{@ruby_ranges[5]}\n**** : #{@ruby_ranges[4]}\n*** : #{@ruby_ranges[3]}\n** : #{@ruby_ranges[2]}\n* : #{@ruby_ranges[1]}"
32
+ end
33
+ end
34
+ describe ".rate" do
35
+ it "rates oldest possible things as fives" do
36
+ RubyPrograms.rate(Date.new(1979)).should == 5
37
+ end
38
+ it "rates newest possible things as ones" do
39
+ RubyPrograms.rate(Date.today).should == 1
40
+ end
41
+ it "rates everything else properly" do
42
+ [Date.new(2001), Date.new(2008), Date.new(2010)].each do |date|
43
+ RubyPrograms.rate(date).should == rating_for(Date.new(1979), date)
44
+ end
45
+ end
46
+ it "can take an argument for a particular date" do
47
+ RubyPrograms.rate(Date.new(2010), :when => Date.new(2050)).should == 5
48
+ end
49
+ it "can have formatted output instead" do
50
+ RubyPrograms.rate(Date.today, :formatted=>true).should == "*"
51
+ RubyPrograms.rate(Date.new(2010), :when => Date.new(2050), :formatted => true).should == "*****"
52
+ end
53
+ end
54
+ describe ".first" do
55
+ it "returns a Work object with the attributes passed to .began" do
56
+ RubyPrograms.first.title.should == "Hello World"
57
+ RubyPrograms.first.by.should == "Matz"
58
+ RubyPrograms.first.date.should == Date.new(1979)
59
+ RubyPrograms.first.to_s.should == "Hello World (1979), by Matz"
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,3 @@
1
+ require 'rspec'
2
+ require_relative '../lib/oldness'
3
+ require 'date'
data/spec/work_spec.rb ADDED
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ module Oldness
4
+ describe Work do
5
+ context "BC, year only, no title, no credit" do
6
+ let(:w) {Work.new(Date.new(-1000))}
7
+ describe "#date" do
8
+ it "returns the date object" do
9
+ w.date.should == Date.new(-1000)
10
+ end
11
+ end
12
+ describe "#by" do
13
+ it "defaults to 'Unknown'" do
14
+ w.by.should == "Unknown"
15
+ end
16
+ end
17
+ describe "#title" do
18
+ it "defaults to 'Untitled'" do
19
+ w.title.should == "Untitled"
20
+ end
21
+ end
22
+ describe "#to_s" do
23
+ it "Uses 'BC' instead of negative years" do
24
+ "#{w}".should == "Untitled (1000BC)"
25
+ end
26
+ end
27
+ end
28
+ context "Year and Month, Title, no author" do
29
+ let(:w) {Work.new(Date.new(1974, 2), :title => "Dungeons and Dragons")}
30
+ describe "#to_s" do
31
+ it "formats the month as a word" do
32
+ "#{w}".should == "Dungeons and Dragons (February 1974)"
33
+ end
34
+ end
35
+ end
36
+ context "Year, month and day, title and author" do
37
+ let(:w) {Work.new(Date.new(1906, 4, 6), :title => "Humorous Phases of Funny Faces", :by => "J. Stuart Blackton")}
38
+ describe "#to_s" do
39
+ it "includes the day of the month" do
40
+ "#{w}".should == "#{w.title} (April 6, 1906), by #{w.by}"
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ end
data/tasks.thor ADDED
@@ -0,0 +1,98 @@
1
+
2
+ class Gems < Thor
3
+ desc "validate", "Test gemspec"
4
+ def validate
5
+ raise Exception unless gemspec.validate
6
+ end
7
+
8
+ desc "build", "Build gem locally"
9
+ def build
10
+ invoke :validate
11
+ system "gem build #{gemspec.name}.gemspec"
12
+ FileUtils.mkdir_p "pkg"
13
+ FileUtils.mv "#{gemspec.name}-#{gemspec.version}.gem", "pkg"
14
+ end
15
+
16
+ desc "clean", "Delete generated gem files"
17
+ def clean
18
+ FileUtils.rm_rf "pkg"
19
+ end
20
+
21
+ desc "install", "Build and install gem locally"
22
+ def install
23
+ invoke :build
24
+ system "gem install pkg/#{gemspec.name}-#{gemspec.version}"
25
+ end
26
+
27
+ no_tasks do
28
+ def gemspec
29
+ @gemspec ||= eval(File.read(Dir["*.gemspec"].first))
30
+ end
31
+ end
32
+ end
33
+
34
+ class VersionBump < Thor
35
+ desc "manual MAJOR MINOR PATCH", "Set version number to 'MAJOR.MINOR.PATCH'"
36
+ def manual(major, minor, patch)
37
+ version[0], version[1], version[2] = major, minor, patch
38
+ update_version
39
+ end
40
+
41
+ desc "major", "Bump by a major version"
42
+ def major
43
+ version[0] += 1
44
+ version[1] = 0
45
+ version[2] = 0
46
+ update_version
47
+ end
48
+ desc "minor", "Bump by a minor version"
49
+ def minor
50
+ version[1] += 1
51
+ version[2] = 0
52
+ update_version
53
+ end
54
+ desc "patch", "Bump by a patch version"
55
+ def patch
56
+ version[2] += 1
57
+ update_version
58
+ end
59
+ no_tasks do
60
+ def version
61
+ $:.push File.expand_path("../lib", __FILE__)
62
+ require 'oldness/version'
63
+ Oldness::VERSION =~ /(\d+)\.(\d+)\.(\d+)/
64
+ @version ||= [$1.to_i, $2.to_i, $3.to_i]
65
+ end
66
+ def update_version
67
+ path = File.expand_path("./lib/oldness/version.rb")
68
+ new_source = File.read(path).sub(/VERSION\s*=.*/, %Q{VERSION = "#{version.join('.')}"})
69
+ File.open(path, 'w') { |f| f.puts new_source }
70
+ end
71
+ end
72
+ end
73
+
74
+ class Publish < Thor
75
+ desc "github", "Push changes to github"
76
+ def github
77
+ system "git push origin : --tags"
78
+ end
79
+ desc "gem", "Build gem and push it to rubygems"
80
+ def gem
81
+ confirm = ask "This will push whatever's in the working directory to rubygems. Are you SURE? Y/N"
82
+ if confirm == "Y"
83
+ invoke "gems:build"
84
+ system "gem push pkg/#{gemspec.name}-#{gemspec.version}.gem"
85
+ end
86
+ end
87
+ desc "all", "Push to both github and rubygems"
88
+ def all
89
+ invoke :github
90
+ invoke :gem
91
+ end
92
+
93
+ no_tasks do
94
+ def gemspec
95
+ @gemspec ||= eval(File.read(Dir["*.gemspec"].first))
96
+ end
97
+ end
98
+ end
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: oldness
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Nick Novitski
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-12-20 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ type: :development
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: bundler
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ type: :development
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: thor
39
+ prerelease: false
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: "0.14"
46
+ type: :runtime
47
+ version_requirements: *id003
48
+ description: A library and shell command that rates the age of different types of things on a five-star system
49
+ email: nicknovitski@gmail.com
50
+ executables:
51
+ - oldness
52
+ extensions: []
53
+
54
+ extra_rdoc_files: []
55
+
56
+ files:
57
+ - bin/oldness
58
+ - config.ru
59
+ - Gemfile
60
+ - lib/oldness/cli.rb
61
+ - lib/oldness/medium.rb
62
+ - lib/oldness/version.rb
63
+ - lib/oldness/work.rb
64
+ - lib/oldness.rb
65
+ - oldness.gemspec
66
+ - pkg/oldness-0.0.1.gem
67
+ - readme.markdown
68
+ - spec/cli_spec.rb
69
+ - spec/medium_spec.rb
70
+ - spec/spec_helper.rb
71
+ - spec/work_spec.rb
72
+ - tasks.thor
73
+ - .gitignore
74
+ homepage: http://github.com/njay/oldness
75
+ licenses: []
76
+
77
+ post_install_message:
78
+ rdoc_options: []
79
+
80
+ require_paths:
81
+ - lib
82
+ required_ruby_version: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: "0"
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: 1.3.7
94
+ requirements: []
95
+
96
+ rubyforge_project:
97
+ rubygems_version: 1.8.11
98
+ signing_key:
99
+ specification_version: 3
100
+ summary: Instant historical perspective
101
+ test_files:
102
+ - spec/cli_spec.rb
103
+ - spec/medium_spec.rb
104
+ - spec/spec_helper.rb
105
+ - spec/work_spec.rb
106
+ has_rdoc: