reagent-snip-snap 0.1.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/README.rdoc +45 -0
- data/Rakefile +57 -0
- data/lib/snip_snap/client.rb +48 -0
- data/lib/snip_snap/flickr.rb +22 -0
- data/lib/snip_snap/imgly.rb +18 -0
- data/lib/snip_snap/skitch.rb +14 -0
- data/lib/snip_snap/twitpic.rb +18 -0
- data/lib/snip_snap/version.rb +13 -0
- data/lib/snip_snap/yfrog.rb +19 -0
- data/lib/snip_snap.rb +63 -0
- data/test/fixtures/skitch.html +84 -0
- data/test/fixtures/yfrog.xml +35 -0
- data/test/test_helper.rb +15 -0
- data/test/unit/snip_snap/client_test.rb +107 -0
- data/test/unit/snip_snap/flickr_test.rb +49 -0
- data/test/unit/snip_snap/imgly_test.rb +31 -0
- data/test/unit/snip_snap/skitch_test.rb +28 -0
- data/test/unit/snip_snap/twitpic_test.rb +31 -0
- data/test/unit/snip_snap/yfrog_test.rb +31 -0
- data/test/unit/snip_snap_test.rb +77 -0
- metadata +96 -0
data/README.rdoc
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
= SnipSnap
|
2
|
+
|
3
|
+
== Description
|
4
|
+
|
5
|
+
SnipSnap is a Ruby library that will allow you to extract the URL of an image from
|
6
|
+
one of many popular image sharing services. Just give it the shortened URL and it can
|
7
|
+
give you the full URL to the embedded image. This library currently supports Img.ly,
|
8
|
+
Skitch, Twitpic, Flickr, and Yfrog - others are coming.
|
9
|
+
|
10
|
+
== Installation
|
11
|
+
|
12
|
+
sudo gem install snip-snap --source=http://gemcutter.org
|
13
|
+
|
14
|
+
== Usage
|
15
|
+
|
16
|
+
require 'rubygems
|
17
|
+
require 'snip_snap'
|
18
|
+
|
19
|
+
client = SnipSnap.from_url('http://yfrog.com/7hb9lj')
|
20
|
+
puts client.image_url
|
21
|
+
|
22
|
+
== License
|
23
|
+
|
24
|
+
Copyright (c) 2009 Patrick Reagan (reaganpr@gmail.com)
|
25
|
+
|
26
|
+
Permission is hereby granted, free of charge, to any person
|
27
|
+
obtaining a copy of this software and associated documentation
|
28
|
+
files (the "Software"), to deal in the Software without
|
29
|
+
restriction, including without limitation the rights to use,
|
30
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
31
|
+
copies of the Software, and to permit persons to whom the
|
32
|
+
Software is furnished to do so, subject to the following
|
33
|
+
conditions:
|
34
|
+
|
35
|
+
The above copyright notice and this permission notice shall be
|
36
|
+
included in all copies or substantial portions of the Software.
|
37
|
+
|
38
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
39
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
40
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
41
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
42
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
43
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
44
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
45
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake/gempackagetask'
|
3
|
+
require 'rake/testtask'
|
4
|
+
|
5
|
+
require 'lib/snip_snap/version'
|
6
|
+
|
7
|
+
spec = Gem::Specification.new do |s|
|
8
|
+
s.name = 'snip-snap'
|
9
|
+
s.version = SnipSnap::Version.to_s
|
10
|
+
s.has_rdoc = true
|
11
|
+
s.extra_rdoc_files = %w(README.rdoc)
|
12
|
+
s.rdoc_options = %w(--main README.rdoc)
|
13
|
+
s.summary = "A ruby library that allows you to extract images from popular image-sharing services"
|
14
|
+
s.author = 'Patrick Reagan'
|
15
|
+
s.email = 'reaganpr@gmail.com'
|
16
|
+
s.homepage = 'http://sneaq.net'
|
17
|
+
s.files = %w(README.rdoc Rakefile) + Dir.glob("{lib,test}/**/*")
|
18
|
+
# s.executables = ['snip-snap']
|
19
|
+
|
20
|
+
s.add_dependency('curb', '>= 0.5.1.0')
|
21
|
+
s.add_dependency('fleakr', '>= 0.5.1')
|
22
|
+
end
|
23
|
+
|
24
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
25
|
+
pkg.gem_spec = spec
|
26
|
+
end
|
27
|
+
|
28
|
+
Rake::TestTask.new do |t|
|
29
|
+
t.libs << 'test'
|
30
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
31
|
+
t.verbose = true
|
32
|
+
end
|
33
|
+
|
34
|
+
begin
|
35
|
+
require 'rcov/rcovtask'
|
36
|
+
|
37
|
+
Rcov::RcovTask.new(:coverage) do |t|
|
38
|
+
t.libs = ['test']
|
39
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
40
|
+
t.verbose = true
|
41
|
+
t.rcov_opts = ['--text-report', "-x #{Gem.path}", '-x /Library/Ruby', '-x /usr/lib/ruby']
|
42
|
+
end
|
43
|
+
|
44
|
+
task :default => :coverage
|
45
|
+
|
46
|
+
rescue LoadError
|
47
|
+
warn "\n**** Install rcov (sudo gem install relevance-rcov) to get coverage stats ****\n"
|
48
|
+
task :default => :test
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
desc 'Generate the gemspec to serve this Gem from Github'
|
53
|
+
task :github do
|
54
|
+
file = File.dirname(__FILE__) + "/#{spec.name}.gemspec"
|
55
|
+
File.open(file, 'w') {|f| f << spec.to_ruby }
|
56
|
+
puts "Created gemspec: #{file}"
|
57
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module SnipSnap
|
2
|
+
module Client # :nodoc:
|
3
|
+
|
4
|
+
module InstanceMethods
|
5
|
+
|
6
|
+
attr_reader :url
|
7
|
+
|
8
|
+
def initialize(url)
|
9
|
+
@url = url
|
10
|
+
end
|
11
|
+
|
12
|
+
def fetch
|
13
|
+
client = Curl::Easy.new(url) do |config|
|
14
|
+
config.follow_location = true
|
15
|
+
config.max_redirects = 5
|
16
|
+
config.head = self.class.head?
|
17
|
+
end
|
18
|
+
|
19
|
+
client.perform
|
20
|
+
|
21
|
+
client
|
22
|
+
end
|
23
|
+
|
24
|
+
def response
|
25
|
+
@response ||= fetch
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
module ClassMethods
|
31
|
+
|
32
|
+
def request_method(method_name)
|
33
|
+
@request_method = method_name
|
34
|
+
end
|
35
|
+
|
36
|
+
def head?
|
37
|
+
@request_method == :head
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.included(other)
|
43
|
+
other.send(:include, SnipSnap::Client::InstanceMethods)
|
44
|
+
other.send(:extend, SnipSnap::Client::ClassMethods)
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module SnipSnap
|
2
|
+
class Flickr
|
3
|
+
|
4
|
+
include Client
|
5
|
+
|
6
|
+
request_method :head
|
7
|
+
|
8
|
+
def identifier
|
9
|
+
url = response.last_effective_url
|
10
|
+
url.match(/([^\/]+)\/$/)[1]
|
11
|
+
end
|
12
|
+
|
13
|
+
def photo
|
14
|
+
Fleakr::Objects::Photo.find_by_id(identifier)
|
15
|
+
end
|
16
|
+
|
17
|
+
def image_url
|
18
|
+
photo.medium.url
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module SnipSnap
|
2
|
+
class Imgly
|
3
|
+
|
4
|
+
include Client
|
5
|
+
|
6
|
+
request_method :head
|
7
|
+
|
8
|
+
def url
|
9
|
+
identifier = @url.match(/([^\/]+)$/)[1]
|
10
|
+
"http://img.ly/show/large/#{identifier}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def image_url
|
14
|
+
response.last_effective_url
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module SnipSnap
|
2
|
+
class Twitpic
|
3
|
+
|
4
|
+
include Client
|
5
|
+
|
6
|
+
request_method :head
|
7
|
+
|
8
|
+
def url
|
9
|
+
identifier = @url.match(/([^\/]+)$/)[1]
|
10
|
+
"http://twitpic.com/show/large/#{identifier}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def image_url
|
14
|
+
response.last_effective_url
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module SnipSnap
|
2
|
+
class Yfrog
|
3
|
+
|
4
|
+
include Client
|
5
|
+
|
6
|
+
request_method :get
|
7
|
+
|
8
|
+
def url
|
9
|
+
identifier = @url.match(/([^\/]+)$/)[1]
|
10
|
+
"http://yfrog.com/api/xmlInfo?path=#{identifier}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def image_url
|
14
|
+
body = response.body_str
|
15
|
+
body.match(/<image_link>(.+)<\/image_link>/)[1]
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
data/lib/snip_snap.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__)
|
2
|
+
|
3
|
+
require 'curb'
|
4
|
+
require 'fleakr'
|
5
|
+
require 'uri'
|
6
|
+
|
7
|
+
require 'snip_snap/client'
|
8
|
+
|
9
|
+
require 'snip_snap/skitch'
|
10
|
+
require 'snip_snap/imgly'
|
11
|
+
require 'snip_snap/yfrog'
|
12
|
+
require 'snip_snap/twitpic'
|
13
|
+
require 'snip_snap/flickr'
|
14
|
+
|
15
|
+
# = SnipSnap
|
16
|
+
#
|
17
|
+
# This is a small Ruby library that allows you to extract images from the more popular
|
18
|
+
# image sharing services. Currently supported services are:
|
19
|
+
#
|
20
|
+
# * Img.ly
|
21
|
+
# * Skitch
|
22
|
+
# * Twitpic
|
23
|
+
# * Yfrog
|
24
|
+
# * Flickr
|
25
|
+
#
|
26
|
+
# To use, just point it at a URL:
|
27
|
+
#
|
28
|
+
# require 'rubygems'
|
29
|
+
# require 'snip_snap'
|
30
|
+
#
|
31
|
+
# client = SnipSnap.from_url('http://yfrog.com/7hb9lj')
|
32
|
+
# puts client.image_url
|
33
|
+
#
|
34
|
+
# That's it.
|
35
|
+
#
|
36
|
+
module SnipSnap
|
37
|
+
|
38
|
+
def self.host_map # :nodoc:
|
39
|
+
{
|
40
|
+
'skitch.com' => 'Skitch',
|
41
|
+
'img.ly' => 'Imgly',
|
42
|
+
'twitpic.com' => 'Twitpic',
|
43
|
+
'yfrog.com' => 'Yfrog',
|
44
|
+
'flic.kr' => 'Flickr'
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
# Use the correct class to handle image extraction for a given URL
|
49
|
+
def self.from_url(url)
|
50
|
+
const_get(class_name_for(url)).new(url)
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.class_name_for(url) # :nodoc:
|
54
|
+
uri = URI.parse(url)
|
55
|
+
host_map[uri.host]
|
56
|
+
end
|
57
|
+
|
58
|
+
# Set the Flickr API key for use by the underlying Flickr API library
|
59
|
+
def self.flickr_api_key=(key)
|
60
|
+
Fleakr.api_key = key
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
2
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
5
|
+
<meta name="KEYWORDS" content="Skitch Web" />
|
6
|
+
<meta name="DESCRIPTION" content="Skitch Web" />
|
7
|
+
<meta name="robots" content="index,follow" />
|
8
|
+
<link rel="icon" href="/favicon.ico" type="image/x-icon" />
|
9
|
+
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
|
10
|
+
<title>Skitch.com > reagent > Clinical Reader: Research articles, news and multimedia for doctors, all in one place</title>
|
11
|
+
<style type="text/css" media="screen,projection">
|
12
|
+
/*<![CDATA[*/
|
13
|
+
@import "/css/mySkitch.css?13363";
|
14
|
+
/*]]>*/
|
15
|
+
</style>
|
16
|
+
<script type="text/javascript" src="/js/src/myskitch.composite.js?13363"></script>
|
17
|
+
<!-- stylesheet /-->
|
18
|
+
<link rel="alternate" type="application/atom+xml" title="Atom 1.0" href="http://skitch.com/feeds/reagent/atom.xml" />
|
19
|
+
</head>
|
20
|
+
<body id="body" onload="plasq.mySkitch.browser.loader();" onresize="plasq.mySkitch.browser.resize();">
|
21
|
+
|
22
|
+
<div id="header">
|
23
|
+
<div id="logo"><a href="/"><img src="/images/logo.png" border="0" alt="" /></a></div>
|
24
|
+
<div id="menu">
|
25
|
+
<span class="shadow"><ul><li>sign-up</li> <span>|</span> <li>login</li></ul></span>
|
26
|
+
<span class="overlay"><ul><li><a href="/signup/">sign-up</a></li> <span class="i">|</span> <li><a href="/login/">login</a></li></ul></span>
|
27
|
+
</div>
|
28
|
+
</div>
|
29
|
+
|
30
|
+
<div id="content"><!-- content /--></div>
|
31
|
+
<div id="bottomad"><!-- adzone1 /--></div>
|
32
|
+
|
33
|
+
<div id="mtlogo"><div id="rightbar"></div><div id="rightbarbottom"><a href="http://www.mediatemple.net" target="_blank" title="Hosted by (mt)"><img src="/images/mt-hosted.png" alt="Hosted by (mt)" border="0" /></a><br /><br /><!-- adzone2 /--><br /><br /><br /><br /></div></div>
|
34
|
+
|
35
|
+
<div id="footer">
|
36
|
+
<div class="left padding5px">© 2007 - 2009 <a href="http://plasq.com" target="_blank">plasq</a> • <a href="http://skitch.com/ToS">Terms of Service</a> • <a href="http://skitch.com/Privacy">Privacy Policy</a> • <a href="http://skitch.com/DMCA">DMCA Notice</a> • <a href="http://help.skitch.com">Support</a> • <a href="http://plasq.com/skitch">Skitch Info</a> • <a href="http://blog.skitch.com">Skitch Blog</a></div>
|
37
|
+
<div class="right marginright"><a href="http://plasq.com" target="_blank" title="Visit plasq!"><img src="/images/footer-plasq.png" border="0" alt="Visit plasq!" /></a></div>
|
38
|
+
</div>
|
39
|
+
|
40
|
+
<script type="text/javascript">
|
41
|
+
/*<![CDATA[*/
|
42
|
+
plasq.mySkitch.sidebar = new plasq.mySkitch.classes.container( 'content' );
|
43
|
+
plasq.mySkitch.sidebar.element.className = 'myskitch-image-strip-right';
|
44
|
+
plasq.mySkitch.sidebar.addText( ' ' );
|
45
|
+
plasq.mySkitch.backLink = '';
|
46
|
+
|
47
|
+
plasq.mySkitch.selectCopyContainer = plasq.mySkitch.sidebar.addSelectCopyContainer();
|
48
|
+
plasq.mySkitch.selectCopyContainer.addSelectCopy( 'This page', 'http://skitch.com/reagent/baadt/clinical-reader-research-articles-news-and-multimedia-for-doctors-all-in-one-place', 'Link to the page you are looking at <b>right now</b> (Recommended)' );
|
49
|
+
plasq.mySkitch.selectCopyContainer.addSelectCopy( 'Image only', 'http://img.skitch.com/20090830-ejnqt1s9car55ju2sdnfirdsdn.jpg', '<b>Image only</b> link. Comments can\'t be made on these' );
|
50
|
+
plasq.mySkitch.selectCopyContainer.addSelectCopy( 'Embed', '<div class="thumbnail"><a href="http://skitch.com/reagent/baadt/clinical-reader-research-articles-news-and-multimedia-for-doctors-all-in-one-place"><img src="http://img.skitch.com/20090830-ejnqt1s9car55ju2sdnfirdsdn.preview.jpg" alt="Clinical Reader: Research articles, news and multimedia for doctors, all in one place" /></a><br /><span style="font-family: Lucida Grande, Trebuchet, sans-serif, Helvetica, Arial; font-size: 10px; color: #808080">Uploaded with <a href="http://plasq.com/">plasq</a>\'s <a href="http://skitch.com">Skitch</a>!</span></div>', 'HTML with zoomable <b>thumbnail</b>. (Great for eBay, MySpace blogs etc)' );
|
51
|
+
plasq.mySkitch.selectCopyContainer.addSelectCopy( 'Fullsize', '<img src="http://img.skitch.com/20090830-ejnqt1s9car55ju2sdnfirdsdn.jpg" alt="Clinical Reader: Research articles, news and multimedia for doctors, all in one place"/>', 'HTML to show the <b>fullsize</b> image' );
|
52
|
+
plasq.mySkitch.selectCopyContainer.addSelectCopy( 'Forum', '[url=http://skitch.com/reagent/baadt/clinical-reader-research-articles-news-and-multimedia-for-doctors-all-in-one-place][img]http://img.skitch.com/20090830-ejnqt1s9car55ju2sdnfirdsdn.preview.jpg[/img][/url][br][url=http://skitch.com/reagent/baadt/clinical-reader-research-articles-news-and-multimedia-for-doctors-all-in-one-place]Click for full size[/url] - [color=#A7A7A7]Uploaded with [url=http://plasq.com]plasq[/url]\'s [url=http://skitch.com]Skitch[/url][/color]', 'For use in web based <b>forums</b>' );
|
53
|
+
|
54
|
+
$('mtlogo').style.right = '32px';
|
55
|
+
$('mtlogo').style.top = '304px';
|
56
|
+
|
57
|
+
plasq.mySkitch.container = new plasq.mySkitch.classes.container( 'content' );
|
58
|
+
plasq.mySkitch.container.addSection( 'Clinical Reader: Research articles, news and multimedia for doctors, all in one place' );
|
59
|
+
plasq.mySkitch.container.addText( '<div style="display:block;" class="myskitch-header-notes">Pssst!.. This page is Secret - it can only be seen if you give people the URL</div>' );
|
60
|
+
plasq.mySkitch.container.addImage( 'http://img.skitch.com/20090830-ejnqt1s9car55ju2sdnfirdsdn.jpg', '', '', '', false, '472', '459' ).enableInfo().enableSlurp( 'skitch://img.skitch.com/20090830-ejnqt1s9car55ju2sdnfirdsdn.jpg?skitchtitle=Re%3A%20Clinical%20Reader%3A%20Research%20articles%2C%20news%20and%20multimedia%20for%20doctors%2C%20all%20in%20one%20place' ).enableDescription( ' ' );
|
61
|
+
plasq.mySkitch.container.addText( ' <br /> ' );
|
62
|
+
plasq.mySkitch.container.addSection( 'Comments' );
|
63
|
+
plasq.mySkitch.container.comments = plasq.mySkitch.container.addComments( '77fdb5-801093-1b64d7-a01c34-df9430-dd', 'This image has no comments yet. Be the first!', '0d171c5663e826463cc1f8eb32cdb0fa', true, '0' );
|
64
|
+
/*]]>*/
|
65
|
+
</script>
|
66
|
+
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
|
67
|
+
</script>
|
68
|
+
<script type="text/javascript">
|
69
|
+
_uacct = "UA-2305120-1";
|
70
|
+
urchinTracker();
|
71
|
+
</script>
|
72
|
+
|
73
|
+
<!-- Start Quantcast tag -->
|
74
|
+
<script type="text/javascript" src="https://secure.quantserve.com/quant.js"></script>
|
75
|
+
<script type="text/javascript">
|
76
|
+
_qacct="p-a3PI6F3Y912Tk";
|
77
|
+
quantserve();
|
78
|
+
</script>
|
79
|
+
<noscript>
|
80
|
+
<img src="https://secure.quantserve.com/pixel/p-a3PI6F3Y912Tk.gif" style="display: none" height="1" width="1" alt="Quantcast"/></noscript>
|
81
|
+
<!-- End Quantcast tag -->
|
82
|
+
|
83
|
+
</body>
|
84
|
+
</html>
|
@@ -0,0 +1,35 @@
|
|
1
|
+
<?xml version="1.0" encoding="iso-8859-1"?><imginfo xmlns="http://ns.imageshack.us/imginfo/7/" version="7" timestamp="1251516300">
|
2
|
+
<rating>
|
3
|
+
<ratings>0</ratings>
|
4
|
+
<avg>0.0</avg>
|
5
|
+
</rating>
|
6
|
+
<files server="377" bucket="9665">
|
7
|
+
<image size="29599" content-type="image/jpeg">b97.jpg</image>
|
8
|
+
<thumb size="4042" content-type="image/jpeg">b97.th.jpg</thumb>
|
9
|
+
</files>
|
10
|
+
<resolution>
|
11
|
+
<width>525</width>
|
12
|
+
<height>700</height>
|
13
|
+
</resolution>
|
14
|
+
<class>r</class>
|
15
|
+
<visibility>yes</visibility>
|
16
|
+
<uploader>
|
17
|
+
<ip>38.99.76.246</ip>
|
18
|
+
<cookie>1d5927aee7676b56f5fb5e1c6dc386bf</cookie>
|
19
|
+
<username>twitter~urbanflex</username>
|
20
|
+
</uploader>
|
21
|
+
<links>
|
22
|
+
<image_link>http://img377.imageshack.us/img377/9665/b97.jpg</image_link>
|
23
|
+
<image_html><a href="http://img377.imageshack.us/my.php?image=b97.jpg" target="_blank"><img src="http://img377.imageshack.us/img377/9665/b97.jpg" alt="Free Image Hosting at www.ImageShack.us" border="0"/></a></image_html>
|
24
|
+
<image_bb>[URL=http://img377.imageshack.us/my.php?image=b97.jpg][IMG]http://img377.imageshack.us/img377/9665/b97.jpg[/IMG][/URL]</image_bb>
|
25
|
+
<image_bb2>[url=http://img377.imageshack.us/my.php?image=b97.jpg][img=http://img377.imageshack.us/img377/9665/b97.jpg][/url]</image_bb2>
|
26
|
+
<thumb_link>http://img377.imageshack.us/img377/9665/b97.th.jpg</thumb_link>
|
27
|
+
<thumb_html><a href="http://img377.imageshack.us/my.php?image=b97.jpg" target="_blank"><img src="http://img377.imageshack.us/img377/9665/b97.th.jpg" alt="Free Image Hosting at www.ImageShack.us" border="0"/></a></thumb_html>
|
28
|
+
<thumb_bb>[URL=http://img377.imageshack.us/my.php?image=b97.jpg][IMG]http://img377.imageshack.us/img377/9665/b97.th.jpg[/IMG][/URL]</thumb_bb>
|
29
|
+
<thumb_bb2>[url=http://img377.imageshack.us/my.php?image=b97.jpg][img=http://img377.imageshack.us/img377/9665/b97.th.jpg][/url]</thumb_bb2>
|
30
|
+
<yfrog_link>http://yfrog.com/ahb97j</yfrog_link>
|
31
|
+
<yfrog_thumb>http://yfrog.com/ahb97j.th.jpg</yfrog_thumb>
|
32
|
+
<ad_link>http://img377.imageshack.us/my.php?image=b97.jpg</ad_link>
|
33
|
+
<done_page>http://img377.imageshack.us/content.php?page=done&l=img377/9665/b97.jpg</done_page>
|
34
|
+
</links>
|
35
|
+
</imginfo>
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# http://sneaq.net/textmate-wtf
|
2
|
+
$:.reject! { |e| e.include? 'TextMate' }
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'throat_punch'
|
6
|
+
|
7
|
+
require File.dirname(__FILE__) + '/../lib/snip_snap'
|
8
|
+
|
9
|
+
class Test::Unit::TestCase
|
10
|
+
|
11
|
+
def read_fixture(filename)
|
12
|
+
File.read(File.dirname(__FILE__) + '/fixtures/' + filename)
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../test_helper'
|
2
|
+
|
3
|
+
class ClientImplementation
|
4
|
+
include SnipSnap::Client
|
5
|
+
end
|
6
|
+
|
7
|
+
class ClientGetImplementation
|
8
|
+
include SnipSnap::Client
|
9
|
+
request_method :get
|
10
|
+
end
|
11
|
+
|
12
|
+
class ClientHeadImplementation
|
13
|
+
include SnipSnap::Client
|
14
|
+
request_method :head
|
15
|
+
end
|
16
|
+
|
17
|
+
module SnipSnap
|
18
|
+
class ClientTest < Test::Unit::TestCase
|
19
|
+
|
20
|
+
context "An instance of the ClientImplementation class" do
|
21
|
+
|
22
|
+
should "be able to fetch a response" do
|
23
|
+
response = stub()
|
24
|
+
|
25
|
+
c = ClientImplementation.new('http://example.com')
|
26
|
+
c.expects(:fetch).once.with().returns(response)
|
27
|
+
|
28
|
+
c.response.should == response
|
29
|
+
end
|
30
|
+
|
31
|
+
should "cache the response object" do
|
32
|
+
response = stub()
|
33
|
+
|
34
|
+
c = ClientImplementation.new('http://example.com')
|
35
|
+
c.expects(:fetch).once.with().returns(response)
|
36
|
+
|
37
|
+
2.times { c.response }
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
context "The ClientGetImplementation class" do
|
43
|
+
|
44
|
+
should "know that it doesn't make a head request" do
|
45
|
+
ClientGetImplementation.head?.should be(false)
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
context "An instance of the ClientGetImplementation class" do
|
51
|
+
|
52
|
+
should "fetch a response using a GET request" do
|
53
|
+
url = 'http://example.com'
|
54
|
+
|
55
|
+
client = mock() do |c|
|
56
|
+
c.expects(:perform).with()
|
57
|
+
end
|
58
|
+
|
59
|
+
config = mock() do |c|
|
60
|
+
c.expects(:follow_location=).with(true)
|
61
|
+
c.expects(:max_redirects=).with(5)
|
62
|
+
c.expects(:head=).with(false)
|
63
|
+
end
|
64
|
+
|
65
|
+
Curl::Easy.expects(:new).with(url).yields(config).returns(client)
|
66
|
+
|
67
|
+
c = ClientGetImplementation.new(url)
|
68
|
+
c.fetch.should == client
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
context "The ClientHeadImplementation class" do
|
75
|
+
|
76
|
+
should "know that it doesn't makes a head request" do
|
77
|
+
ClientHeadImplementation.head?.should be(true)
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
context "An instance of the ClientHeadImplementation class" do
|
83
|
+
|
84
|
+
should "fetch a response using a HEAD request" do
|
85
|
+
url = 'http://example.com'
|
86
|
+
|
87
|
+
client = mock() do |c|
|
88
|
+
c.expects(:perform).with()
|
89
|
+
end
|
90
|
+
|
91
|
+
config = mock() do |c|
|
92
|
+
c.expects(:follow_location=).with(true)
|
93
|
+
c.expects(:max_redirects=).with(5)
|
94
|
+
c.expects(:head=).with(true)
|
95
|
+
end
|
96
|
+
|
97
|
+
Curl::Easy.expects(:new).with(url).yields(config).returns(client)
|
98
|
+
|
99
|
+
c = ClientHeadImplementation.new(url)
|
100
|
+
c.fetch.should == client
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../test_helper'
|
2
|
+
|
3
|
+
module SnipSnap
|
4
|
+
class FlickrTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context "An instance of the Flickr class" do
|
7
|
+
setup do
|
8
|
+
@url = 'http://flic.kr/p/64cBqN'
|
9
|
+
@expanded_url = 'http://www.flickr.com/photos/northernraven/3317998738/'
|
10
|
+
end
|
11
|
+
|
12
|
+
should "know the identifier for the photo" do
|
13
|
+
response = stub()
|
14
|
+
response.stubs(:last_effective_url).with().returns(@expanded_url)
|
15
|
+
|
16
|
+
f = SnipSnap::Flickr.new(@url)
|
17
|
+
f.stubs(:response).with().returns(response)
|
18
|
+
|
19
|
+
f.identifier.should == '3317998738'
|
20
|
+
end
|
21
|
+
|
22
|
+
should "be able to find the photo for the identifier" do
|
23
|
+
identifier = '3317998738'
|
24
|
+
photo = stub()
|
25
|
+
|
26
|
+
Fleakr::Objects::Photo.expects(:find_by_id).with(identifier).returns(photo)
|
27
|
+
|
28
|
+
f = SnipSnap::Flickr.new(@url)
|
29
|
+
f.stubs(:identifier).with().returns(identifier)
|
30
|
+
|
31
|
+
f.photo.should == photo
|
32
|
+
end
|
33
|
+
|
34
|
+
should "know the image url" do
|
35
|
+
url = 'http://farm.flickr.com/photo.jpg'
|
36
|
+
|
37
|
+
photo = stub()
|
38
|
+
photo.stubs(:medium).with().returns(stub(:url => url))
|
39
|
+
|
40
|
+
f = SnipSnap::Flickr.new(@url)
|
41
|
+
f.stubs(:photo).with().returns(photo)
|
42
|
+
|
43
|
+
f.image_url.should == url
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../test_helper'
|
2
|
+
|
3
|
+
module SnipSnap
|
4
|
+
class ImglyTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context "An instance of the Imgly class" do
|
7
|
+
setup do
|
8
|
+
@url = 'http://img.ly/3aa'
|
9
|
+
@expanded_url = 'http://img.ly/show/large/3aa'
|
10
|
+
end
|
11
|
+
|
12
|
+
should "have a url expanded from the source" do
|
13
|
+
i = SnipSnap::Imgly.new(@url)
|
14
|
+
i.url.should == @expanded_url
|
15
|
+
end
|
16
|
+
|
17
|
+
should "be able to return an image url for a given url" do
|
18
|
+
response = stub()
|
19
|
+
response.stubs(:last_effective_url).with().returns(@expanded_url)
|
20
|
+
|
21
|
+
i = SnipSnap::Imgly.new(@url)
|
22
|
+
i.stubs(:response).with().returns(response)
|
23
|
+
|
24
|
+
i.image_url.should == @expanded_url
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../test_helper'
|
2
|
+
|
3
|
+
module SnipSnap
|
4
|
+
class SkitchTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context "An instance of the Skitch class" do
|
7
|
+
setup { @url = 'http://skitch.com/example' }
|
8
|
+
|
9
|
+
should "have a URL" do
|
10
|
+
s = SnipSnap::Skitch.new(@url)
|
11
|
+
s.url.should == @url
|
12
|
+
end
|
13
|
+
|
14
|
+
should "be able to return an image url for a given url" do
|
15
|
+
s = SnipSnap::Skitch.new(@url)
|
16
|
+
|
17
|
+
response = stub()
|
18
|
+
response.stubs(:body_str).with().returns(read_fixture('skitch.html'))
|
19
|
+
|
20
|
+
s.stubs(:response).with().returns(response)
|
21
|
+
|
22
|
+
s.image_url.should == 'http://img.skitch.com/20090830-ejnqt1s9car55ju2sdnfirdsdn.jpg'
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../test_helper'
|
2
|
+
|
3
|
+
module SnipSnap
|
4
|
+
class TwitpicTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context "An instance of the Twitpic class" do
|
7
|
+
setup do
|
8
|
+
@url = 'http://twitpic.com/203o0'
|
9
|
+
@expanded_url = 'http://twitpic.com/show/large/203o0'
|
10
|
+
end
|
11
|
+
|
12
|
+
should "have a url derived from the source URL" do
|
13
|
+
t = SnipSnap::Twitpic.new(@url)
|
14
|
+
t.url.should == @expanded_url
|
15
|
+
end
|
16
|
+
|
17
|
+
should "be able to return an image url for a given url" do
|
18
|
+
response = stub()
|
19
|
+
response.stubs(:last_effective_url).with().returns(@expanded_url)
|
20
|
+
|
21
|
+
t = SnipSnap::Twitpic.new(@url)
|
22
|
+
t.stubs(:response).with().returns(response)
|
23
|
+
|
24
|
+
t.image_url.should == @expanded_url
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../test_helper'
|
2
|
+
|
3
|
+
module SnipSnap
|
4
|
+
class YfrogTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context "An instance of the Yfrog class" do
|
7
|
+
setup do
|
8
|
+
@url = 'http://yfrog.com/ahb97j'
|
9
|
+
@expanded_url = 'http://yfrog.com/api/xmlInfo?path=ahb97j'
|
10
|
+
end
|
11
|
+
|
12
|
+
should "have a url derived from the source URL" do
|
13
|
+
y = SnipSnap::Yfrog.new(@url)
|
14
|
+
y.url.should == @expanded_url
|
15
|
+
end
|
16
|
+
|
17
|
+
should "be able to return an image url for a given url" do
|
18
|
+
y = SnipSnap::Yfrog.new(@url)
|
19
|
+
|
20
|
+
response = stub()
|
21
|
+
response.stubs(:body_str).with().returns(read_fixture('yfrog.xml'))
|
22
|
+
|
23
|
+
y.stubs(:response).with().returns(response)
|
24
|
+
|
25
|
+
y.image_url.should == 'http://img377.imageshack.us/img377/9665/b97.jpg'
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class SnipSnapTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context "The SnipSnap module" do
|
6
|
+
|
7
|
+
should "know the correct class name for a Skitch URL" do
|
8
|
+
url = 'http://skitch.com/reagent/bh4ei/bleeergh'
|
9
|
+
SnipSnap.class_name_for(url).should == 'Skitch'
|
10
|
+
end
|
11
|
+
|
12
|
+
should "know the correct class name for an Imgly URL" do
|
13
|
+
url = 'http://img.ly/3ey'
|
14
|
+
SnipSnap.class_name_for(url).should == 'Imgly'
|
15
|
+
end
|
16
|
+
|
17
|
+
should "know the correct class name for a Twitpic URL" do
|
18
|
+
url = 'http://twitpic.com/203o0'
|
19
|
+
SnipSnap.class_name_for(url).should == 'Twitpic'
|
20
|
+
end
|
21
|
+
|
22
|
+
should "know the correct class name for a Yfrog URL" do
|
23
|
+
url = 'http://yfrog.com/ahb97j'
|
24
|
+
SnipSnap.class_name_for(url).should == 'Yfrog'
|
25
|
+
end
|
26
|
+
|
27
|
+
should "know the correct class name for a Flickr URL" do
|
28
|
+
url = 'http://flic.kr/p/64cBqN'
|
29
|
+
SnipSnap.class_name_for(url).should == 'Flickr'
|
30
|
+
end
|
31
|
+
|
32
|
+
should "be able to create an instance of the Skitch class with the supplied URL" do
|
33
|
+
url = 'http://skitch.com/reagent/bh4ei/bleeergh'
|
34
|
+
SnipSnap::Skitch.expects(:new).with(url).returns('skitch')
|
35
|
+
|
36
|
+
SnipSnap.from_url(url).should == 'skitch'
|
37
|
+
end
|
38
|
+
|
39
|
+
should "be able to create an instance of the Imgly class with the supplied URL" do
|
40
|
+
url = 'http://img.ly/3ey'
|
41
|
+
SnipSnap::Imgly.expects(:new).with(url).returns('imgly')
|
42
|
+
|
43
|
+
SnipSnap.from_url(url).should == 'imgly'
|
44
|
+
end
|
45
|
+
|
46
|
+
should "be able to create an instance of the Twitpic class with the supplied URL" do
|
47
|
+
url = 'http://twitpic.com/203o0'
|
48
|
+
SnipSnap::Twitpic.expects(:new).with(url).returns('twitpic')
|
49
|
+
|
50
|
+
SnipSnap.from_url(url).should == 'twitpic'
|
51
|
+
end
|
52
|
+
|
53
|
+
should "be able to create an instance of the Yfrog class with the supplied URL" do
|
54
|
+
url = 'http://yfrog.com/ahb97j'
|
55
|
+
SnipSnap::Yfrog.expects(:new).with(url).returns('yfrog')
|
56
|
+
|
57
|
+
SnipSnap.from_url(url).should == 'yfrog'
|
58
|
+
end
|
59
|
+
|
60
|
+
should "be able to create an instance of the Flickr class with the supplied URL" do
|
61
|
+
url = 'http://flic.kr/p/64cBqN'
|
62
|
+
SnipSnap::Flickr.expects(:new).with(url).returns('flickr')
|
63
|
+
|
64
|
+
SnipSnap.from_url(url).should == 'flickr'
|
65
|
+
end
|
66
|
+
|
67
|
+
should "be able to set the Flickr API key" do
|
68
|
+
key = 'abc123'
|
69
|
+
|
70
|
+
Fleakr.expects(:api_key=).with(key)
|
71
|
+
|
72
|
+
SnipSnap.flickr_api_key = key
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: reagent-snip-snap
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Patrick Reagan
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-09-06 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: curb
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.5.1.0
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: fleakr
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.5.1
|
34
|
+
version:
|
35
|
+
description:
|
36
|
+
email: reaganpr@gmail.com
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- README.rdoc
|
43
|
+
files:
|
44
|
+
- README.rdoc
|
45
|
+
- Rakefile
|
46
|
+
- lib/snip_snap
|
47
|
+
- lib/snip_snap/client.rb
|
48
|
+
- lib/snip_snap/flickr.rb
|
49
|
+
- lib/snip_snap/imgly.rb
|
50
|
+
- lib/snip_snap/skitch.rb
|
51
|
+
- lib/snip_snap/twitpic.rb
|
52
|
+
- lib/snip_snap/version.rb
|
53
|
+
- lib/snip_snap/yfrog.rb
|
54
|
+
- lib/snip_snap.rb
|
55
|
+
- test/fixtures
|
56
|
+
- test/fixtures/skitch.html
|
57
|
+
- test/fixtures/yfrog.xml
|
58
|
+
- test/test_helper.rb
|
59
|
+
- test/unit
|
60
|
+
- test/unit/snip_snap
|
61
|
+
- test/unit/snip_snap/client_test.rb
|
62
|
+
- test/unit/snip_snap/flickr_test.rb
|
63
|
+
- test/unit/snip_snap/imgly_test.rb
|
64
|
+
- test/unit/snip_snap/skitch_test.rb
|
65
|
+
- test/unit/snip_snap/twitpic_test.rb
|
66
|
+
- test/unit/snip_snap/yfrog_test.rb
|
67
|
+
- test/unit/snip_snap_test.rb
|
68
|
+
has_rdoc: false
|
69
|
+
homepage: http://sneaq.net
|
70
|
+
post_install_message:
|
71
|
+
rdoc_options:
|
72
|
+
- --main
|
73
|
+
- README.rdoc
|
74
|
+
require_paths:
|
75
|
+
- lib
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: "0"
|
81
|
+
version:
|
82
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: "0"
|
87
|
+
version:
|
88
|
+
requirements: []
|
89
|
+
|
90
|
+
rubyforge_project:
|
91
|
+
rubygems_version: 1.2.0
|
92
|
+
signing_key:
|
93
|
+
specification_version: 3
|
94
|
+
summary: A ruby library that allows you to extract images from popular image-sharing services
|
95
|
+
test_files: []
|
96
|
+
|