cinch-toolbox 1.0.3 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,10 +1,10 @@
1
- # Cinch Toolbox
1
+ # Cinch::Toolbox
2
2
 
3
- [![Gem Version](https://badge.fury.io/rb/cinch-toolbox.png)](http://badge.fury.io/rb/cinch-dicebag)
4
- [![Dependency Status](https://gemnasium.com/bhaberer/cinch-toolbox.png)](https://gemnasium.com/bhaberer/cinch-dicebag)
5
- [![Build Status](https://travis-ci.org/bhaberer/cinch-toolbox.png?branch=master)](https://travis-ci.org/bhaberer/cinch-dicebag)
6
- [![Coverage Status](https://coveralls.io/repos/bhaberer/cinch-toolbox/badge.png?branch=master)](https://coveralls.io/r/bhaberer/cinch-dicebag?branch=master)
7
- [![Code Climate](https://codeclimate.com/github/bhaberer/cinch-toolbox.png)](https://codeclimate.com/github/bhaberer/cinch-dicebag)
3
+ [![Gem Version](https://badge.fury.io/rb/cinch-toolbox.png)](http://badge.fury.io/rb/cinch-toolbox)
4
+ [![Dependency Status](https://gemnasium.com/bhaberer/cinch-toolbox.png)](https://gemnasium.com/bhaberer/cinch-toolbox)
5
+ [![Build Status](https://travis-ci.org/bhaberer/cinch-toolbox.png?branch=master)](https://travis-ci.org/bhaberer/cinch-toolbox)
6
+ [![Coverage Status](https://coveralls.io/repos/bhaberer/cinch-toolbox/badge.png?branch=master)](https://coveralls.io/r/bhaberer/cinch-toolbox?branch=master)
7
+ [![Code Climate](https://codeclimate.com/github/bhaberer/cinch-toolbox.png)](https://codeclimate.com/github/bhaberer/cinch-toolbox)
8
8
 
9
9
  This is just a gem required fro many of my plugins, it facilitates a variety of mundane operations.
10
10
 
@@ -4,18 +4,19 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'cinch/toolbox/version'
5
5
 
6
6
  Gem::Specification.new do |gem|
7
- gem.name = "cinch-toolbox"
7
+ gem.name = 'cinch-toolbox'
8
8
  gem.version = Cinch::Toolbox::VERSION
9
- gem.authors = ["Brian Haberer"]
10
- gem.email = ["bhaberer@gmail.com"]
9
+ gem.authors = ['Brian Haberer']
10
+ gem.email = ['bhaberer@gmail.com']
11
11
  gem.description = %q{A gem of various methods used in many of my plugins. If you need the namespace, let me know.}
12
12
  gem.summary = %q{Common methods used in Cinch Plugins.}
13
- gem.homepage = "https://github.com/bhaberer/cinch-toolbox"
13
+ gem.homepage = 'https://github.com/bhaberer/cinch-toolbox'
14
+ gem.license = 'MIT'
14
15
 
15
16
  gem.files = `git ls-files`.split($/)
16
17
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
18
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
- gem.require_paths = ["lib"]
19
+ gem.require_paths = ['lib']
19
20
 
20
21
  gem.add_development_dependency 'rake'
21
22
  gem.add_development_dependency 'rspec'
data/lib/cinch/toolbox.rb CHANGED
@@ -5,125 +5,162 @@ require 'patron'
5
5
  require 'nokogiri'
6
6
 
7
7
  module Cinch
8
+ # Module for conveniance methods used in multiple Cinch plugins.
8
9
  module Toolbox
9
-
10
10
  # Get an element of the supplied website
11
11
  # @param [String] url The url to access.
12
12
  # @param [String] selector The the selector to try an acquire on the page.
13
- # @param [String] mode (:css) Set this to the kind of selection you want to do.
14
- # @option [String] :mode :css Fetch just the text content at the css selector.
15
- # @option [String] :mode :css_full Fetch the markup and text content at the css selector.
16
- # @option [String] :mode :xpath Fetch just the text content at the xpath selector.
17
- # @option [String] :mode :xpath_full Fetch the markup and text at the xpath selector.
18
- # @return [String] The content ofg the Element or Nil if the element could not be found.
19
- def Toolbox.get_html_element(url, selector, mode = :css)
13
+ # @param [String] mode (:css) Set this to the kind of selection you want to
14
+ # do.
15
+ # @option [String] :mode :css Fetch just the text content at the css
16
+ # selector.
17
+ # @option [String] :mode :css_full Fetch the markup and text content at
18
+ # the css selector.
19
+ # @option [String] :mode :xpath Fetch just the text content at the
20
+ # xpath selector.
21
+ # @option [String] :mode :xpath_full Fetch the markup and text at the
22
+ # xpath selector.
23
+ # @return [String] The content ofg the Element or Nil if the element
24
+ # could not be found.
25
+ def self.get_html_element(url, selector, mode = :css)
20
26
  # Make sure the URL is legit
21
- url = URI::extract(url, ["http", "https"]).first
22
- url = Nokogiri::HTML(open(url))
23
-
24
- content = case mode
25
- when :css, :xpath
26
- page = url.send(mode.to_sym, selector)
27
- page.first.content unless page.first.nil?
28
- when :css_full, :xpath_full
29
- url.send("at_#{mode.to_s.gsub(/_full/, '')}", selector).to_html
30
- end
31
- return content
32
- rescue SocketError, RuntimeError
33
- # Rescue for any kind of network sillyness
34
- return nil
27
+ url = Nokogiri.HTML(open(extract_url(url)))
28
+
29
+ case mode
30
+ when :css, :xpath
31
+ page = url.send(mode.to_sym, selector)
32
+ page.first.content unless page.first.nil?
33
+ when :css_full, :xpath_full
34
+ url.send("at_#{mode.to_s.gsub(/_full/, '')}", selector).to_html
35
+ end
36
+ # Rescue for any kind of network sillyness
37
+ rescue SocketError, RuntimeError, HTTPError
38
+ nil
35
39
  end
36
40
 
37
41
  # Get the title of a given web page.
38
42
  # @param [String] url The url of the page you want the title from.
39
- # @return [String] Either contents of the title element or a notion for an image.
40
- def Toolbox.get_page_title(url)
43
+ # @return [String] Either contents of the title element or a notion
44
+ # for an image.
45
+ def self.get_page_title(url)
41
46
  # Make sure the URL is legit
42
- url = URI::extract(url, ["http", "https"]).first
43
-
44
- # If the link is to an image, extract the filename.
45
- if url.match(/\.jpg|jpeg|gif|png$/)
46
- # unless it's from reddit, then change the url to the gallery to get the image's caption.
47
- if imgur_id = url[/https?:\/\/i\.imgur\.com.*\/([A-Za-z0-9]+)\.(jpg|jpeg|png|gif)/, 1]
48
- url = "http://imgur.com/#{imgur_id}"
49
- else
50
- site = url.match(/([^\.]+\.[^\/]+)/)
51
- return site.nil? ? "Image [#{url}]!!!" : "Image from #{site[1]}"
52
- end
53
- end
47
+ url = extract_url(url)
54
48
 
55
- # Grab the element, return nothing if the site doesn't have a title.
56
- title = Toolbox.get_html_element(url, 'title')
57
- return title.strip.gsub(/\s+/, ' ') unless title.nil?
49
+ if url.match(/([^\s]+(\.(?i)(jpe?g|png|gif|bmp))$)/)
50
+ # If the link is to an image, extract the filename.
51
+ title = get_image_title(url)
52
+ else
53
+ # Grab the element, return nothing if the site doesn't have a title.
54
+ title = Toolbox.get_html_element(url, 'title')
55
+ end
56
+ title.strip.gsub(/\s+/, ' ') unless title.nil?
58
57
  end
59
58
 
60
59
  # Shorten a URL via the configured shortener
61
60
  # @param [String] url The url of the page you want to shorten.
62
61
  # @return [String] The shortened url.
63
- def Toolbox.shorten(url)
62
+ def self.shorten(url)
64
63
  return url if url.length < 45
65
- return shortener.get("create.php?format=simple&url=#{url}").body
64
+ uri = URI.parse("http://is.gd/create.php?format=simple&url=#{url}")
65
+ shortened = Net::HTTP.get(uri)
66
+ shortened if shortened.match(%r(https?://is.gd/))
66
67
  end
67
68
 
68
69
  # Expand a previously shortened URL via the configured shortener
69
70
  # @param [String] url A previously shortened url.
70
71
  # @return [String] The expanded url.
71
- def Toolbox.expand(url)
72
- shortener.get("forward.php?format=simple&shorturl=#{url}").body
72
+ def self.expand(url)
73
+ uri = URI.parse("http://is.gd/forward.php?format=simple&shorturl=#{url}")
74
+ unshortened = Net::HTTP.get(uri)
75
+ unshortened unless unshortened.match(%r(https?://is.gd/))
73
76
  end
74
77
 
75
- # Truncate a given block of text, used for making sure the bot doesn't flood.
78
+ # Truncate a given block of text, used for making sure the bot doesn't
79
+ # flood.
76
80
  # @param [String] text The block of text to check.
77
- # @param [Fixnum] length (250) length to which to constrain the block of text.
78
- def Toolbox.truncate(text, length = 250)
81
+ # @param [Fixnum] length (250) length to which to constrain the
82
+ # block of text.
83
+ def self.truncate(text, length = 250)
79
84
  text = text.gsub(/\n/, ' ')
80
- if text.length > length
81
- text = text[0, (length - 3)] + '...'
82
- end
83
- return text
85
+ text = text[0, (length - 3)] + '...' if text.length > length
86
+ text
84
87
  end
85
88
 
86
- # Simple check to make sure people are using a command via the main channel for plugins that
87
- # require a channel for context.
88
- def Toolbox.sent_via_private_message?(m, error = "You must use that command in the main channel.")
89
+ # Simple check to make sure people are using a command via the main channel
90
+ # for plugins that require a channel for context.
91
+ def self.sent_via_private_message?(m, error = nil)
89
92
  return false unless m.channel.nil?
93
+ error = 'You must use that command in the main channel.' if error.nil?
90
94
  m.user.msg error
91
- return true
95
+ true
92
96
  end
93
97
 
94
98
  # Used to render a period of time in a uniform string.
95
- # There is probably a much better way to do this, so FIXME
99
+ # There is probably a much better way to do this
96
100
  # @param [Fixnum] secs Number of seconds to render into a string.
97
- def Toolbox.time_format(secs, units = nil, format = :long)
98
- data = { :days => (secs / 86400).floor,
99
- :hours => ((secs % 86400) / 3600).floor,
100
- :mins => ((secs % 3600) / 60).floor,
101
- :seconds => (secs % 60).floor }
102
- string = []
103
- data.keys.map do |period|
104
- if period == :seconds || !(data[period].zero? && string.empty?)
105
- if units.nil? || units.include?(period)
106
- string << "#{data[period]}#{format == :long ? " #{period}" : period.slice(0)}"
107
- end
108
- end
109
- end
110
- return string.join(', ')
101
+ def self.time_format(secs, units = nil, format = :long)
102
+ time = build_time_hash(secs, units)
103
+ parse_time_hash(time, format)
104
+ end
105
+
106
+ # Extract the first url from a string
107
+ # @param [String] url String to parse URIs from.
108
+ # @return [URI] URI created from the url.
109
+ def self.extract_url(url)
110
+ extract_urls(url).first
111
+ end
112
+
113
+ # Extract the urls from a string
114
+ # @param [String] url String to parse URIs from.
115
+ # @return [Array] List of URIs created from the string.
116
+ def self.extract_urls(url)
117
+ URI.extract(url, %w(http https))
111
118
  end
112
119
 
113
120
  private
114
121
 
115
- def Toolbox.shortener
116
- short = Patron::Session.new
117
- short.base_url = 'http://is.gd/'
118
- return short
122
+ def self.get_image_title(url)
123
+ if url.match(/imgur/)
124
+ # Get the page title if it's imgur
125
+ imgur_image_title(url)
126
+ else
127
+ site = url[/([^\.]+\.[^\/]+)/, 1]
128
+ site.nil? ? "Image [#{url}]" : "Image from #{site}"
129
+ end
130
+ end
131
+
132
+ def self.imgur_image_title(url)
133
+ imgur_id = url[%r(https?://i\.imgur\.com.*/(\w+)\.(\D{3,4})), 1]
134
+ url = "http://imgur.com/#{imgur_id}"
135
+ Toolbox.get_html_element(url, 'title')
119
136
  end
120
137
 
138
+ def self.build_time_hash(secs, units)
139
+ { days: (secs / 86_400).floor,
140
+ hours: ((secs % 86_400) / 3600).floor,
141
+ mins: ((secs % 3_600) / 60).floor,
142
+ seconds: (secs % 60).floor }
143
+ .delete_if { |period, _time| units && !units.include?(period) }
144
+ end
145
+
146
+ def self.parse_time_hash(times, format)
147
+ string = []
148
+ times.each_pair do |period, time|
149
+ if period == :seconds || !(time.zero? && string.empty?)
150
+ string << [time, format == :long ? " #{period}" : period.slice(0)]
151
+ .join
152
+ end
153
+ end
154
+ string.join(', ')
155
+ end
121
156
  end
122
157
  end
123
158
 
159
+ # Patch OpenURI to allow for redirection from http => https
124
160
  module OpenURI
125
- def OpenURI.redirectable?(uri1, uri2) # :nodoc:
161
+ def self.redirectable?(uri1, uri2) # :nodoc:
126
162
  uri1.scheme.downcase == uri2.scheme.downcase ||
127
- (/\A(?:http|ftp)\z/i =~ uri1.scheme && /\A(?:http|ftp|https)\z/i =~ uri2.scheme)
163
+ /\A(?:http|ftp)\z/i =~ uri1.scheme &&
164
+ /\A(?:http|ftp|https)\z/i =~ uri2.scheme
128
165
  end
129
166
  end
@@ -1,5 +1,7 @@
1
+ # -*- encoding: utf-8 -*-
1
2
  module Cinch
3
+ # Version Info
2
4
  module Toolbox
3
- VERSION = "1.0.3"
5
+ VERSION = '1.1.0'
4
6
  end
5
7
  end
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,11 @@
1
1
  require 'coveralls'
2
- Coveralls.wear!
2
+ require 'simplecov'
3
+
4
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
5
+ SimpleCov::Formatter::HTMLFormatter,
6
+ Coveralls::SimpleCov::Formatter
7
+ ]
8
+ SimpleCov.start
9
+
3
10
  require 'cinch/toolbox'
4
11
  require 'cinch/test'
5
-
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cinch-toolbox
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-09 00:00:00.000000000 Z
12
+ date: 2014-02-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -143,7 +143,8 @@ files:
143
143
  - spec/cinch-toolbox_spec.rb
144
144
  - spec/spec_helper.rb
145
145
  homepage: https://github.com/bhaberer/cinch-toolbox
146
- licenses: []
146
+ licenses:
147
+ - MIT
147
148
  post_install_message:
148
149
  rdoc_options: []
149
150
  require_paths:
@@ -169,3 +170,4 @@ summary: Common methods used in Cinch Plugins.
169
170
  test_files:
170
171
  - spec/cinch-toolbox_spec.rb
171
172
  - spec/spec_helper.rb
173
+ has_rdoc: