urban 0.0.12 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -15,3 +15,12 @@ Session.vim
15
15
  .bundle
16
16
  Gemfile.lock
17
17
  pkg/*
18
+ .yardoc
19
+ doc/*
20
+ coverage/*
21
+
22
+
23
+ # Ignore individual preferences
24
+ .rvmrc
25
+ .rbenv-version
26
+ vendor/bundle/*
data/README.rdoc CHANGED
@@ -6,6 +6,10 @@ random definition from {Urban Dictionary}[http://www.urbandictionary.com].
6
6
  * {Git}[http://github.com/tmiller/urban]
7
7
  * {Bug Tracker}[http://github.com/tmiller/urban/issues]
8
8
 
9
+ == Requirements
10
+
11
+ * >= Ruby 1.9.2-180
12
+
9
13
  == Installation
10
14
 
11
15
  With Rubygems:
@@ -24,15 +28,24 @@ With git and local working copy
24
28
 
25
29
  $ urban cookie monster
26
30
 
27
- === 2. Random word
31
+ === 2. Random definition
32
+
33
+ $ urban -r
34
+
35
+ === 3. Print all definitons
36
+
37
+ $ urban -l cookie monster
28
38
 
29
- $ urban
39
+ === 4. Print help and version
30
40
 
41
+ $ urban --help
42
+ $ urban --version
43
+
31
44
  == To Do
32
45
 
33
- * Write Tests
34
46
  * Document with {YARD}[http://yardoc.org]
35
- * Implement -l switch to list all definitions
47
+ * Print better looking output
48
+ * Test problem words below with new parser
36
49
 
37
50
  == Test words for formatting
38
51
 
data/Rakefile CHANGED
@@ -1 +1,13 @@
1
- require 'bundler/gem_tasks'
1
+ require 'bundler/gem_helper'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+
5
+ task :default => :test
6
+
7
+ require 'rake/testtask'
8
+ Rake::TestTask.new do |t|
9
+ t.libs << "test"
10
+ t.test_files = FileList['test/**/*_test.rb']
11
+ t.verbose = true
12
+ t.warning = true
13
+ end
data/bin/urban CHANGED
@@ -4,4 +4,4 @@ require 'rubygems'
4
4
  require 'urban/version'
5
5
  require 'urban/cli'
6
6
 
7
- Urban.process
7
+ Urban::CLI.new.run(ARGV)
data/lib/urban/cli.rb CHANGED
@@ -1,14 +1,73 @@
1
+ require 'optparse'
2
+ require 'ostruct'
1
3
  require 'urban/dictionary'
2
4
 
3
5
  module Urban
6
+ class CLI
4
7
 
5
- def process
6
- begin
7
- result = ARGV.first ? define(ARGV.join(' ')) : random
8
- puts "#{result[:word]}: #{result[:definition]}"
9
- rescue
10
- puts "ERROR: #{ARGV.join(' ')} not found!"
8
+ attr_accessor :dictionary
9
+
10
+ def initialize
11
+ @dictionary = Urban::Dictionary.new
11
12
  end
12
- end
13
13
 
14
+ def run(args = ARGV)
15
+ options = parse(args)
16
+ results = case
17
+ when options.exit then return
18
+ when options.random then dictionary.random
19
+ when !options.phrase.empty? then dictionary.search(options.phrase)
20
+ end
21
+ output_results(results, options.list)
22
+ end
23
+
24
+ private
25
+
26
+ def output_results(results, list)
27
+ puts "\n#{results.word.upcase}\n\n"
28
+ if list
29
+ results.definitions.each { |definition| puts "#{definition}\n\n" }
30
+ else
31
+ puts "#{results.definitions.first}\n\n"
32
+ end
33
+ end
34
+
35
+ def parse(args)
36
+ options = OpenStruct.new
37
+ options.random = false
38
+ options.list = false
39
+ options.phrase = ''
40
+ opts = OptionParser.new do |o|
41
+ o.banner = "Usage: urban [OPTION]... [PHRASE]"
42
+ o.separator "Search http://urbandictionary.com for definitions"
43
+
44
+ o.separator ''
45
+ o.on('-l', '--list', 'List all definitions') do
46
+ options.list = true
47
+ end
48
+
49
+ o.on('-r', '--random', 'Find random word on urban dictionary') do
50
+ options.random = true
51
+ end
52
+
53
+ o.on('-h', '--help', 'Show this message') do
54
+ options.exit = true
55
+ end
56
+
57
+ o.on('--version', 'Show version') do
58
+ puts "Urban #{Urban::VERSION} (c) Thomas Miller"
59
+ options.exit = true
60
+ end
61
+ end
62
+ opts.parse!(args)
63
+ options.phrase = args.join(' ')
64
+
65
+ if (options.exit || !options.random && options.phrase.empty?)
66
+ puts opts
67
+ options.exit = true
68
+ end
69
+
70
+ options
71
+ end
72
+ end
14
73
  end
@@ -1,53 +1,41 @@
1
- require 'urban/version'
2
-
3
- require 'open-uri'
4
1
  require 'nokogiri'
2
+ require 'ostruct'
3
+ require 'urban/version'
4
+ require 'urban/web'
5
5
 
6
6
  module Urban
7
- extend self
7
+ class Dictionary
8
8
 
9
- URL = 'http://www.urbandictionary.com'
10
-
11
- def random
12
- get_definition(query(:random))
13
- end
9
+ attr_accessor :web_service
14
10
 
15
- def define(word)
16
- get_definition(query(:define, word))
17
- end
18
-
19
- def get_definition(document)
20
- word = wordize(node_to_s(document.at_css('.word')))
21
- definition = definitionize(node_to_s(document.at_css('.definition')))
22
- return { word: word, definition: definition }
23
- end
11
+ def initialize
12
+ @web_service = Urban::Web.new
13
+ end
24
14
 
25
- def query(type, word = nil)
26
- query = "#{type.to_s}.php"
27
- query << "?term=#{word}" if word
28
- doc = Nokogiri.HTML(open(URI.encode("#{URL}/#{query}")))
29
- end
15
+ def random
16
+ document = Nokogiri::HTML(@web_service.query(:random))
17
+ process(document)
18
+ end
30
19
 
31
- def node_to_s(node_set)
32
- node_set.children.each do |node|
33
- case node.name
34
- when 'br'
35
- node.previous.content = node.previous.content << "\n" if node.previous
36
- node.remove
37
- end
20
+ def search(phrase)
21
+ document = Nokogiri::HTML(@web_service.query(:define, phrase))
22
+ process(document)
38
23
  end
