reagent-snip-snap 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|