eymiha_url 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/gem_package.rb ADDED
@@ -0,0 +1,31 @@
1
+ class GemPackage
2
+
3
+ attr_reader :name, :version, :files
4
+
5
+ def initialize
6
+ @name = 'eymiha_url'
7
+ @version = '1.0.0'
8
+ @files = FileList[
9
+ '*.rb',
10
+ 'lib/**/*',
11
+ 'test/*',
12
+ 'html/**/*'
13
+ ]
14
+ end
15
+
16
+ def fill_spec(s)
17
+ s.name = name
18
+ s.version = version
19
+ s.summary = "Eymiha application url features"
20
+ s.files = files.to_a
21
+ s.require_path = 'lib'
22
+ s.autorequire = name
23
+ s.has_rdoc = true
24
+ s.rdoc_options << "--all"
25
+ s.author = "Dave Anderson"
26
+ s.email = "dave@eymiha.com"
27
+ s.homepage = "http://www.eymiha.com"
28
+ s.rubyforge_project = "cori"
29
+ end
30
+
31
+ end
@@ -0,0 +1,7 @@
1
+ module Eymiha
2
+
3
+ # Raised when a problem has occured when normalizing or opening a URL.
4
+ class UrlException < Exception
5
+ end
6
+
7
+ end
@@ -0,0 +1,105 @@
1
+ require 'uri'
2
+
3
+ require 'eymiha/url/url_exception'
4
+
5
+ module Eymiha
6
+
7
+ # A UrlNormalizer normalizes URLs. They are validated using the URI class
8
+ # except when they can be identified as file resources. When so, if the
9
+ # designated file's name starts with a slash (or a drive identifier
10
+ # followed by a slash on a windows box) the path is used verbatim. If not,
11
+ # the named file is assumed to be relative to a caller-supplied base
12
+ # directory.
13
+ class UrlNormalizer
14
+
15
+ @@using_pc_filesystem = Config::CONFIG['target_vendor'] == "pc"
16
+
17
+ @@relative_base = nil
18
+
19
+ # Returns true if the given relative_base is valid. It should start and
20
+ # end with a slash (or start with a drive designator and a slash and end
21
+ # with a slash on a PC).
22
+ def self.valid_relative_base? relative_base
23
+ ((@@using_pc_filesystem and (relative_base =~ /^[A-Za-z]:\//)) or
24
+ (!@@using_pc_filesystem and (relative_base =~ /^\//))) and
25
+ (relative_base =~ /\/$/)
26
+ end
27
+
28
+ # Sets and returns the default directory for normalizing relative file
29
+ # resources. The directory is validated prior to assignment - if invalid
30
+ # a UrlException will be raised.
31
+ def self.relative_base=(relative_base)
32
+ if valid_relative_base? relative_base
33
+ @@relative_base = relative_base
34
+ else
35
+ raise UrlException, "Invalid relative file base '#{relative_base}'"
36
+ end
37
+ end
38
+
39
+ # Returns the default directory for normalizing relative file resources.
40
+ def self.relative_base
41
+ @@relative_base
42
+ end
43
+
44
+ attr_reader :relative_base
45
+
46
+ # Creates a new instance using the default direcory for normalizing
47
+ # relative file resources.
48
+ def initialize()
49
+ @relative_base = @@relative_base
50
+ end
51
+
52
+ # Returns a normalized URL relative to the given base if it is a
53
+ # relative file resource.
54
+ def normalize(url,relative_base=nil)
55
+ self.relative_base = relative_base if relative_base
56
+ (self.class.file_url? url) ? normalize_file(url) : URI.parse(url).to_s
57
+ end
58
+
59
+ # Returns true if the given URL is a file resource.
60
+ def self.file_url? url
61
+ (url =~ /^file:/) or
62
+ (url =~ /^\//) or
63
+ ((url =~ /^[A-Za-z]:/) and @@using_pc_filesystem) or
64
+ !(url =~ /:/)
65
+ end
66
+
67
+ # Normalizes and returns a relative or absolute URL file resource.
68
+ def normalize_file file_url
69
+ "file://#{normalize_file_path((file_url =~ /file:\/\//) ? $' : file_url)}"
70
+ end
71
+
72
+ # Sets and Returns the directory for normalizing relative file resources.
73
+ # The directory is validated prior to assignment - if invalid a
74
+ # UrlException will be raised.
75
+ def relative_base=(relative_base)
76
+ if self.class.valid_relative_base? relative_base
77
+ @relative_base = relative_base
78
+ else
79
+ raise UrlException, "Invalid relative file base '#{relative_base}'"
80
+ end
81
+ end
82
+
83
+ # Returns true if the given URL file resource is absolute.
84
+ def self.absolute_file_path? file_url
85
+ @@using_pc_filesystem ?
86
+ (file_url =~ /^[A-Za-z]:\//) :
87
+ (!(file_url =~ /^[A-Za-z]:/) and (file_url =~ /^\//))
88
+ end
89
+
90
+ # Returns an absolute path for the given URL file resource. This is either
91
+ # the incoming URL if absolute, or the URL anchored at the relative base
92
+ # if relative.
93
+ def normalize_file_path file_url
94
+ if self.class.absolute_file_path? file_url
95
+ file_url
96
+ elsif @relative_base != nil
97
+ "#{relative_base}#{file_url}"
98
+ else
99
+ raise UrlException, "no relative file base was configured"
100
+ end
101
+ end
102
+
103
+ end
104
+
105
+ end
@@ -0,0 +1,141 @@
1
+ require 'eymiha'
2
+ require 'eymiha/url/url_exception'
3
+ require 'eymiha/url/url_normalizer'
4
+
5
+ optional_require 'win32/registry'
6
+
7
+ module Eymiha
8
+
9
+ # UrlOpener opens a URL in a user's URL viewer of choice. URLs are
10
+ # normalized prior to being opened.
11
+ #
12
+ # Instances use the Kernel::system method to open the resource in its
13
+ # own Thread to avoid blocking. Any problems are raised through a
14
+ # caller-supplied exception handler's handle(Exception) method.
15
+ #
16
+ # For Apple and Windows, the viewer-of-choice is defaulted to the user's
17
+ # designated viewer in the environment. For other platforms, the caller
18
+ # must assign the viewer prior to opening the URL.
19
+ class UrlOpener
20
+
21
+ @@url_viewer = nil
22
+
23
+ # Sets and returns the user's default URL viewer-or-choice.
24
+ def self.url_viewer=(url_viewer)
25
+ @@url_viewer = url_viewer
26
+ end
27
+
28
+ # Returns the user's default URL viewer-of-choice.
29
+ def self.url_viewer
30
+ @@url_viewer
31
+ end
32
+
33
+ @@relative_base = nil
34
+
35
+ # Sets and returns the default directory for opening relative file
36
+ # resources. The directory is validated prior to assignment - if invalid
37
+ # a UrlException will be raised.
38
+ def self.relative_base=(relative_base)
39
+ if UrlNormalizer.valid_relative_base? relative_base
40
+ @@relative_base = relative_base
41
+ else
42
+ raise UrlException, "Invalid relative file base '#{relative_base}'"
43
+ end
44
+ end
45
+
46
+ # Returns the default directory for opening relative file resources.
47
+ def self.relative_base
48
+ @@relative_base
49
+ end
50
+
51
+ @@exception_handler = nil
52
+
53
+ # Sets and returns the default exception handler. Problems are reported
54
+ # through its handle method, so it should either have the method, or
55
+ # construct it or delegate at runtime.
56
+ def self.exception_handler=(exception_handler)
57
+ @@exceptionHandler = exception_handler
58
+ end
59
+
60
+ # Returns the default exception handler.
61
+ def self.exception_handler
62
+ @@exception_handler
63
+ end
64
+
65
+ attr_accessor :url_viewer, :exception_handler
66
+ attr_reader :relative_base
67
+
68
+ # Constructs and returns a new instance, using the default exception
69
+ # handler, directory for opening relative file resources, and viewer of
70
+ # choice.
71
+ def initialize(exception_handler=@@exception_handler,
72
+ relative_base=@@relative_base,
73
+ url_viewer=@@url_viewer)
74
+ @exception_handler = exception_handler
75
+ @relative_base = relative_base
76
+ @url_viewer = url_viewer
77
+ @url_normalizer = UrlNormalizer.new
78
+ end
79
+
80
+ # Sets and Returns the directory for opening relative file resources. The
81
+ # directory is validated prior to assignment - if invalid a UrlException
82
+ # will be raised.
83
+ def relative_base=(relative_base)
84
+ if UrlNormalizer.valid_relative_base? relative_base
85
+ @relative_base = relative_base
86
+ else
87
+ raise UrlException, "Invalid relative file base '#{relative_base}'"
88
+ end
89
+ end
90
+
91
+ # opens the given URL in the user's viewer of choice. The method uses a
92
+ # separate Thread to avoid blocking. Local file resources are opened
93
+ # relative to the value of the current relative base directory, and any
94
+ # problems are reported through the exception handler.
95
+ def open url
96
+ Thread.new {
97
+ begin
98
+ send "open_#{Config::CONFIG['target_vendor']}".to_sym,
99
+ @url_normalizer.normalize(url.to_s,@relative_base)
100
+ rescue Exception => exception
101
+ @exception_handler.handle exception
102
+ end
103
+ terminate
104
+ }
105
+ end
106
+
107
+ def method_missing(method,*args)
108
+ open_other(*args) if method.to_s =~ /^open_/
109
+ end
110
+
111
+ private
112
+
113
+ def open_apple url
114
+ system "#{url_viewer||"open"} #{url}"
115
+ end
116
+
117
+ def windows_browser
118
+ @@windows_browser ||=
119
+ Win32::Registry::HKEY_CLASSES_ROOT.
120
+ open('htmlfile\shell\open\command') { |reg|
121
+ reg_type, reg_value = reg.read('')
122
+ return reg_value
123
+ }
124
+ end
125
+
126
+ def open_pc url
127
+ system "#{url_viewer||windows_browser} #{url}"
128
+ end
129
+
130
+ def open_other *args
131
+ if @url_viewer
132
+ system "#{@url_viewer} #{args.join(' ')}"
133
+ else
134
+ raise UrlException,
135
+ "No program was designated to open the URL."
136
+ end
137
+ end
138
+
139
+ end
140
+
141
+ end
data/lib/eymiha/url.rb ADDED
@@ -0,0 +1,4 @@
1
+ # Adds the URL-aware classes.
2
+ require 'eymiha/url/url_exception'
3
+ require 'eymiha/url/url_normalizer'
4
+ require 'eymiha/url/url_opener'
data/rakefile.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'gem_package'
2
+ require 'gem_raker'
@@ -0,0 +1,143 @@
1
+ require 'test/unit'
2
+
3
+ require 'eymiha/url'
4
+
5
+
6
+ class TC_url_normalizer < Test::Unit::TestCase
7
+
8
+ include Eymiha
9
+
10
+ def test_absolute_file_path
11
+
12
+ UrlNormalizer.using_pc_filesystem = true # pc tests
13
+ assert( UrlNormalizer.absolute_file_path?("c:/foo/bar"))
14
+ assert(! UrlNormalizer.absolute_file_path?("c:bar"))
15
+ assert(! UrlNormalizer.absolute_file_path?("/foo/bar"))
16
+ assert(! UrlNormalizer.absolute_file_path?("bar"))
17
+
18
+ UrlNormalizer.using_pc_filesystem = false # non-pc-tests
19
+ assert(! UrlNormalizer.absolute_file_path?("c:/foo/bar"))
20
+ assert(! UrlNormalizer.absolute_file_path?("c:bar"))
21
+ assert( UrlNormalizer.absolute_file_path?("/foo/bar"))
22
+ assert(! UrlNormalizer.absolute_file_path?("bar"))
23
+
24
+ end
25
+
26
+ def test_valid_relative_base
27
+
28
+ UrlNormalizer.using_pc_filesystem = true # pc tests
29
+ assert( UrlNormalizer.valid_relative_base?("c:/foo/"))
30
+ assert(! UrlNormalizer.valid_relative_base?("/foo/"))
31
+ assert(! UrlNormalizer.valid_relative_base?("c:/foo"))
32
+ assert(! UrlNormalizer.valid_relative_base?("/foo"))
33
+ assert( UrlNormalizer.valid_relative_base?("c:/"))
34
+ assert(! UrlNormalizer.valid_relative_base?("/"))
35
+
36
+ UrlNormalizer.using_pc_filesystem = false # non-pc-tests
37
+ assert(! UrlNormalizer.valid_relative_base?("c:/foo/"))
38
+ assert( UrlNormalizer.valid_relative_base?("/foo/"))
39
+ assert(! UrlNormalizer.valid_relative_base?("c:/foo"))
40
+ assert(! UrlNormalizer.valid_relative_base?("/foo"))
41
+ assert(! UrlNormalizer.valid_relative_base?("c:/"))
42
+ assert( UrlNormalizer.valid_relative_base?("/"))
43
+
44
+ end
45
+
46
+ def test_file_url
47
+
48
+ UrlNormalizer.using_pc_filesystem = true # pc tests
49
+ assert( UrlNormalizer.file_url?("file://foo/bar"))
50
+ assert( UrlNormalizer.file_url?("/foo/bar"))
51
+ assert( UrlNormalizer.file_url?("c:foo"))
52
+ assert( UrlNormalizer.file_url?("foo"))
53
+ assert(! UrlNormalizer.file_url?("bump:mumble"))
54
+
55
+ UrlNormalizer.using_pc_filesystem = false # non-pc-tests
56
+ assert( UrlNormalizer.file_url?("file://foo/bar"))
57
+ assert( UrlNormalizer.file_url?("/foo/bar"))
58
+ assert(! UrlNormalizer.file_url?("c:foo"))
59
+ assert( UrlNormalizer.file_url?("foo"))
60
+ assert(! UrlNormalizer.file_url?("bump:mumble"))
61
+
62
+ end
63
+
64
+ def test_normalize
65
+
66
+ urlNormalizer = UrlNormalizer.new
67
+
68
+ UrlNormalizer.using_pc_filesystem = true # pc tests
69
+ urlNormalizer.relative_base = "c:/foo/"
70
+ assert(urlNormalizer.normalize("file://c:/foo/bar") == "file://c:/foo/bar")
71
+ assert(urlNormalizer.normalize("c:/foo/bar") == "file://c:/foo/bar")
72
+ assert(urlNormalizer.normalize("file://bar") == "file://c:/foo/bar")
73
+ assert(urlNormalizer.normalize("bar") == "file://c:/foo/bar")
74
+ assert(urlNormalizer.normalize("bump:mumble") == "bump:mumble")
75
+
76
+ UrlNormalizer.using_pc_filesystem = false # non-pc-tests
77
+ urlNormalizer.relative_base = "/foo/"
78
+ assert(urlNormalizer.normalize("file:///foo/bar") == "file:///foo/bar")
79
+ assert(urlNormalizer.normalize("/foo/bar") == "file:///foo/bar")
80
+ assert(urlNormalizer.normalize("file://bar") == "file:///foo/bar")
81
+ assert(urlNormalizer.normalize("bar") == "file:///foo/bar")
82
+ assert(urlNormalizer.normalize("bump:mumble") == "bump:mumble")
83
+
84
+ end
85
+
86
+ def test_normalize_file
87
+
88
+ urlNormalizer = UrlNormalizer.new
89
+
90
+ UrlNormalizer.using_pc_filesystem = true # pc tests
91
+ urlNormalizer.relative_base = "c:/foo/"
92
+ assert(urlNormalizer.normalize_file("file://c:/foo/bar") == "file://c:/foo/bar")
93
+ assert(urlNormalizer.normalize_file("c:/foo/bar") == "file://c:/foo/bar")
94
+ assert(urlNormalizer.normalize_file("file://bar") == "file://c:/foo/bar")
95
+ assert(urlNormalizer.normalize_file("bar") == "file://c:/foo/bar")
96
+
97
+ UrlNormalizer.using_pc_filesystem = false # non-pc-tests
98
+ urlNormalizer.relative_base = "/foo/"
99
+ assert(urlNormalizer.normalize_file("file:///foo/bar") == "file:///foo/bar")
100
+ assert(urlNormalizer.normalize_file("/foo/bar") == "file:///foo/bar")
101
+ assert(urlNormalizer.normalize_file("file://bar") == "file:///foo/bar")
102
+ assert(urlNormalizer.normalize_file("bar") == "file:///foo/bar")
103
+
104
+ end
105
+
106
+ def test_normalize_file_path
107
+
108
+ urlNormalizer = UrlNormalizer.new
109
+ assert_raise(UrlException) { urlNormalizer.normalize_file_path("bar") }
110
+
111
+ UrlNormalizer.using_pc_filesystem = true # pc tests
112
+ urlNormalizer.relative_base = "c:/foo/"
113
+ assert(urlNormalizer.normalize_file_path("c:/foo/bar") == "c:/foo/bar")
114
+ assert(urlNormalizer.normalize_file_path("bar") == "c:/foo/bar")
115
+
116
+ UrlNormalizer.using_pc_filesystem = false # non-pc-tests
117
+ urlNormalizer.relative_base = "/foo/"
118
+ assert(urlNormalizer.normalize_file_path("/foo/bar") == "/foo/bar")
119
+ assert(urlNormalizer.normalize_file_path("bar") == "/foo/bar")
120
+
121
+ end
122
+
123
+ def test_relative_base
124
+
125
+ assert_raise(UrlException) { UrlNormalizer.relative_base = ""}
126
+
127
+ urlNormalizer = UrlNormalizer.new
128
+ assert_raise(UrlException) { urlNormalizer.relative_base = ""}
129
+
130
+ end
131
+
132
+ end
133
+
134
+
135
+ # just for testing...
136
+
137
+ class Eymiha::UrlNormalizer
138
+
139
+ def self.using_pc_filesystem=(using_pc_filesystem)
140
+ @@using_pc_filesystem = using_pc_filesystem
141
+ end
142
+
143
+ end
@@ -0,0 +1,75 @@
1
+ require 'eymiha/test'
2
+ require 'eymiha/url'
3
+
4
+
5
+ class TC_url_opener < Test::Unit::TestCase
6
+
7
+ # exception_handler is tested indirectly
8
+ # relative_base is tested in UrlNormalizer
9
+ # method_missing is tested indirectly
10
+ # windows registry access is assumed correct
11
+
12
+ include Eymiha
13
+
14
+ def test_open_apple
15
+ url_opener = UrlOpener.new
16
+ probe UrlOpener, :open_apple do
17
+ assert(url_opener.open_apple("foo") == "open foo")
18
+ end
19
+ url_opener.url_viewer = "url_viewer"
20
+ probe UrlOpener, :open_apple do
21
+ assert(url_opener.open_apple("foo") == "url_viewer foo")
22
+ end
23
+ end
24
+
25
+ def test_open_pc
26
+ url_opener = UrlOpener.new
27
+ UrlOpener.windows_browser = "windows_browser"
28
+ probe UrlOpener, :open_pc do
29
+ assert(url_opener.open_pc("foo") == "windows_browser foo")
30
+ end
31
+ url_opener.url_viewer = "url_viewer"
32
+ probe UrlOpener, :open_pc do
33
+ assert(url_opener.open_pc("foo") == "url_viewer foo")
34
+ end
35
+ end
36
+
37
+ def test_open_other
38
+ url_opener = UrlOpener.new(self,nil,nil)
39
+ probe UrlOpener, :open_other do
40
+ assert_raise(UrlException) { url_opener.open_foo }
41
+ end
42
+ url_opener.url_viewer = "url_viewer"
43
+ probe UrlOpener, :open_other do
44
+ assert(url_opener.open_other("foo") == "url_viewer foo")
45
+ end
46
+ end
47
+
48
+ end
49
+
50
+
51
+ # just for testing...
52
+
53
+ class Eymiha::UrlOpener
54
+
55
+ def system(command)
56
+ command
57
+ end
58
+
59
+ def url_normalizer=(url_normalizer)
60
+ @url_normalizer = url_normalizer
61
+ end
62
+
63
+ def normalize(url,relative_base)
64
+ url
65
+ end
66
+
67
+ def self.windows_browser=(windows_browser)
68
+ @@windows_browser = windows_browser
69
+ end
70
+
71
+ def handle
72
+ raise UrlException
73
+ end
74
+
75
+ end
metadata ADDED
@@ -0,0 +1,55 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.4
3
+ specification_version: 1
4
+ name: eymiha_url
5
+ version: !ruby/object:Gem::Version
6
+ version: 1.0.0
7
+ date: 2008-05-07 00:00:00 -04:00
8
+ summary: Eymiha application url features
9
+ require_paths:
10
+ - lib
11
+ email: dave@eymiha.com
12
+ homepage: http://www.eymiha.com
13
+ rubyforge_project: cori
14
+ description:
15
+ autorequire: eymiha_url
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Dave Anderson
31
+ files:
32
+ - gem_package.rb
33
+ - rakefile.rb
34
+ - lib/eymiha
35
+ - lib/eymiha/url
36
+ - lib/eymiha/url/url_exception.rb
37
+ - lib/eymiha/url/url_normalizer.rb
38
+ - lib/eymiha/url/url_opener.rb
39
+ - lib/eymiha/url.rb
40
+ - test/tc_url_normalizer.rb
41
+ - test/tc_url_opener.rb
42
+ test_files: []
43
+
44
+ rdoc_options:
45
+ - --all
46
+ extra_rdoc_files: []
47
+
48
+ executables: []
49
+
50
+ extensions: []
51
+
52
+ requirements: []
53
+
54
+ dependencies: []
55
+