39
- return node_set.content.strip.gsub(/\r/, "\n")
40
- end
41
24
 
42
- def capitalize(string, pattern)
43
- return string.gsub(pattern, &:upcase).gsub(/\s{2,}/, ' ')
44
- end
25
+ private
45
26
 
46
- def wordize(string)
47
- return capitalize(string, /^\s*\w/)
48
- end
27
+ def process(document)
28
+ OpenStruct.new({
29
+ word: document.at_xpath('//td[@class="word"][1]').content.strip,
30
+ definitions: parse_definitions(document) })
31
+ end
49
32
 
50
- def definitionize(string)
51
- return capitalize(string, /^\s*\w|\.\s+\w/)
33
+ def parse_definitions(document)
34
+ definitions = document.xpath('//td/div[@class="definition"]').map do |node|
35
+ node.xpath('//br').each { |br| br.replace(Nokogiri::XML::Text.new("\n", node.document)) };
36
+ node.content.strip
37
+ end
38
+ definitions || []
39
+ end
52
40
  end
53
41
  end
data/lib/urban/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Urban
2
- VERSION = '0.0.12'
2
+ VERSION = '0.1.0'
3
3
  end
data/lib/urban/web.rb ADDED
@@ -0,0 +1,13 @@
1
+ require 'urban/version'
2
+ require 'open-uri'
3
+
4
+ module Urban
5
+ class Web
6
+ URL = 'http://www.urbandictionary.com'
7
+
8
+ def query(type, word = nil)
9
+ query = "#{type.to_s}.php" << (word ? "?term=#{word}" : '')
10
+ open(URI::Parser.new.escape("#{URL}/#{query}"))
11
+ end
12
+ end
13
+ end
data/lib/urban.rb CHANGED
@@ -1,2 +1,3 @@
1
- require 'urban/version'
2
1
  require 'urban/dictionary'
