eymiha_url 1.0.0

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/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
+