muri 1.1.2 → 1.1.4

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/CHANGELOG ADDED
@@ -0,0 +1,13 @@
1
+ Muri Changelog
2
+ ===================================
3
+
4
+ Version 1.1.3
5
+ * Changed "FLICKR_PHOTO" to "FLICKR_MEDIA" (since it can parse videos)
6
+ - "flickr_photo?" is replaced by "flickr_media?" now
7
+ * Facebook parser overhaul thanks to their new 'Graph API'
8
+ - media_api_id is no longer the true facebook database API id for photos, though it is now for videos
9
+ - Facebook parser accepts video URL's, but albums temporarily disabled
10
+ * Removed deprecated "is_" methods
11
+ * Changed service names all lowercase letters (eg. "Vimeo" to "vimeo").
12
+ - Should not have any major impact on usage, mostly an internal change.
13
+ * URL parse now only escapes spaces, not all characters (allows # to create URI fragment)
data/README.textile CHANGED
@@ -62,7 +62,7 @@ Assuming the URI was successfully parsed (thus @a.valid? == true@), all media ty
62
62
  * Services with a @media_api_id@ also have a @media_api_type@, which indicates what sort of API call should be made (be it 'photo', 'video', 'media', 'set', 'album', or 'playlist', depending on URI type)
63
63
 
64
64
 
65
- *NOTE: Facebook photos return a @media_api_id@ which can be used to search for photo information in a Facebook photos.get API call as the pid. This pid is NOT the same as the pid found in the query string (the @media_id@)*
65
+ *NOTE: Facebook photos return a @media_api_id@ hash, keyed for photos by @uid@ and @pid@ (user and photo id, not the true Graph API id), and for videos by @v@ (the video id)*
66
66
 
67
67
  *ALSO NOTE: Picasa @media_api_id@ is a partial string for using the photo API call, so for example @'bananastalktome/album/TestForAPI/photoid/5450524726782297346'@, thus the API call would be @"http://picasaweb.google.com/data/feed/api/user/#{media_api_id}"@*
68
68
 
data/VERSION.yml CHANGED
@@ -1,4 +1,5 @@
1
1
  ---
2
+ :patch: 4
3
+ :build:
2
4
  :major: 1
3
5
  :minor: 1
4
- :patch: 2
data/lib/muri/base.rb CHANGED
@@ -9,25 +9,19 @@ class Muri
9
9
  # match accepted formats
10
10
  class UnsupportedURI < ArgumentError; end
11
11
 
12
- AVAILABLE_PARSERS = %w[Youtube Flickr Vimeo Imageshack Photobucket Facebook Twitpic Picasa].freeze
12
+ AVAILABLE_PARSERS = %w[youtube flickr vimeo imageshack photobucket facebook twitpic picasa].freeze
13
13
 
14
14
  PARSERS = { }
15
15
 
16
16
  # Defines #{service}? and #{service_type}? methods, and sets service name constnat
17
17
  AVAILABLE_PARSERS.each do |parser|
18
- eval "include Filter::#{parser}"
19
- is_service = "is_#{parser.downcase}?"
20
- service = "#{parser.downcase}?"
18
+ eval "include Filter::#{parser.capitalize}"
19
+ service = "#{parser}?"
21
20
  define_method(service) { self.media_service == parser }
22
- define_method(is_service) { puts "This method will be deprecated, use #{service} instead"; self.instance_eval(service) }
23
21
  self.constants.reject { |c| c !~ /^#{parser.upcase}/ }.each do |exp|
24
22
  define_method("#{exp.downcase}?") do
25
23
  self.media_api_type == eval(exp) && self.instance_eval(service)
26
24
  end
27
- define_method("is_#{exp.downcase}?") do
28
- puts "This method will be deprecated, use #{exp.downcase}? instead"
29
- self.instance_eval("#{exp.downcase}?")
30
- end
31
25
  end
32
26
  const_set "#{parser.upcase}_SERVICE_NAME", "#{parser}"
33
27
  end
@@ -69,7 +63,7 @@ class Muri
69
63
 
70
64
  def parse(raw_url)
71
65
  begin
72
- raw_url = URI.encode(URI.decode(raw_url)) unless raw_url.nil?
66
+ raw_url = URI.encode(URI.decode(raw_url), " ") unless raw_url.nil?
73
67
  self.uri = URI.parse(raw_url)
74
68
  if self.uri.scheme.nil?
75
69
  raw_url = "http://#{raw_url}"
@@ -4,10 +4,12 @@ class Muri
4
4
 
5
5
  private
6
6
  FACEBOOK_PHOTO = "photo"
7
- #FACEBOOK_VIDEO = "video"
8
- FACEBOOK_ALBUM = "album"
9
- REGEX_FACEBOOK_PHOTO = /^\/photo\.php$/i
10
- REGEX_FACEBOOK_ALBUM = /^\/album\.php$/i
7
+ FACEBOOK_VIDEO = "video"
8
+
9
+ #FACEBOOK_ALBUM = "album"
10
+ REGEX_FACEBOOK_PHOTO = /\/photo\.php/i
11
+ REGEX_FACEBOOK_VIDEO = /\/video\/video\.php/i
12
+ #REGEX_FACEBOOK_ALBUM = /^\/album\.php$/i
11
13
 
12
14
  def self.included(base)
13
15
  base.class_eval do
@@ -20,55 +22,44 @@ class Muri
20
22
  end
21
23
 
22
24
  def facebook_parse
23
- self.media_service = FACEBOOK_SERVICE_NAME #'Facebook'
24
- params = Muri.param_parse(self.uri.query)
25
+ self.media_service = FACEBOOK_SERVICE_NAME #'facebook'
25
26
 
26
- url_common = "http://www.facebook.com"
27
+ url_string = self.uri.fragment.nil? ? (self.uri.path.to_s + "?" + self.uri.query.to_s) : self.uri.fragment
27
28
 
28
- # if self.uri.path =~ /^\/v\/([0-9]+)/
29
- # @info[:media_id] = $1
30
- # @info[:media_url] = "#{url_common}/v/#{@info[:media_id]}"
31
- #
32
- # # Currently no API for video, but media_id is best guess value for such content
33
- # @info[:media_api_id] = @info[:media_id]
34
- # @info[:media_api_type] = FACEBOOK_VIDEO
35
- if ((self.uri.path =~ REGEX_FACEBOOK_PHOTO) &&
36
- params["pid"] =~ /^([0-9]+)$/ &&
37
- params["id"] =~ /^([0-9]+)$/ &&
38
- params["l"] =~ /^([0-9a-z]+)$/i)
29
+ url_common = "http://www.facebook.com"
39
30
 
31
+ if (url_string =~ REGEX_FACEBOOK_VIDEO && (v = url_string.gsub(/\A.*?v=(\d+)(&.*|\Z)/i, '\1')))
32
+
33
+ self.media_api_type = FACEBOOK_VIDEO
34
+ self.media_id = v
35
+ self.media_api_id = {:v => v}
36
+ self.media_website = "#{url_common}/video/video.php?v=#{self.media_id}"
37
+ elsif (url_string =~ REGEX_FACEBOOK_PHOTO &&
38
+ (pid = url_string.gsub(/\A.*?pid=(\d+)(&.*|\Z)/i, '\1')) &&
39
+ (uid = url_string.gsub(/\A.*?[^p]id=(\d+)(&.*|\Z)/i, '\1')))
40
+
40
41
  self.media_api_type = FACEBOOK_PHOTO
41
- self.media_id = params["pid"]
42
- media_creator = params["id"]
43
- share_key = params["l"]
44
-
45
- self.media_website = "#{url_common}/photo.php?pid=#{self.media_id}&l=#{share_key}&id=#{media_creator}"
46
- elsif ((self.uri.path =~ REGEX_FACEBOOK_ALBUM) &&
47
- params["aid"] =~ /^([0-9]+)$/ &&
48
- params["id"] =~ /^([0-9]+)$/ &&
49
- params["l"] =~ /^([0-9a-z]+)$/i)
42
+ self.media_id = pid
43
+ media_creator = uid
44
+ self.media_api_id = {:pid => pid, :uid => media_creator}
50
45
 
51
- self.media_api_type = FACEBOOK_ALBUM
52
- self.media_id = params["aid"]
53
- media_creator = params["id"]
54
- share_key = params["l"]
55
-
56
- self.media_website = "#{url_common}/album.php?aid=#{self.media_id}&l=#{share_key}&id=#{media_creator}"
46
+ self.media_website = "#{url_common}/photo.php?pid=#{self.media_id}&id=#{media_creator}"
47
+ # elsif ((self.uri.path =~ REGEX_FACEBOOK_ALBUM) &&
48
+ # params["aid"] =~ /^([0-9]+)$/ &&
49
+ # params["id"] =~ /^([0-9]+)$/ &&
50
+ # params["l"] =~ /^([0-9a-z]+)$/i)
51
+ #
52
+ # self.media_api_type = FACEBOOK_ALBUM
53
+ # self.media_id = params["aid"]
54
+ # media_creator = params["id"]
55
+ # share_key = params["l"]
56
+ #
57
+ # self.media_website = "#{url_common}/album.php?aid=#{self.media_id}&l=#{share_key}&id=#{media_creator}"
57
58
  else
58
59
  raise UnsupportedURI
59
60
  end
60
-
61
- # The media_api_id is the PID which can be searched for in the facebook photos/albums table
62
- self.media_api_id = (media_creator.to_i << 32) + self.media_id.to_i
61
+
63
62
  end
64
63
  end
65
64
  end
66
- end
67
- # http://www.facebook.com/album.php?aid=2131184&id=15201063&l=8917e51479
68
- # http://www.facebook.com/photo.php?pid=34929102&l=a1abf8cd37&id=15201063 (preview)
69
- # database_pid = (USER_ID << 32) + PID
70
- # pid = photo id
71
- # id = user id
72
- # l = photo share key
73
- # http://www.facebook.com/v/614695029223 (full) - deprecated
74
- # http://www.facebook.com/album.php?aid=2149275&id=15201063&l=99900807c3
65
+ end
@@ -3,11 +3,11 @@ class Muri
3
3
  module Flickr
4
4
 
5
5
  private
6
- FLICKR_PHOTO = "photo"
6
+ FLICKR_MEDIA = "media"
7
7
  FLICKR_SET = "set"
8
8
 
9
- REGEX_FLICKR_PHOTO_OR_SET = /^\/photos\/([a-z0-9\-\_\@]+?)\/(sets\/)?([0-9]+)/i
10
- REGEX_FLICKR_STATIC_PHOTO = /^farm([1-3])\.static.flickr.com\/([0-9]+?)\/([0-9]+?)\_([a-z0-9]+?)((?:\_[a-z]){1,2}){0,1}\.([a-z]+)/i
9
+ REGEX_FLICKR_MEDIA_OR_SET = /^\/photos\/([a-z0-9\-\_\@]+?)\/(sets\/)?([0-9]+)/i
10
+ REGEX_FLICKR_STATIC_MEDIA = /^farm([1-3])\.static.flickr.com\/([0-9]+?)\/([0-9]+?)\_([a-z0-9]+?)((?:\_[a-z]){1,2}){0,1}\.([a-z]+)/i
11
11
  REGEX_FLICKR_SHORTURL = /^flic\.kr\/p\/([a-z0-9]+)/i
12
12
 
13
13
  def self.included(base)
@@ -23,28 +23,28 @@ class Muri
23
23
  def flickr_parse
24
24
  self.media_service = FLICKR_SERVICE_NAME #'Flickr'
25
25
 
26
- if self.uri.path =~ REGEX_FLICKR_PHOTO_OR_SET
26
+ if self.uri.path =~ REGEX_FLICKR_MEDIA_OR_SET
27
27
  media_creator = $1
28
28
  self.media_id = $3
29
- self.media_api_type = $2.nil? ? FLICKR_PHOTO : FLICKR_SET
30
- elsif (self.uri.host + self.uri.path) =~ REGEX_FLICKR_STATIC_PHOTO
29
+ self.media_api_type = $2.nil? ? FLICKR_MEDIA : FLICKR_SET
30
+ elsif (self.uri.host + self.uri.path) =~ REGEX_FLICKR_STATIC_MEDIA
31
31
  farm = $1
32
32
  server_id = $2
33
33
  self.media_id = $3
34
- self.media_api_type = FLICKR_PHOTO
34
+ self.media_api_type = FLICKR_MEDIA
35
35
  media_secret = $4
36
36
  url_prefix = "http://farm#{farm}.static.flickr.com/#{server_id}/#{self.media_id}_#{media_secret}"
37
37
  self.media_url = "#{url_prefix}.jpg"
38
38
  self.media_thumbnail = "#{url_prefix}_t.jpg"
39
39
  elsif (self.uri.host + self.uri.path) =~ REGEX_FLICKR_SHORTURL
40
40
  self.media_id = Filter::Flickr.decode58($1)
41
- self.media_api_type = FLICKR_PHOTO
41
+ self.media_api_type = FLICKR_MEDIA
42
42
  else
43
43
  raise UnsupportedURI
44
44
  end
45
45
 
46
46
  self.media_api_id = self.media_id
47
- if self.flickr_photo?
47
+ if self.flickr_media?
48
48
  self.media_website = "http://flic.kr/p/" + Filter::Flickr.encode58(self.media_id.to_i)
49
49
  elsif self.flickr_set?
50
50
  self.media_website = "http://www.flickr.com/photos/#{media_creator}/sets/#{self.media_id}" # appending /show takes direct to image through redirect
@@ -19,14 +19,12 @@ class Muri
19
19
  self.media_service = PICASA_SERVICE_NAME
20
20
  url_common = "http://picasaweb.google.com"
21
21
 
22
- #I hate to have to do this, but it's the best way I can think of to get the hash symbol
23
- #reencoded_url = URI.parse(URI.encode self.uri.to_s)
24
-
25
- if self.uri.path =~ /^\/(.[^\/]+)\/(.[^\/]+)/i
22
+ if (self.uri.path =~ /^\/(.[^\/]+)\/(.[^\/]+)/i) && !self.uri.fragment.nil?
26
23
  username = $1
27
- album_photoid = $2.split("%23")
24
+ album = $2 #album_photoid[0..-2].join("#") #in case other hash symbols exist
25
+
26
+ album_photoid = self.uri.fragment.split("#")
28
27
  photoid = album_photoid.last
29
- album = album_photoid[0..-2].join("#") #in case other hash symbols exist
30
28
  self.media_id = photoid
31
29
  self.media_website = "#{url_common}/#{username}/#{album}##{photoid}"
32
30
  self.media_api_type = PICASA_PHOTO
@@ -41,4 +39,5 @@ class Muri
41
39
  end
42
40
  # http://picasaweb.google.com/bananastalktome/TestForAPI#5450524726782297346
43
41
  # API Call: http://picasaweb.google.com/data/feed/api/user/bananastalktome/album/TestForAPI/photoid/5450524726782297346
44
- # #=%23
42
+ # #=%23
43
+ # http://picasaweb.google.com/data/entry/api/user/bananastalktome/photoid/5450524726782297346
data/muri.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{muri}
8
- s.version = "1.1.2"
8
+ s.version = "1.1.4"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["William Schneider"]
12
- s.date = %q{2010-04-06}
12
+ s.date = %q{2010-04-29}
13
13
  s.description = %q{Automatically get media information from the URL.}
14
14
  s.email = %q{bananastalktome@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -17,6 +17,7 @@ Gem::Specification.new do |s|
17
17
  ]
18
18
  s.files = [
19
19
  ".gitignore",
20
+ "CHANGELOG",
20
21
  "README.textile",
21
22
  "Rakefile",
22
23
  "VERSION.yml",
@@ -17,6 +17,24 @@ shared_examples_for "Facebook parse" do
17
17
  @a.valid?.should == true
18
18
  end
19
19
  end
20
+ shared_examples_for "Facebook parse video" do
21
+ it_should_behave_like "Facebook parse"
22
+ it "should have media api type = FACEBOOK_VIDEO" do
23
+ @a.media_api_type.should == Muri::FACEBOOK_VIDEO
24
+ end
25
+
26
+ it "should be facebook video" do
27
+ @a.facebook_video?.should == true
28
+ end
29
+
30
+ it "should not be facebook photo" do
31
+ @a.facebook_photo?.should == false
32
+ end
33
+
34
+ it "should not be flickr media" do
35
+ @a.flickr_media?.should == false
36
+ end
37
+ end
20
38
 
21
39
  shared_examples_for "Facebook parse photo" do
22
40
  it_should_behave_like "Facebook parse"
@@ -28,22 +46,39 @@ shared_examples_for "Facebook parse photo" do
28
46
  @a.facebook_photo?.should == true
29
47
  end
30
48
 
31
- it "should not be flickr photo" do
32
- @a.flickr_photo?.should == false
49
+ it "should not be flickr media" do
50
+ @a.flickr_media?.should == false
33
51
  end
34
52
  end
35
53
 
36
54
  {'http://www.facebook.com/photo.php?pid=34929102&l=a1abf8cd37&id=15201063' =>
37
- { :media_id => '34929102',
38
- :media_website => 'http://www.facebook.com/photo.php?pid=34929102&l=a1abf8cd37&id=15201063',
39
- :media_api_id => 65288068484364750
55
+ { :type => :photo,
56
+ :media_id => '34929102',
57
+ :media_website => 'http://www.facebook.com/photo.php?pid=34929102&id=15201063',
58
+ :media_api_id => {:pid => "34929102", :uid => "15201063"}
59
+ },
60
+ 'http://www.facebook.com/photo.php?pid=3343211&l=a1abf8cd37&id=322232#!/photo.php?pid=34929102&l=a1abf8cd37&id=15201063' =>
61
+ { :type => :photo,
62
+ :media_id => '34929102',
63
+ :media_website => 'http://www.facebook.com/photo.php?pid=34929102&id=15201063',
64
+ :media_api_id => {:pid => "34929102", :uid => "15201063"}
65
+ },
66
+ 'http://www.facebook.com/photo.php?pid=34929101&id=15201063#!/video/video.php?v=545993063513&subj=15201063' =>
67
+ { :type => :video,
68
+ :media_id => '545993063513',
69
+ :media_website => "http://www.facebook.com/video/video.php?v=545993063513",
70
+ :media_api_id => {:v => '545993063513'}
40
71
  }
41
72
  }.each do |url, values|
42
73
  describe "Facebook parse #{url}" do
43
74
  before(:all) do
44
75
  @a = Muri.parse url
45
76
  end
46
- it_should_behave_like "Facebook parse photo"
77
+ if values[:type] == :photo
78
+ it_should_behave_like "Facebook parse photo"
79
+ elsif values[:type] == :video
80
+ it_should_behave_like "Facebook parse video"
81
+ end
47
82
 
48
83
  if values[:media_id]
49
84
  it "should have media id" do
data/test/flickr_test.rb CHANGED
@@ -20,11 +20,11 @@ end
20
20
  shared_examples_for "Flickr parse photo" do
21
21
  it_should_behave_like "Flickr parse"
22
22
  it "should have media api type = FLICKR_PHOTO" do
23
- @a.media_api_type.should == Muri::FLICKR_PHOTO
23
+ @a.media_api_type.should == Muri::FLICKR_MEDIA
24
24
  end
25
25
 
26
- it "should be flickr photo" do
27
- @a.flickr_photo?.should == true
26
+ it "should be flickr media" do
27
+ @a.flickr_media?.should == true
28
28
  end
29
29
 
30
30
  it "should not be facebook photo" do
@@ -41,9 +41,9 @@ shared_examples_for "Photobucket parse album" do
41
41
  @a.photobucket_album?.should == true
42
42
  end
43
43
 
44
- it "should not be facebook album" do
45
- @a.facebook_album?.should == false
46
- end
44
+ # it "should not be facebook album" do
45
+ # @a.facebook_album?.should == false
46
+ # end
47
47
  end
48
48
  shared_examples_for "Photobucket parse group album" do
49
49
  it_should_behave_like "Photobucket parse"
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 1
7
7
  - 1
8
- - 2
9
- version: 1.1.2
8
+ - 4
9
+ version: 1.1.4
10
10
  platform: ruby
11
11
  authors:
12
12
  - William Schneider
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-04-06 00:00:00 -04:00
17
+ date: 2010-04-29 00:00:00 -04:00
18
18
  default_executable:
19
19
  dependencies: []
20
20
 
@@ -28,6 +28,7 @@ extra_rdoc_files:
28
28
  - README.textile
29
29
  files:
30
30
  - .gitignore
31
+ - CHANGELOG
31
32
  - README.textile
32
33
  - Rakefile
33
34
  - VERSION.yml