2
+ require 'urban/version'
3
+ require 'urban/web'
@@ -0,0 +1,463 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
+ <html lang='en-US' xml:lang='en-US' xmlns='http://www.w3.org/1999/xhtml'>
3
+ <head><script>var NREUMQ=[];NREUMQ.push(["mark","firstbyte",new Date().getTime()]);(function(){var d=document;var e=d.createElement("script");e.type="text/javascript";e.async=true;e.src="https://d1ros97qkrwjf5.cloudfront.net/16/eum/rum.js";var s=d.getElementsByTagName("script")[0];s.parentNode.insertBefore(e,s);})()</script>
4
+ <title>Urban Dictionary: impromptu</title>
5
+ <script type='text/javascript'>
6
+ //<![CDATA[
7
+ var MobileDetector={redirect:function(b,a){if(b&&b.match(/(iPhone|iPod|Android|webOS|Opera Mini|PlayStation Portable)/)){this.go(a)}},go:function(a){window.location=a}};
8
+ MobileDetector.redirect(navigator.userAgent, "/iphone/#define?term=impromptu");
9
+ //]]>
10
+ </script>
11
+
12
+
13
+ <!--[if (!IE)|(gte IE 8)]><!-->
14
+ <link href="http://static3.urbandictionary.com/assets/base-datauri.css?1314062438" media="screen" rel="stylesheet" type="text/css" />
15
+ <!--<![endif]-->
16
+ <!--[if lte IE 7]>
17
+ <link href="http://static3.urbandictionary.com/assets/base.css?1314062438" media="screen" rel="stylesheet" type="text/css" />
18
+ <![endif]-->
19
+ <link href="http://feeds.urbandictionary.com/UrbanWordOfTheDay" rel="alternate" title="Urban Word of the Day" type="application/rss+xml" />
20
+ <link href="http://static0.urbandictionary.com/favicon.ico?1314062439" rel="shortcut icon" /><link href="http://static0.urbandictionary.com/favicon.ico?1314062439" rel="icon" />
21
+
22
+
23
+ <link href='http://static2.urbandictionary.com/osd.xml?1314062439' rel='search' title='Urban Dictionary Search' type='application/opensearchdescription+xml' />
24
+ <meta content='Something that is made up on the spot and given little time to gather and present. Usually referring to speeches that are given only a few minutes ...' name='Description' />
25
+ <meta content='Something that is made up on the spot and given little time to gather and present. Usually referring to speeches that are given only a few minutes ...' property='og:description' />
26
+ <meta content='impromptu' property='og:title' />
27
+ <meta content="http://static0.urbandictionary.com/images/og_image.png?1314062439" property="og:image" />
28
+ <script type="text/javascript">
29
+ //<![CDATA[
30
+ var Record={setRecordingCookie:function(a){document.cookie="recording="+a},getRecordingCookie:function(){var a=document.cookie.match("recording=(true|false)");return a?(a[1]=="true"):null},start:function(a){if(Record.getRecordingCookie()===null){Record.setRecordingCookie(Math.random()<a/100)}if(Record.getRecordingCookie()){document.write(unescape("%3Cscript src='"+(("https:"==document.location.protocol)?"https":"http")+"://c.mouseflow.com/projects/38f33478-b73a-4335-a2df-b0f221197471.js' type='text/javascript'%3E%3C/script%3E"))}}};
31
+ //]]>
32
+ </script>
33
+ <script type='text/javascript'>
34
+ //<![CDATA[
35
+ Record.start(0.001);
36
+ //]]>
37
+ </script>
38
+ <meta content='Urban Dictionary' property='og:site_name' />
39
+ </head>
40
+ <body class='define_controller'>
41
+ <div id='header_background'>
42
+ <div id='header_width'>
43
+ <div id='header'>
44
+ <a href="/" id="logo_anchor"><img alt="" id="logo" src="http://static1.urbandictionary.com/images/logo-holiday.png?1314062439" /></a>
45
+ <div id='like_button'>
46
+ <iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Ffacebook.com%2Furbandictionary&amp;send=false&amp;layout=button_count&amp;width=100&amp;show_faces=false&amp;action=like&amp;colorscheme=light&amp;font&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:100px; height:21px;" allowTransparency="true"></iframe>
47
+ </div>
48
+ <div id='form'>
49
+ <form action="/define.php" method="get">
50
+ <table>
51
+ <tr>
52
+ <td></td>
53
+ <td class='look_up'>look up any word:</td>
54
+ </tr>
55
+ <tr>
56
+ <td>
57
+ <div id='autocompleter_spinner' style='display: none'></div>
58
+ </td>
59
+ <td><input id="term" name="term" tabindex="1" type="text" value="impromptu" /></td>
60
+ <td>
61
+ <input type='submit' value='search' />
62
+ </td>
63
+ </tr>
64
+ </table>
65
+ </form>
66
+ </div>
67
+ <div id='topnav'>
68
+ <a href="/">word of the day</a> <a class="active" href="/popular.php?character=A">dictionary</a> <a href="/thesaurus.php">thesaurus</a> <a href="/names.php">names</a> <a href="/video.list.php">media</a> <a href="/products.php">store</a> <a href="/add.php">add</a> <a href="/editor/staygo.php">edit</a> <a href="http://blog.urbandictionary.com/">blog</a>
69
+ </div>
70
+ </div>
71
+ </div>
72
+ </div>
73
+ <div class='autocomplete' id='term_list' style='display:none'></div>
74
+
75
+ <div id='outer'>
76
+ <div class='' id='whole'>
77
+ <div class='innernav' id='subnav'>
78
+ <a accesskey="1" href="/random.php" title="hot key + 1">random</a> <a href="/popular.php?character=A">A</a> <a href="/popular.php?character=B">B</a> <a href="/popular.php?character=C">C</a> <a href="/popular.php?character=D">D</a> <a href="/popular.php?character=E">E</a> <a href="/popular.php?character=F">F</a> <a href="/popular.php?character=G">G</a> <a href="/popular.php?character=H">H</a> <a class="active" href="/browse.php?word=impromptu">I</a> <a href="/popular.php?character=J">J</a> <a href="/popular.php?character=K">K</a> <a href="/popular.php?character=L">L</a> <a href="/popular.php?character=M">M</a> <a href="/popular.php?character=N">N</a> <a href="/popular.php?character=O">O</a> <a href="/popular.php?character=P">P</a> <a href="/popular.php?character=Q">Q</a> <a href="/popular.php?character=R">R</a> <a href="/popular.php?character=S">S</a> <a href="/popular.php?character=T">T</a> <a href="/popular.php?character=U">U</a> <a href="/popular.php?character=V">V</a> <a href="/popular.php?character=W">W</a> <a href="/popular.php?character=X">X</a> <a href="/popular.php?character=Y">Y</a> <a href="/popular.php?character=Z">Z</a> <a href="/browse.php?character=%2A">#</a> <a href="/yesterday.php?date=2011-08-28">new</a> <a href="/favorites.php">favorites</a>
79
+ </div>
80
+ <table cellpadding='0' cellspacing='0' id='tablist'>
81
+ <tr>
82
+ <td id='leftist'>
83
+ <div class='prev_next_buttons'>
84
+ <a href="#" id="prev_titles" onclick="nearby.go('prev'); return false;" onmouseout="$(this).down().src = &quot;http://static0.urbandictionary.com/images/uparrow.gif?1314062439&quot;" onmouseover="$(this).down().src = &quot;http://static3.urbandictionary.com/images/uparrow_dark.gif?1314062439&quot;"><img src="http://static0.urbandictionary.com/images/uparrow.gif?1314062439" /></a>
85
+ <a href="#" id="next_titles" onclick="nearby.go('next'); return false;" onmouseout="$(this).down().src = &quot;http://static3.urbandictionary.com/images/downarrow.gif?1314062439&quot;" onmouseover="$(this).down().src = &quot;http://static2.urbandictionary.com/images/downarrow_dark.gif?1314062439&quot;"><img src="http://static3.urbandictionary.com/images/downarrow.gif?1314062439" /></a>
86
+ </div>
87
+ <ul id='nearby_titles'>
88
+ <li><a href="/define.php?term=Imprimplicate" class="urbantip">Imprimplicate</a></li><li><a href="/define.php?term=imprint" class="urbantip">imprint</a></li><li><a href="/define.php?term=Imprinting" class="urbantip">Imprinting</a></li><li><a href="/define.php?term=imprints" class="urbantip">imprints</a></li><li><a href="/define.php?term=imprisionate" class="urbantip">imprisionate</a></li><li><a href="/define.php?term=Imprisoned%20in%20the%20elevator" class="urbantip">Imprisoned in the elevator</a></li><li><a href="/define.php?term=imprisonment" class="urbantip">imprisonment</a></li><li><a href="/define.php?term=Imprist" class="urbantip">Imprist</a></li><li><a href="/define.php?term=imprn" class="urbantip">imprn</a></li><li><a href="/define.php?term=improbement" class="urbantip">improbement</a></li><li><a href="/define.php?term=Improdiblass" class="urbantip">Improdiblass</a></li><li><a href="/define.php?term=improgae" class="urbantip">improgae</a></li><li><a href="/define.php?term=impromperaneous" class="urbantip">impromperaneous</a></li><li><a href="/define.php?term=Imprompoo" class="urbantip">Imprompoo</a></li><li><a href="/define.php?term=Impromptitude" class="urbantip">Impromptitude</a></li><li class="active">impromptu</li><li><a href="/define.php?term=Impromptu%20Ding%20Dong" class="urbantip">Impromptu Ding Dong</a></li><li><a href="/define.php?term=impromptu%20peanutbutter%20sandwich" class="urbantip">impromptu peanutbutter sandwich</a></li><li><a href="/define.php?term=Impromptu%20Protein%20Party" class="urbantip">Impromptu Protein Party</a></li><li><a href="/define.php?term=impromtu" class="urbantip">impromtu</a></li><li><a href="/define.php?term=impronathon" class="urbantip">impronathon</a></li><li><a href="/define.php?term=improovisation" class="urbantip">improovisation</a></li><li><a href="/define.php?term=impropaganda" class="urbantip">impropaganda</a></li><li><a href="/define.php?term=Improper%20bo%20I%20don%E2%80%99t%20tell%20thou" class="urbantip">Improper bo I don’t tell thou</a></li><li><a href="/define.php?term=improper%20dumpling" class="urbantip">improper dumpling</a></li><li><a href="/define.php?term=improper%20fraction" class="urbantip">improper fraction</a></li><li><a href="/define.php?term=Improperganda" class="urbantip">Improperganda</a></li><li><a href="/define.php?term=impropertuity" class="urbantip">impropertuity</a></li><li><a href="/define.php?term=improprietous" class="urbantip">improprietous</a></li><li><a href="/define.php?term=improps" class="urbantip">improps</a></li><li><a href="/define.php?term=Improstable" class="urbantip">Improstable</a></li><li><a href="/define.php?term=Improta%20Bush" class="urbantip">Improta Bush</a></li><li><a href="/define.php?term=improtantly" class="urbantip">improtantly</a></li><li><a href="/define.php?term=improtivation" class="urbantip">improtivation</a></li><li><a href="/define.php?term=improv" class="urbantip">improv</a></li><li><a href="/define.php?term=Improv%20Everywhere" class="urbantip">Improv Everywhere</a></li><li><a href="/define.php?term=improvasationalist" class="urbantip">improvasationalist</a></li><li><a href="/define.php?term=improveder" class="urbantip">improveder</a></li><li><a href="/define.php?term=improveise" class="urbantip">improveise</a></li><li><a href="/define.php?term=improver" class="urbantip">improver</a></li><li><a href="/define.php?term=improverished" class="urbantip">improverished</a></li>
89
+ </ul>
90
+ <script type='text/javascript'>
91
+ //<![CDATA[
92
+ window.onDomLoaded = window.onDomLoaded || [];
93
+ window.onDomLoaded.push(function() {
94
+ window.nearby = new Nearby(new NearbyView(), "Imprimplicate", "improverished");
95
+ });
96
+ //]]>
97
+ </script>
98
+
99
+ <div class='prev_next_buttons'>
100
+ <a href="#" id="prev_titles_bottom" onclick="nearby.go('prev'); return false;" onmouseout="$(this).down().src = &quot;http://static0.urbandictionary.com/images/uparrow.gif?1314062439&quot;" onmouseover="$(this).down().src = &quot;http://static3.urbandictionary.com/images/uparrow_dark.gif?1314062439&quot;"><img src="http://static0.urbandictionary.com/images/uparrow.gif?1314062439" /></a>
101
+ <a href="#" id="next_titles_bottom" onclick="nearby.go('next'); return false;" onmouseout="$(this).down().src = &quot;http://static3.urbandictionary.com/images/downarrow.gif?1314062439&quot;" onmouseover="$(this).down().src = &quot;http://static2.urbandictionary.com/images/downarrow_dark.gif?1314062439&quot;"><img src="http://static3.urbandictionary.com/images/downarrow.gif?1314062439" /></a>
102
+ </div>
103
+
104
+ </td>
105
+ <td>
106
+ <div id='content'><!-- google_ad_section_start --><style>
107
+ .related_words { padding: 9px; border: 1px solid #F9C365; margin-bottom: 12px; }
108
+ </style>
109
+ <div class='related_words text'>
110
+ <span id='tags'>
111
+ <b>
112
+ thesaurus for
113
+ <a href="/thesaurus.php?term=impromptu">impromptu</a>:
114
+ </b>
115
+ <br />
116
+
117
+ <a href="/define.php?term=speech" class="urbantip">speech</a>
118
+
119
+ <a href="/define.php?term=bitch" class="urbantip">bitch</a>
120
+
121
+ <a href="/define.php?term=ad-lib" class="urbantip">ad-lib</a>
122
+
123
+ <a href="/define.php?term=extemporaneous" class="urbantip">extemporaneous</a>
124
+
125
+ <a href="/define.php?term=party" class="urbantip">party</a>
126
+ <a href="/thesaurus.php?term=impromptu">more...</a>
127
+ </span>
128
+ </div>
129
+
130
+ <table id='entries'>
131
+ <tr>
132
+ <td class='index'>
133
+ <a href="http://impromptu.urbanup.com/266132">1.</a>
134
+ </td>
135
+ <td class='word'>
136
+ impromptu
137
+ </td>
138
+ <td class='tools' id='tools_266132'>
139
+ <span class='status'></span>
140
+ <span class='thumbs'></span>
141
+ </td>
142
+ </tr>
143
+ <tr>
144
+ <td></td>
145
+ <td class='text' colspan='2' id='entry_266132'>
146
+ <div class="definition">Something that is made up on the spot and given little time to gather and present. Usually referring to speeches that are given only a few minutes to prepare for. </div><div class="example">I had to write an impromptu speech about Anal Cancer in 3 minutes without using the word 'ass' 'anus' 'shit' or 'hair'.</div>
147
+ <div class="zazzle_links"><a href="/products.php?term=impromptu&amp;defid=266132"><span class="zazzle_link_text">buy impromptu mugs & shirts</span></a></div>
148
+ <div class='greenery'>
149
+ by <a href="/author.php?author=Bastardized+Bottomburp" class="author urbantip">Bastardized Bottomburp</a>
150
+ <span class='date'>
151
+ Sep 26, 2003
152
+ </span>
153
+ <a href="#" id="share_this_266132" onclick="emailer.toggle($(&quot;share_this_266132&quot;), &quot;http://impromptu.urbanup.com/266132&quot;, &quot;Entry&quot;, 266132, &quot;http://twitter.com/share?text=impromptu%20-%20Something%20that%20is%20made%20up%20on%20the%20spot%20and%20given%20little%20time%20to%20gather%20and%20present.%20U...\u0026url=http%3A%2F%2Furbanup.com%2F266132\u0026via=urbandictionary&quot;); return false;">share this</a>
154
+ <a href="/video.php?defid=266132&amp;word=impromptu">add a video</a>
155
+ </div>
156
+ </td>
157
+ </tr>
158
+
159
+ <tr>
160
+ <td class='index'>
161
+ <a href="http://impromptu.urbanup.com/313210">2.</a>
162
+ </td>
163
+ <td class='word'>
164
+ impromptu
165
+ </td>
166
+ <td class='tools' id='tools_313210'>
167
+ <span class='status'></span>
168
+ <span class='thumbs'></span>
169
+ </td>
170
+ </tr>
171
+ <tr>
172
+ <td></td>
173
+ <td class='text' colspan='2' id='entry_313210'>
174
+ <div class="definition">On the spot</div><div class="example">When my chik walked in on me with my mistress, I had to make up an impromptu excuse for why my purple headed yogurt slinger was in her tuna taco.</div>
175
+ <div class="zazzle_links"><a href="/products.php?term=impromptu&amp;defid=313210"><span class="zazzle_link_text">buy impromptu mugs & shirts</span></a></div>
176
+ <div class='greenery'>
177
+ by <a href="/author.php?author=Vigilante+DB" class="author urbantip">Vigilante DB</a>
178
+ <span class='date'>
179
+ Oct 25, 2003
180
+ </span>
181
+ <a href="#" id="share_this_313210" onclick="emailer.toggle($(&quot;share_this_313210&quot;), &quot;http://impromptu.urbanup.com/313210&quot;, &quot;Entry&quot;, 313210, &quot;http://twitter.com/share?text=impromptu%20-%20On%20the%20spot\u0026url=http%3A%2F%2Furbanup.com%2F313210\u0026via=urbandictionary&quot;); return false;">share this</a>
182
+ <a href="/video.php?defid=313210&amp;word=impromptu">add a video</a>
183
+ </div>
184
+ </td>
185
+ </tr>
186
+
187
+ <tr>
188
+ <td class='index'>
189
+ <a href="http://impromptu.urbanup.com/263663">3.</a>
190
+ </td>
191
+ <td class='word'>
192
+ impromptu
193
+ </td>
194
+ <td class='tools' id='tools_263663'>
195
+ <span class='status'></span>
196
+ <span class='thumbs'></span>
197
+ </td>
198
+ </tr>
199
+ <tr>
200
+ <td></td>
201
+ <td class='text' colspan='2' id='entry_263663'>
202
+ <div class="definition">Something that is made up on the spot. Can also mean a speech that was made with little or no preparation.</div><div class="example">The drug dealer had to come up with an impromptu excuse to his boss for losing the shipment of crack to the police.</div>
203
+ <div class="zazzle_links"><a href="/products.php?term=impromptu&amp;defid=263663"><span class="zazzle_link_text">buy impromptu mugs & shirts</span></a></div>
204
+ <div class='greenery'>
205
+ by <a href="/author.php?author=AYB" class="author urbantip">AYB</a>
206
+ <span class='date'>
207
+ Sep 24, 2003
208
+ </span>
209
+ <a href="#" id="share_this_263663" onclick="emailer.toggle($(&quot;share_this_263663&quot;), &quot;http://impromptu.urbanup.com/263663&quot;, &quot;Entry&quot;, 263663, &quot;http://twitter.com/share?text=impromptu%20-%20Something%20that%20is%20made%20up%20on%20the%20spot.%20Can%20also%20mean%20a%20speech%20that%20was%20made%20with%20lit...\u0026url=http%3A%2F%2Furbanup.com%2F263663\u0026via=urbandictionary&quot;); return false;">share this</a>
210
+ <a href="/video.php?defid=263663&amp;word=impromptu">add a video</a>
211
+ </div>
212
+ </td>
213
+ </tr>
214
+
215
+ <tr>
216
+ <td colspan='3' style='padding: 10px 0 30px 0'>
217
+ <div style='width: 300px; margin: 0 auto'>
218
+ <script type="text/javascript">
219
+ //<![CDATA[
220
+ var googletag = googletag || {};
221
+ googletag.cmd = googletag.cmd || [];
222
+ googletag.cmd.push(function() {
223
+ googletag.defineUnit('/1031683/ca-pub-4733233155277872/HP_ATF_300x250', [300, 250], 'dfp_homepage_medium_rectangle').addService(googletag.pubads());
224
+ googletag.defineUnit('/1031683/ca-pub-4733233155277872/HP_BTF_300x250', [300, 250], 'dfp_homepage_medium_rectangle_below').addService(googletag.pubads());
225
+ googletag.defineUnit('/1031683/ca-pub-4733233155277872/ROS_BTF_728x90', [728, 90], 'dfp_every_page_leaderboard').addService(googletag.pubads());
226
+ googletag.defineUnit('/1031683/ca-pub-4733233155277872/ROS_Right_160x60', [160, 600], 'dfp_skyscraper').addService(googletag.pubads());
227
+ googletag.defineUnit('/1031683/ca-pub-4733233155277872/Define_300x250', [300, 250], 'dfp_define_rectangle').addService(googletag.pubads());
228
+ googletag.defineUnit('/1031683/ca-pub-4733233155277872/ROS_500x250', [475, 250], 'dfp_define_double_rectangle').addService(googletag.pubads());
229
+
230
+ googletag.pubads().set("alternate_ad_url", "http://www.urbandictionary.com/google_alternate_ad.html");
231
+ googletag.pubads().setTargeting("safe_word", "false");
232
+
233
+ googletag.pubads().enableSingleRequest();
234
+ googletag.enableServices();
235
+ });
236
+
237
+ (function() {
238
+ var gads = document.createElement('script');
239
+ gads.async = true;
240
+ gads.type = 'text/javascript';
241
+ gads.src = "http://www.googletagservices.com/tag/js/gpt.js";
242
+ var node = document.getElementsByTagName('script')[0];
243
+ node.parentNode.insertBefore(gads, node);
244
+ })();
245
+
246
+ //]]>
247
+ </script><div id="dfp_define_rectangle" style="width: 300px; height: 250px"><script type="text/javascript">
248
+ //<![CDATA[
249
+ googletag.cmd.push(function() { googletag.display('dfp_define_rectangle'); });
250
+ //]]>
251
+ </script></div>
252
+ </div>
253
+ </td>
254
+ </tr>
255
+
256
+ </table>
257
+ <div id='paginator'>
258
+
259
+ </div>
260
+ <!-- google_ad_section_end --><div id='email_pane' style='display: none'>
261
+ <form action='javascript:void(0)' onsubmit='emailer.sendEmail(); return false'>
262
+ <table cellpadding='0' cellspacing='0'>
263
+ <tr>
264
+ <th>
265
+ <label for='permalink'>permalink:</label>
266
+ </th>
267
+ <td>
268
+ <input id='permalink' name='permalink' onclick='this.focus(); this.select()' type='text' />
269
+ <input id='shared_id' name='share[shared_id]' type='hidden' />
270
+ <input id='shared_type' name='share[shared_type]' type='hidden' value='Entry' />
271
+ </td>
272
+ </tr>
273
+ <tr>
274
+ <td></td>
275
+ <td>
276
+ Share on
277
+ <span id='share_links'></span>
278
+ </td>
279
+ </tr>
280
+ <tr id='sendtoafriend'>
281
+ <td></td>
282
+ <td>
283
+ <label for='yours'>Send to a friend</label>
284
+ </td>
285
+ </tr>
286
+ <tr>
287
+ <th>
288
+ <label for='yours'>your email:</label>
289
+ </th>
290
+ <td>
291
+ <input id='yours' name='share[yours]' type='text' />
292
+ </td>
293
+ </tr>
294
+ <tr>
295
+ <th>
296
+ <label for='theirs'>their email:</label>
297
+ </th>
298
+ <td>
299
+ <input id='theirs' name='share[theirs]' type='text' />
300
+ </td>
301
+ </tr>
302
+ <tr>
303
+ <th>
304
+ <label for='comment'>comment:</label>
305
+ </th>
306
+ <td>
307
+ <textarea id="comment" name="share[comment]" rows="3"></textarea>
308
+ </td>
309
+ </tr>
310
+ <tr>
311
+ <td></td>
312
+ <td>
313
+ <input id='subscribe' name='subscribe' type='checkbox' />
314
+ <label for='subscribe'> send me the word of the day (it's free)</label>
315
+ </td>
316
+ </tr>
317
+ <tr id='submit'>
318
+ <td></td>
319
+ <td>
320
+ <table>
321
+ <tr>
322
+ <td>
323
+ <input type='submit' value='Send message' />
324
+ </td>
325
+ <td id='status'></td>
326
+ </tr>
327
+ </table>
328
+ </td>
329
+ </tr>
330
+ </table>
331
+ </form>
332
+ </div>
333
+
334
+ </div>
335
+ </td>
336
+ <td id='rightist'>
337
+ <div id="dfp_skyscraper" style="width: 160px; height: 600px"><script type="text/javascript">
338
+ //<![CDATA[
339
+ googletag.cmd.push(function() { googletag.display('dfp_skyscraper'); });
340
+ //]]>
341
+ </script></div>
342
+ </td>
343
+ </tr>
344
+ </table>
345
+
346
+ <div id='bottomad'>
347
+ <div id="dfp_every_page_leaderboard" style="width: 728px; height: 90px; margin: 0 auto"><script type="text/javascript">
348
+ //<![CDATA[
349
+ googletag.cmd.push(function() { googletag.display('dfp_every_page_leaderboard'); });
350
+ //]]>
351
+ </script></div>
352
+ </div>
353
+ </div>
354
+ <div id='copyright'>
355
+ <a href="/">Urban Dictionary</a>
356
+ <span id='years'>
357
+ &copy;1999-2011
358
+ </span>
359
+ <a href='/tos.php'>terms of service</a>
360
+ <a href='/privacy.php'>privacy</a>
361
+ <a href='/feedback.php'>feedback</a>
362
+ <a href='/editor/remove.php'>remove</a>
363
+ <a href='/ads.php'>advertise</a>
364
+ <a href='/poweredby.php'>technology</a>
365
+ <a href='http://jobs.urbandictionary.com/'>jobs</a>
366
+ <a href="/live_support.php" id="live_support" onclick="popAndFocus(&quot;/live_support.php&quot;, &quot;live support&quot;); return false;" style="display: none">live support</a>
367
+ </div>
368
+
369
+ <table class='offsite'>
370
+ <tr>
371
+ <td>
372
+ <table class='facebook'>
373
+ <tr>
374
+ <td>
375
+ <a href="http://feeds.urbandictionary.com/UrbanWordOfTheDay" onclick="urchinTracker(&quot;/outgoing/http_feeds_urbandictionary_com_UrbanWordOfTheDay&quot;)"><div class="rss_image"></div></a>
376
+ </td>
377
+ <td>
378
+ <a href="http://feeds.urbandictionary.com/UrbanWordOfTheDay" onclick="urchinTracker(&quot;/outgoing/http_feeds_urbandictionary_com_UrbanWordOfTheDay&quot;)">add via <b>rss</b></a>
379
+ <br />
380
+ <a href="http://www.google.com/calendar/render?cid=http%3A%2F%2Fwww.urbandictionary.com%2Fdaily.ics" onclick="urchinTracker(&quot;/outgoing/http_www_google_com_calendar_render_cid_http_A_F_Fwww_urbandictionary_com_Fdaily_ics&quot;)">or <b>google calendar</b></a>
381
+ </td>
382
+ </tr>
383
+ </table>
384
+ </td>
385
+ <td>
386
+ <table class='facebook'>
387
+ <tr>
388
+ <td>
389
+ <a href="http://www.facebook.com/profile.php?id=6295613171" onclick="urchinTracker(&quot;/outgoing/http_www_facebook_com_profile_php_id&quot;)"><div class="facebook_image"></div></a>
390
+ </td>
391
+ <td>
392
+ <a href="http://www.facebook.com/profile.php?id=6295613171" onclick="urchinTracker(&quot;/outgoing/http_www_facebook_com_profile_php_id&quot;)">add <b>urban dictionary</b><br/>on <b>facebook</b></a>
393
+ </td>
394
+ </tr>
395
+ </table>
396
+ </td>
397
+ <td>
398
+ <table class='facebook'>
399
+ <tr>
400
+ <td>
401
+ <div class='iphone_image'></div>
402
+ </td>
403
+ <td>
404
+ search ud
405
+ <br />
406
+ <a href="http://iphone.urbandictionary.com/" onclick="urchinTracker(&quot;/outgoing/http_iphone_urbandictionary_com&quot;)">from your <b>phone</b></a>
407
+ <br />
408
+ <a href="/sms.php" onclick="urchinTracker(&quot;/outgoing/sms_php&quot;)">or via <b>txt</b></a>
409
+ </td>
410
+ </tr>
411
+ </table>
412
+ </td>
413
+ <td>
414
+ <table class='facebook'>
415
+ <tr>
416
+ <td>
417
+ <a href="http://twitter.com/urbandaily/" onclick="urchinTracker(&quot;/outgoing/http_twitter_com_urbandaily&quot;)"><div class="twitter_image"></div></a>
418
+ </td>
419
+ <td>
420
+ <a href="http://twitter.com/urbandaily/" onclick="urchinTracker(&quot;/outgoing/http_twitter_com_urbandaily&quot;)"><b>follow urbandaily</b><br/>on twitter</a>
421
+ </td>
422
+ </tr>
423
+ </table>
424
+ </td>
425
+ </tr>
426
+ </table>
427
+
428
+ </div>
429
+ <script src="http://static2.urbandictionary.com/assets/base.js?1314062438" type="text/javascript"></script>
430
+ <script type='text/javascript'>
431
+ //<![CDATA[
432
+ var host_env = new HostEnv(document.location.hostname);
433
+ Uncacheable.instance.load([266132,313210,263663], host_env.uncacheableUrl());
434
+ //]]>
435
+ </script>
436
+
437
+
438
+
439
+ <script type="text/javascript">
440
+
441
+ var _gaq = _gaq || [];
442
+ _gaq.push(['_setAccount', "UA-31805-1"]);
443
+ _gaq.push(['_trackPageview']);
444
+
445
+ (function() {
446
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
447
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
448
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
449
+ })();
450
+
451
+ </script>
452
+
453
+ <!-- Start Quantcast tag -->
454
+ <script type="text/javascript" src="http://edge.quantserve.com/quant.js"></script>
455
+ <script type="text/javascript">
456
+ _qacct="p-77H27_lnOeCCI";quantserve();</script>
457
+ <noscript>
458
+ <img src="http://pixel.quantserve.com/pixel/p-77H27_lnOeCCI.gif" style="display: none" height="1" width="1" alt=""/></noscript>
459
+ <!-- End Quantcast tag -->
460
+
461
+
462
+ <script type="text/javascript" charset="utf-8">NREUMQ.push(["nrf2","beacon-1.newrelic.com","77b5945d2d",131063,"cFoIQEcMXQ5TSh4FB1VcCFEaCl8GU0A=",1,41])</script></body>
463
+ </html>
@@ -0,0 +1,33 @@
1
+ $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
2
+
3
+ require 'minitest/autorun'
4
+ require 'urban'
5
+ require 'urban/cli'
6
+
7
+ TEST_PHRASE = OpenStruct.new({
8
+ word: 'impromptu',
9
+ definitions: [
10
+ 'Something that is made up on the spot and given little time to gather and present. Usually referring to speeches that are given only a few minutes to prepare for.',
11
+ 'On the spot',
12
+ 'Something that is made up on the spot. Can also mean a speech that was made with little or no preparation.'
13
+ ]})
14
+
15
+ def load_file(filename)
16
+ IO.read(File.expand_path("../data/#{filename}", __FILE__))
17
+ end
18
+
19
+ ['refute', 'assert'].each do |action|
20
+ eval <<-EOM
21
+ def #{action}_cli_prints(matches, &block)
22
+ out, err = capture_io(&block)
23
+ [*matches].each { |match| #{action}_match(match, out) }
24
+ end
25
+ EOM
26
+ end
27
+
28
+ module Stub
29
+ def stub(name, &block)
30
+ self.class.send(:remove_method, name) if respond_to?(name)
31
+ self.class.send(:define_method, name, &block)
32
+ end
33
+ end
@@ -0,0 +1,101 @@
1
+ require 'test_helper'
2
+
3
+ class CLITest < MiniTest::Unit::TestCase
4
+
5
+ def setup
6
+ @program = Urban::CLI.new
7
+ end
8
+
9
+ def test_parse_prints_help
10
+ expectations = [
11
+ /Usage: urban \[OPTION\]\.\.\. \[PHRASE\]/,
12
+ /Search http:\/\/urbandictionary\.com for definitions/,
13
+ /-l, --list\s*List all definitions/,
14
+ /-r, --random\s*Find random word on urban dictionary/,
15
+ /-h, --help\s*Show this message/,
16
+ /-version\s*Show version/
17
+ ]
18
+ assert_cli_prints(expectations) { @program.run(["-h"]) }
19
+ end
20
+
21
+ def test_parse_prints_version_info
22
+ args = ['-v']
23
+ assert_cli_prints(/^Urban \d+\.\d+\.\d+ \(c\) Thomas Miller$/) { @program.run(args) }
24
+ end
25
+
26
+ def test_no_args_prints_help
27
+ args = []
28
+ assert_cli_prints(/Usage: urban \[OPTION\]\.\.\. \[PHRASE\]/) { @program.run(args) }
29
+ end
30
+
31
+ def test_no_args_with_list_option_prints_help
32
+ args = ['-l']
33
+ assert_cli_prints(/Usage: urban \[OPTION\]\.\.\. \[PHRASE\]/) { @program.run(args) }
34
+ end
35
+
36
+ def test_parse_returns_random
37
+ capture_io do
38
+ actual = @program.send(:parse, ['-r'])
39
+ assert(actual.random, 'Args -r; Expected true, returned false')
40
+ actual = @program.send(:parse, ['--random'])
41
+ assert(actual.random, 'Args --random Expected true, returned false')
42
+ end
43
+ end
44
+
45
+ def test_parse_returns_list
46
+ capture_io do
47
+ actual = @program.send(:parse, ['-l'])
48
+ assert(actual.list, 'Args: -l; Expected true, returned false')
49
+ actual = @program.send(:parse, ['--list'])
50
+ assert(actual.list, 'Args: --list; Expected true, returned false')
51
+ end
52
+ end
53
+
54
+ def test_parse_returns_phrase
55
+ capture_io do
56
+ actual = @program.send(:parse, ['Cookie', 'monster'])
57
+ assert_equal('Cookie monster', actual.phrase)
58
+ actual = @program.send(:parse, ['Cookie monster'])
59
+ assert_equal('Cookie monster', actual.phrase)
60
+ end
61
+ end
62
+
63
+ class CLIDefinintionOutputTest < CLITest
64
+ def setup
65
+ @dictionary = MiniTest::Mock.new
66
+ super
67
+ end
68
+
69
+ def test_cli_prints_random_definition
70
+ args = ['-r']
71
+ expected = [ "#{TEST_PHRASE.word.upcase}", TEST_PHRASE.definitions.first ]
72
+ @program.dictionary = @dictionary.expect(:random, TEST_PHRASE)
73
+ assert_cli_prints(expected) { @program.run(args) }
74
+ @dictionary.verify
75
+ end
76
+
77
+ def test_cli_prints_random_definition_list
78
+ args = ['-rl']
79
+ expected = [ "#{TEST_PHRASE.word.upcase}", *TEST_PHRASE.definitions ]
80
+ @program.dictionary = @dictionary.expect(:random, TEST_PHRASE)
81
+ assert_cli_prints(expected) { @program.run(args) }
82
+ @dictionary.verify
83
+ end
84
+
85
+ def test_cli_prints_definition
86
+ args = ['impromptu']
87
+ expected = [ "#{TEST_PHRASE.word.upcase}", TEST_PHRASE.definitions.first ]
88
+ @program.dictionary = @dictionary.expect(:search, TEST_PHRASE, ['impromptu'])
89
+ assert_cli_prints(expected) { @program.run(['impromptu']) }
90
+ @dictionary.verify
91
+ end
92
+
93
+ def test_cli_prints_definition_list
94
+ args = ['-l', 'impromptu']
95
+ expected = [ "#{TEST_PHRASE.word.upcase}", *TEST_PHRASE.definitions ]
96
+ @program.dictionary = @dictionary.expect(:search, TEST_PHRASE, ['impromptu'])
97
+ assert_cli_prints(expected) { @program.run(args) }
98
+ @dictionary.verify
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,21 @@
1
+ require 'test_helper'
2
+
3
+ class DictionaryTest < MiniTest::Unit::TestCase
4
+
5
+ def setup
6
+ @web_service = MiniTest::Mock.new
7
+ @dictionary = Urban::Dictionary.new
8
+ end
9
+
10
+ def test_dictionary_calls_random
11
+ @dictionary.web_service = @web_service.expect(:query, load_file('impromptu.html') ,[:random])
12
+ assert_equal(TEST_PHRASE, @dictionary.random)
13
+ @web_service.verify
14
+ end
15
+
16
+ def test_dictionary_calls_define
17
+ @dictionary.web_service = @web_service.expect(:query, load_file('impromptu.html'), [:define, 'impromptu'])
18
+ assert_equal(TEST_PHRASE, @dictionary.search('impromptu'))
19
+ @web_service.verify
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ require 'test_helper'
2
+
3
+ class WebTest < MiniTest::Unit::TestCase
4
+
5
+ def setup
6
+ @web_service = (Urban::Web.new).extend Stub
7
+ @web_service.stub(:open) { |arg| return arg; }
8
+ end
9
+
10
+ def test_web_sends_request_to_random
11
+ expected = 'http://www.urbandictionary.com/random.php'
12
+ actual = @web_service.query(:random)
13
+ assert_equal(expected, actual)
14
+ end
15
+
16
+ def test_web_sends_request_to_define_with_phrase
17
+ expected = 'http://www.urbandictionary.com/define.php?term=Cookie%20monster'
18
+ actual = @web_service.query(:define, 'Cookie monster')
19
+ assert_equal(expected, actual)
20
+ end
21
+ end
data/urban.gemspec CHANGED
@@ -7,6 +7,7 @@ Gem::Specification.new do |s|
7
7
  s.version = Urban::VERSION
8
8
  s.authors = ['Thomas Miller']
9
9
  s.email = ['jackerran@gmail.com']
10
+ s.licenses = ['MIT']
10
11
  s.homepage = 'https://github.com/tmiller/urban'
11
12
  s.summary = %q{A command line tool that interfaces with Urban Dictionary.}
12
13
  s.description = %q{Urban is a command line tool that allows you to look up definitions
@@ -19,6 +20,6 @@ Gem::Specification.new do |s|
19
20
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
21
  s.require_paths = ['lib']
21
22
 
22
- s.add_dependency 'nokogiri'
23
- s.add_development_dependency 'ruby-debug19'
23
+ s.add_dependency 'nokogiri', '>= 1.5.0'
24
+ s.add_development_dependency 'rake', '>= 0.8.7'
24
25
  end
metadata CHANGED
@@ -1,54 +1,48 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: urban
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
4
5
  prerelease:
5
- version: 0.0.12
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Thomas Miller
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2011-08-17 00:00:00 -05:00
14
- default_executable:
15
- dependencies:
16
- - !ruby/object:Gem::Dependency
12
+ date: 2011-09-02 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
17
15
  name: nokogiri
18
- prerelease: false
19
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &2153564560 !ruby/object:Gem::Requirement
20
17
  none: false
21
- requirements:
22
- - - ">="
23
- - !ruby/object:Gem::Version
24
- version: "0"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 1.5.0
25
22
  type: :runtime
26
- version_requirements: *id001
27
- - !ruby/object:Gem::Dependency
28
- name: ruby-debug19
29
23
  prerelease: false
30
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: *2153564560
25
+ - !ruby/object:Gem::Dependency
26
+ name: rake
27
+ requirement: &2153564060 !ruby/object:Gem::Requirement
31
28
  none: false
32
- requirements:
33
- - - ">="
34
- - !ruby/object:Gem::Version
35
- version: "0"
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: 0.8.7
36
33
  type: :development
37
- version_requirements: *id002
38
- description: |-
39
- Urban is a command line tool that allows you to look up definitions
40
- or pull a random definition from Urban Dictionary.
41
- email:
34
+ prerelease: false
35
+ version_requirements: *2153564060
36
+ description: ! "Urban is a command line tool that allows you to look up definitions\n
37
+ \ or pull a random definition from Urban Dictionary."
38
+ email:
42
39
  - jackerran@gmail.com
43
- executables:
40
+ executables:
44
41
  - urban
45
42
  extensions: []
46
-
47
43
  extra_rdoc_files: []
48
-
49
- files:
44
+ files:
50
45
  - .gitignore
51
- - .rvmrc
52
46
  - Gemfile
53
47
  - LICENSE
54
48
  - README.rdoc
@@ -58,34 +52,41 @@ files:
58
52
  - lib/urban/cli.rb
59
53
  - lib/urban/dictionary.rb
60
54
  - lib/urban/version.rb
55
+ - lib/urban/web.rb
56
+ - test/data/impromptu.html
57
+ - test/test_helper.rb
58
+ - test/urban/cli_test.rb
59
+ - test/urban/dictionary_test.rb
60
+ - test/urban/web_test.rb
61
61
  - urban.gemspec
62
- has_rdoc: true
63
62
  homepage: https://github.com/tmiller/urban
64
- licenses: []
65
-
63
+ licenses:
64
+ - MIT
66
65
  post_install_message:
67
66
  rdoc_options: []
68
-
69
- require_paths:
67
+ require_paths:
70
68
  - lib
71
- required_ruby_version: !ruby/object:Gem::Requirement
69
+ required_ruby_version: !ruby/object:Gem::Requirement
72
70
  none: false
73
- requirements:
74
- - - ">="
75
- - !ruby/object:Gem::Version
76
- version: "0"
77
- required_rubygems_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ! '>='
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
76
  none: false
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: "0"
77
+ requirements:
78
+ - - ! '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
83
81
  requirements: []
84
-
85
82
  rubyforge_project: urban
86
- rubygems_version: 1.6.2
83
+ rubygems_version: 1.8.6
87
84
  signing_key:
88
85
  specification_version: 3
89
86
  summary: A command line tool that interfaces with Urban Dictionary.
90
- test_files: []
91
-
87
+ test_files:
88
+ - test/data/impromptu.html
89
+ - test/test_helper.rb
90
+ - test/urban/cli_test.rb
91
+ - test/urban/dictionary_test.rb
92
+ - test/urban/web_test.rb
data/.rvmrc DELETED
@@ -1 +0,0 @@
1
- rvm --create use "ruby-1.9.2-p180@urban"