webloc 0.1.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/LICENSE +21 -0
- data/README.md +8 -3
- data/lib/webloc/version.rb +1 -1
- data/lib/webloc.rb +48 -8
- data/test/webloc_test.rb +17 -4
- data/webloc.gemspec +4 -4
- metadata +8 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 498d11e48961e5843a3a25fafb71f4738ebc10733037145ea30a17f176abcaa2
|
4
|
+
data.tar.gz: 78beeadfdafd1a7f414fc6f7b69c6fd24819ed79bb39a9148e72e1bc38089416
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 99b273c4af784bdafe2cde8166da2c3672a263d2e412f0f1547e70ef4b8bf8de74185a13b1050e5c16b713e3f7b8c67baabe9f25b1366ee4e86876a95a368740
|
7
|
+
data.tar.gz: fdbd68bb1239b9b35b1eb8c3d3ef8302d69d8a48eca6830bf636eb693f6e8c9a35e19af02148fda21a2d5a2ce3be1e3b7bef8186d7917dd8c40f73a699557e60
|
data/.gitignore
CHANGED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2011-2024 Peter Cooper
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# webloc
|
2
2
|
|
3
|
-
*webloc* is a Ruby library that can read from and write to <tt>.webloc</tt> files as used on macOS.
|
3
|
+
*webloc* is a Ruby library that can read from and write to <tt>.webloc</tt> files as used on macOS. These are a variant of 'plist' format files, specifically used for storing links to URLs.
|
4
4
|
|
5
|
-
It works on Ruby
|
5
|
+
It works on Ruby 2.7 and up, including Ruby 3.x, and supports URLs of up to 2048 characters in length (and probably longer, but this is around the de facto limit for URLs in most systems).
|
6
6
|
|
7
7
|
## Installation
|
8
8
|
|
@@ -18,8 +18,13 @@ Writing to a .webloc file:
|
|
18
18
|
|
19
19
|
Webloc.new('https://rubyweekly.com/').save('rubyweekly.webloc')
|
20
20
|
|
21
|
+
## Thanks
|
22
|
+
|
23
|
+
Thanks is due to Christos Karaiskos for [this article](https://medium.com/@karaiskc/understanding-apples-binary-property-list-format-281e6da00dbd
|
24
|
+
) which helped me understand the plist format a bit more when fixing a bug in 2024.
|
25
|
+
|
21
26
|
## License
|
22
27
|
|
23
|
-
Copyright (C) 2011-
|
28
|
+
Copyright (C) 2011-2024 Peter Cooper
|
24
29
|
|
25
30
|
webloc is licensed under the terms of the MIT License
|
data/lib/webloc/version.rb
CHANGED
data/lib/webloc.rb
CHANGED
@@ -13,9 +13,16 @@ class Webloc
|
|
13
13
|
|
14
14
|
if data !~ /\<plist/
|
15
15
|
offset = (data =~ /SURL_/)
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
length_offset = 7
|
17
|
+
if data[offset + 5] == "\x10"
|
18
|
+
length = data[offset + 6]
|
19
|
+
length = length.unpack('C')[0]
|
20
|
+
elsif data[offset + 5] == "\x11"
|
21
|
+
length_offset = 8
|
22
|
+
length = data[offset + 6] + data[offset + 7]
|
23
|
+
length = length.unpack('S>')[0]
|
24
|
+
end
|
25
|
+
url = data[offset + length_offset,length]
|
19
26
|
else
|
20
27
|
url = Plist::parse_xml(filename)['URL'] rescue nil
|
21
28
|
end
|
@@ -25,11 +32,44 @@ class Webloc
|
|
25
32
|
end
|
26
33
|
|
27
34
|
def data
|
28
|
-
|
29
|
-
@data
|
30
|
-
|
31
|
-
|
32
|
-
@data +=
|
35
|
+
# PLIST HEADER
|
36
|
+
@data = "bplist\x30\x30".bytes
|
37
|
+
|
38
|
+
# PLIST OBJECT TABLE
|
39
|
+
@data += "\xD1\x01\x02".bytes # object 1 is a dictionary
|
40
|
+
@data += "SURL".bytes # object 2
|
41
|
+
|
42
|
+
length_suffix = @url.length > 255 ? "\x11" : "\x10"
|
43
|
+
@data += ("\x5f" + length_suffix).bytes # object 3 is an ASCII string with a variable length length encoding (I know..)
|
44
|
+
# .. the '0' in \x10 denotes the length can be encoded within 2**0 bytes (i.e. 1)
|
45
|
+
# .. the '1' in \x11 denotes the length can be encoded within 2**1 bytes (i.e. 2)
|
46
|
+
|
47
|
+
if @url.length > 255
|
48
|
+
@data += [@url.length].pack('S>').bytes
|
49
|
+
else
|
50
|
+
@data += [@url.length].pack('C').bytes
|
51
|
+
end
|
52
|
+
@data += @url.bytes # and finally the URL itself
|
53
|
+
|
54
|
+
# This is the offset table
|
55
|
+
@data += "\x08\x0B\x0F".bytes # so objects at 0x08, 0x0b and 0x0f
|
56
|
+
|
57
|
+
# PLIST TRAILER
|
58
|
+
# Bytes 0-4 are unused
|
59
|
+
@data += "\x00\x00\x00\x00\x00".bytes
|
60
|
+
# Byte 5 is the sort version
|
61
|
+
@data += "\x00".bytes
|
62
|
+
# Byte 6 is how many bytes are needed for each offset table offset
|
63
|
+
@data += "\x01".bytes
|
64
|
+
@data += "\x01".bytes
|
65
|
+
# Bytes 8-15 are how many objects are contained in the plist
|
66
|
+
@data += "\x00\x00\x00\x00\x00\x00\x00\x03".bytes
|
67
|
+
# Bytes 16-23 are for an offset from the offset table
|
68
|
+
@data += "\x00\x00\x00\x00\x00\x00\x00\x00".bytes
|
69
|
+
# Bytes 24-31 denote the position of the offset table from the start of the file
|
70
|
+
@data += "\x00\x00\x00\x00\x00\x00".bytes + [@url.length + 18].pack('S>').bytes
|
71
|
+
|
72
|
+
@data = @data.pack('C*')
|
33
73
|
end
|
34
74
|
|
35
75
|
def save(filename)
|
data/test/webloc_test.rb
CHANGED
@@ -20,18 +20,31 @@ class WeblocTest < Test::Unit::TestCase
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def test_webloc_generates_valid_data
|
23
|
-
data = File.read(File.dirname(__FILE__) + '/oldstyle.webloc')
|
23
|
+
data = File.read(File.dirname(__FILE__) + '/oldstyle.webloc').b
|
24
24
|
assert_equal data, Webloc.new('https://github.com/peterc/webloc').data
|
25
25
|
end
|
26
26
|
|
27
|
+
def test_webloc_can_handle_long_urls
|
28
|
+
url = "http://example.com/this-is-a-very-long-url-abcde" + ('a' * 2000)
|
29
|
+
assert_nothing_raised { Webloc.new(url).data }
|
30
|
+
file = Tempfile.new('test-long-webloc')
|
31
|
+
begin
|
32
|
+
Webloc.new(url).save(file.path)
|
33
|
+
assert_equal url, Webloc.load(file.path).url
|
34
|
+
ensure
|
35
|
+
file.close
|
36
|
+
file.unlink
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
27
40
|
def test_webloc_can_write_file
|
28
41
|
file = Tempfile.new('test-webloc')
|
29
42
|
begin
|
30
43
|
Webloc.new('https://github.com/peterc/webloc').save(file.path)
|
31
|
-
assert_equal Webloc.new('https://github.com/peterc/webloc').data, File.read(file.path)
|
44
|
+
assert_equal Webloc.new('https://github.com/peterc/webloc').data, File.read(file.path).b
|
32
45
|
ensure
|
33
|
-
|
34
|
-
|
46
|
+
file.close
|
47
|
+
file.unlink
|
35
48
|
end
|
36
49
|
end
|
37
50
|
end
|
data/webloc.gemspec
CHANGED
@@ -7,10 +7,10 @@ Gem::Specification.new do |s|
|
|
7
7
|
s.version = Webloc::VERSION
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
9
|
s.authors = ["Peter Cooper"]
|
10
|
-
s.email = ["
|
11
|
-
s.homepage = "
|
12
|
-
s.summary = %q{Reads and writes .webloc files on
|
13
|
-
s.description = %q{Webloc reads and writes .webloc files on
|
10
|
+
s.email = ["git@peterc.org"]
|
11
|
+
s.homepage = "https://github.com/peterc/webloc"
|
12
|
+
s.summary = %q{Reads and writes .webloc files on macOS}
|
13
|
+
s.description = %q{Webloc reads and writes .webloc files on macOS}
|
14
14
|
|
15
15
|
s.rubyforge_project = "webloc"
|
16
16
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: webloc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Cooper
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-05-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: plist
|
@@ -24,15 +24,16 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
-
description: Webloc reads and writes .webloc files on
|
27
|
+
description: Webloc reads and writes .webloc files on macOS
|
28
28
|
email:
|
29
|
-
-
|
29
|
+
- git@peterc.org
|
30
30
|
executables: []
|
31
31
|
extensions: []
|
32
32
|
extra_rdoc_files: []
|
33
33
|
files:
|
34
34
|
- ".gitignore"
|
35
35
|
- Gemfile
|
36
|
+
- LICENSE
|
36
37
|
- README.md
|
37
38
|
- Rakefile
|
38
39
|
- lib/webloc.rb
|
@@ -41,7 +42,7 @@ files:
|
|
41
42
|
- test/pliststyle.webloc
|
42
43
|
- test/webloc_test.rb
|
43
44
|
- webloc.gemspec
|
44
|
-
homepage:
|
45
|
+
homepage: https://github.com/peterc/webloc
|
45
46
|
licenses: []
|
46
47
|
metadata: {}
|
47
48
|
post_install_message:
|
@@ -59,10 +60,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
59
60
|
- !ruby/object:Gem::Version
|
60
61
|
version: '0'
|
61
62
|
requirements: []
|
62
|
-
rubygems_version: 3.
|
63
|
+
rubygems_version: 3.5.3
|
63
64
|
signing_key:
|
64
65
|
specification_version: 4
|
65
|
-
summary: Reads and writes .webloc files on
|
66
|
+
summary: Reads and writes .webloc files on macOS
|
66
67
|
test_files:
|
67
68
|
- test/oldstyle.webloc
|
68
69
|
- test/pliststyle.webloc
|