infod 0.0.1 → 0.0.2
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/infod.rb +2 -3
- data/infod/Es.rb +31 -67
- data/infod/{W/source.rb → Es/code.rb} +6 -10
- data/infod/Es/css.rb +21 -0
- data/infod/{W → Es}/csv.rb +0 -0
- data/infod/Es/du.rb +16 -0
- data/infod/{W → Es}/feed.rb +13 -11
- data/infod/Es/filter.rb +75 -0
- data/infod/Es/find.rb +20 -0
- data/infod/Es/fs.rb +145 -136
- data/infod/Es/glob.rb +22 -0
- data/infod/Es/grep.rb +61 -0
- data/infod/Es/groonga.rb +47 -56
- data/infod/Es/html.rb +271 -0
- data/infod/Es/image.rb +114 -0
- data/infod/Es/in.rb +68 -0
- data/infod/Es/index.rb +183 -0
- data/infod/{W → Es}/json.rb +28 -4
- data/infod/Es/kv.rb +60 -0
- data/infod/Es/ls.rb +58 -0
- data/infod/Es/mail.rb +87 -0
- data/infod/Es/man.rb +112 -0
- data/infod/Es/mime.rb +59 -0
- data/infod/Es/out.rb +52 -0
- data/infod/{W/page.rb → Es/pager.rb} +7 -3
- data/infod/Es/pdf.rb +19 -0
- data/infod/Es/rdf.rb +35 -0
- data/infod/Es/schema.rb +99 -0
- data/infod/Es/search.rb +24 -0
- data/infod/Es/sh.rb +21 -0
- data/infod/{W → Es}/text.rb +26 -14
- data/infod/H.rb +15 -29
- data/infod/H/audio.rb +19 -0
- data/infod/H/blog.rb +15 -0
- data/infod/{W → H}/cal.rb +2 -31
- data/infod/H/edit.rb +88 -0
- data/infod/{W/examine/examine.rb → H/facets.rb} +17 -17
- data/infod/{W → H}/forum.rb +1 -0
- data/infod/{W/examine/sw.rb → H/hf.rb} +12 -12
- data/infod/H/histogram.rb +78 -0
- data/infod/H/mail.rb +92 -0
- data/infod/{W/chat.rb → H/microblog.rb} +21 -16
- data/infod/H/threads.rb +77 -0
- data/infod/H/time.rb +131 -0
- data/infod/H/who.rb +30 -0
- data/infod/{W → H}/wiki.rb +0 -0
- data/infod/K.rb +28 -60
- data/infod/N.rb +151 -74
- data/infod/Rb.rb +3 -3
- data/infod/Th.rb +27 -101
- data/infod/Th/404.rb +29 -36
- data/infod/Th/500.rb +36 -5
- data/infod/Th/GET.rb +48 -118
- data/infod/Th/POST.rb +31 -11
- data/infod/Th/perf.rb +37 -0
- data/infod/Th/util.rb +89 -0
- data/infod/Y.rb +24 -7
- data/infod/infod.rb +2 -3
- metadata +92 -64
- data/infod/Es/redis.rb +0 -3
- data/infod/Es/sqlite.rb +0 -3
- data/infod/Th/local.rb +0 -22
- data/infod/W.rb +0 -34
- data/infod/W/audio.rb +0 -56
- data/infod/W/blog.rb +0 -3
- data/infod/W/color.rb +0 -28
- data/infod/W/core.rb +0 -77
- data/infod/W/css.rb +0 -24
- data/infod/W/du.rb +0 -35
- data/infod/W/edit.rb +0 -8
- data/infod/W/examine/exhibit.rb +0 -34
- data/infod/W/examine/hist.rb +0 -55
- data/infod/W/examine/history.rb +0 -19
- data/infod/W/examine/normal.rb +0 -31
- data/infod/W/examine/protovis.rb +0 -30
- data/infod/W/examine/time/graph.rb +0 -86
- data/infod/W/examine/time/line.rb +0 -24
- data/infod/W/find.rb +0 -24
- data/infod/W/grep.rb +0 -27
- data/infod/W/html.rb +0 -143
- data/infod/W/image.rb +0 -61
- data/infod/W/kv.rb +0 -66
- data/infod/W/ls.rb +0 -50
- data/infod/W/mail.rb +0 -248
- data/infod/W/pdf.rb +0 -16
- data/infod/W/post.rb +0 -9
- data/infod/W/rdf.rb +0 -32
- data/infod/W/schema.rb +0 -172
- data/infod/W/search.rb +0 -33
- data/infod/W/shell.rb +0 -30
- data/infod/W/table.rb +0 -87
- data/infod/W/tree.rb +0 -26
- data/infod/W/vfs.rb +0 -175
data/infod/H/who.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
#watch __FILE__
|
2
|
+
class E
|
3
|
+
|
4
|
+
fn '/whois/GET',->e,r{
|
5
|
+
[302,{Location: '/' + ( r.q['p'].match(/to$/) ? 'to' : 'from' ) + '/' + (URI.escape r.q['q'])},[]]
|
6
|
+
}
|
7
|
+
|
8
|
+
fn '/to/GET',->e,r{
|
9
|
+
name = e.pathSegment.uri.sub('/to/','/').tail
|
10
|
+
if !name || name.empty?
|
11
|
+
false
|
12
|
+
else
|
13
|
+
H({style: 'text-align: center',
|
14
|
+
c: [To.E.rangeP.map(&:uri).grep(/#{name}/).map{|n|
|
15
|
+
{_: :a,href: n.E.url+'?set=indexPO&p=sioc:addressed_to&view=page&v', c: n}},
|
16
|
+
{_: :style, c: "a {display:block;text-decoration:none}"}]}).hR
|
17
|
+
end}
|
18
|
+
|
19
|
+
fn '/from/GET',->e,r{
|
20
|
+
name = e.pathSegment.uri.sub('/from/','/').tail
|
21
|
+
if !name || name.empty?
|
22
|
+
false
|
23
|
+
else
|
24
|
+
H({style: 'text-align: center',
|
25
|
+
c: [Creator.E.rangeP(1e4).map(&:uri).grep(/#{name}/).map{|n|
|
26
|
+
{_: :a,href: n.E.url+'?set=indexPO&p=sioc:has_creator&view=page&v', c: n}},
|
27
|
+
{_: :style, c: "a {display:block;text-decoration:none}"}]}).hR
|
28
|
+
end}
|
29
|
+
|
30
|
+
end
|
data/infod/{W → H}/wiki.rb
RENAMED
File without changes
|
data/infod/K.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
+
#watch __FILE__
|
1
2
|
class E
|
2
3
|
|
3
|
-
FSbase
|
4
|
-
Prefix
|
5
|
-
S
|
4
|
+
FSbase = `pwd`.chomp ; BaseLen = FSbase.size
|
5
|
+
Prefix = '/@' # non-HTTP URI path resolution-prefix
|
6
|
+
S = /\._/ # data path-separator
|
6
7
|
|
7
|
-
# frequently-used URIs
|
8
8
|
W3 = 'http://www.w3.org/'
|
9
9
|
Purl = 'http://purl.org/'
|
10
10
|
FOAF = "http://xmlns.com/foaf/0.1/"
|
@@ -22,13 +22,17 @@ class E
|
|
22
22
|
Type = W3 + "1999/02/22-rdf-syntax-ns#type"
|
23
23
|
RDFs = W3 + '2000/01/rdf-schema#'
|
24
24
|
HTTP = W3 + '2011/http#'
|
25
|
+
Header = W3 + '2011/http-headers#'
|
25
26
|
Posix = W3 + 'ns/posix/'
|
26
27
|
Stat = Posix + 'stat#'
|
27
28
|
Label = RDFs + 'label'
|
28
29
|
EXIF = 'http://www.w3.org/2003/12/exif/ns#'
|
29
30
|
Audio = 'http://www.semanticdesktop.org/ontologies/nid3/#'
|
31
|
+
Edit = 'http://buzzword.org.uk/rdf/personal-link-types#edit'
|
32
|
+
Render = 'render/'
|
33
|
+
Apache = ENV['apache']
|
34
|
+
Nginx = ENV['nginx']
|
30
35
|
|
31
|
-
# file-name extension -> MIME type
|
32
36
|
MIME={
|
33
37
|
aif: 'audio/aif',
|
34
38
|
ans: 'text/ansi',
|
@@ -58,12 +62,13 @@ class E
|
|
58
62
|
mp3: 'audio/mpeg',
|
59
63
|
mp4: 'video/mp4',
|
60
64
|
mpg: 'video/mpg',
|
61
|
-
n3: 'text/
|
65
|
+
n3: 'text/n3',
|
62
66
|
nfo: 'text/nfo',
|
63
67
|
nt: 'text/ntriples',
|
64
68
|
ntriples: 'text/ntriples',
|
65
69
|
owl: 'application/rdf+xml',
|
66
70
|
pdf: 'application/pdf',
|
71
|
+
pl: 'application/perl',
|
67
72
|
png: 'image/png',
|
68
73
|
py: 'application/python',
|
69
74
|
rb: 'application/ruby',
|
@@ -76,17 +81,20 @@ class E
|
|
76
81
|
ttl: 'text/turtle',
|
77
82
|
txt: 'text/plain',
|
78
83
|
u: 'application/uri',
|
84
|
+
url: 'text/plain',
|
79
85
|
wav: 'audio/wav',
|
80
86
|
wmv: 'video/wmv',
|
81
87
|
xlsx: 'application/excel',
|
82
88
|
}
|
83
89
|
|
84
|
-
|
90
|
+
VideoFile = /(avi|flv|mkv|mpg|mp4|wmv)$/i
|
91
|
+
AudioFile = /(aif|wav|flac|mp3|m4a|aac|ogg)$/i
|
92
|
+
|
85
93
|
MIMEsource={
|
86
94
|
'application/atom+xml' => [:triplrFeed],
|
87
95
|
'application/markdown' => [:triplrMarkdown],
|
88
96
|
'application/org' => [:triplrOrg],
|
89
|
-
'application/rdf+xml' => [:
|
97
|
+
'application/rdf+xml' => [:triplrRDF,:rdfxml],
|
90
98
|
'application/json' => [:triplrJSON],
|
91
99
|
'application/pdf' => [:triplrPDF],
|
92
100
|
'application/textile' => [:triplrTextile],
|
@@ -95,51 +103,44 @@ class E
|
|
95
103
|
'audio/mp4' => [:triplrStdOut,'faad -i',Audio],
|
96
104
|
'audio/mpeg' => [:triplrStdOut,'id3info',Audio,/\((.*?)\)$/],
|
97
105
|
'audio' => [:triplrStdOut,'sndfile-info',Audio],
|
98
|
-
'
|
106
|
+
'inode/symlink' => [:triplrSymlink],
|
99
107
|
'message/rfc822' => [:triplrMail],
|
100
108
|
'text/ansi' => [:triplrANSI],
|
101
109
|
'text/comma-separated-values'=>[:triplrCSV,/,/],
|
102
|
-
'text/
|
103
|
-
'text/
|
110
|
+
'text/log' => [:triplrIRC],
|
111
|
+
'text/man' => [:triplrMan],
|
104
112
|
'text/nfo' => [:triplrHref,'cp437'],
|
105
|
-
'text/ntriples' => [:
|
113
|
+
'text/ntriples' => [:triplrRDF, :ntriples],
|
106
114
|
'text/plain' => [:triplrHref],
|
107
115
|
'text/rtf' => [:triplrRTF],
|
108
116
|
'text/semicolon-separated-values'=>[:triplrCSV,/;/],
|
109
117
|
'text/tab-separated-values'=>[:triplrCSV,/\t/],
|
110
|
-
'text/turtle' => [:
|
118
|
+
'text/turtle' => [:triplrRDF,:turtle],
|
111
119
|
}
|
112
120
|
|
113
|
-
#
|
114
|
-
Render='render/'
|
115
|
-
fn Render+'application/ld+json',->d,_=nil{E.renderRDF d, :jsonld}
|
116
|
-
fn Render+'application/rdf+xml',->d,_=nil{E.renderRDF d, :rdfxml}
|
117
|
-
fn Render+'text/ntriples',->d,_=nil{E.renderRDF d, :ntriples}
|
118
|
-
fn Render+'text/turtle', ->d,_=nil{E.renderRDF d, :turtle}
|
119
|
-
fn Render+'text/rdf+n3', ->d,_=nil{E.renderRDF d, :n3}
|
120
|
-
fn Render+'text/n3', ->d,_=nil{E.renderRDF d, :n3}
|
121
|
-
|
122
|
-
# render a view even if requested file exists
|
121
|
+
# prefer a view even if requested file exists
|
123
122
|
MIMEcook={
|
124
123
|
'application/atom+xml' => true,
|
125
124
|
'application/markdown' => true,
|
126
|
-
'application/json' => true,
|
127
125
|
'application/json+rdf' => true,
|
128
126
|
'application/org' => true,
|
129
127
|
'application/textile' => true,
|
128
|
+
'application/uri' => true,
|
130
129
|
'application/word' => true,
|
130
|
+
'inode/symlink' => true,
|
131
131
|
'message/rfc822'=> true,
|
132
132
|
'text/ansi'=>true,
|
133
133
|
'text/log'=>true,
|
134
|
+
'text/man'=>true,
|
134
135
|
'text/nfo'=>true,
|
135
136
|
'text/rtf'=>true,
|
136
137
|
}
|
137
|
-
|
138
|
+
|
139
|
+
%w{c c++ fortran haskell makefile pascal perl php python ruby}.map{|t|
|
138
140
|
%w{application/ text/x-}.map{|m|
|
139
141
|
MIMEcook[m+t] = true
|
140
142
|
}}
|
141
143
|
|
142
|
-
# short -> full URI
|
143
144
|
Abbrev={
|
144
145
|
"dc" => DC,
|
145
146
|
"foaf" => FOAF,
|
@@ -149,7 +150,7 @@ class E
|
|
149
150
|
"stat" => Stat,
|
150
151
|
}
|
151
152
|
|
152
|
-
#
|
153
|
+
# literal to pathname types
|
153
154
|
Literal={}
|
154
155
|
[Purl+'dc/elements/1.1/date',
|
155
156
|
Date,
|
@@ -157,41 +158,8 @@ class E
|
|
157
158
|
Modified,
|
158
159
|
].map{|f|Literal[f]=true}
|
159
160
|
|
160
|
-
def mime
|
161
|
-
@mime ||= (# dereferenced symlink
|
162
|
-
f = readlink
|
163
|
-
|
164
|
-
# filename extension
|
165
|
-
x = f.ext.downcase.to_sym
|
166
|
-
|
167
|
-
# directory?
|
168
|
-
if d?
|
169
|
-
"inode/directory"
|
170
|
-
# local MIME-types table
|
171
|
-
elsif MIME[x]
|
172
|
-
# puts "found mime for #{x} -> #{MIME[x]}"
|
173
|
-
MIME[x]
|
174
|
-
# Rack MIME-types table
|
175
|
-
elsif Rack::Mime::MIME_TYPES[t = '.' + x.to_s]
|
176
|
-
Rack::Mime::MIME_TYPES[t]
|
177
|
-
# procmail uses a prefix not an extension
|
178
|
-
elsif f.base.index('msg.')==0
|
179
|
-
"message/rfc822"
|
180
|
-
# ask FILE(1)
|
181
|
-
elsif f.e
|
182
|
-
`file --mime-type -b #{f.sh}`.chomp
|
183
|
-
# default
|
184
|
-
else
|
185
|
-
"application/octet-stream"
|
186
|
-
end)
|
187
|
-
end
|
188
|
-
|
189
161
|
def == u
|
190
162
|
to_s == u.to_s
|
191
163
|
end
|
192
164
|
|
193
|
-
Nginx = ENV['nginx']
|
194
|
-
Apache = ENV['apache']
|
195
|
-
Version = 'http://web.whats-your.name/www/'
|
196
|
-
|
197
165
|
end
|
data/infod/N.rb
CHANGED
@@ -1,39 +1,49 @@
|
|
1
1
|
%w{base64 cgi shellwords}.each{|r|require(r)}
|
2
2
|
|
3
3
|
def E e
|
4
|
-
return e if e.class == E
|
5
|
-
return e unless e
|
6
4
|
E.new e
|
7
5
|
end
|
8
6
|
|
9
7
|
class E
|
10
|
-
def E.[] u; E u end
|
11
|
-
def E e=uri; super e end
|
12
8
|
|
13
|
-
|
14
|
-
|
9
|
+
def E.[] u; u.E end
|
10
|
+
|
11
|
+
def E arg=nil
|
12
|
+
if arg
|
13
|
+
E.new arg
|
14
|
+
else
|
15
|
+
self
|
16
|
+
end
|
17
|
+
end
|
15
18
|
|
16
|
-
|
17
|
-
|
19
|
+
attr_reader :uri
|
20
|
+
|
21
|
+
def initialize uri
|
22
|
+
@uri = uri.to_s
|
18
23
|
end
|
19
24
|
|
20
|
-
def
|
21
|
-
|
22
|
-
rescue
|
23
|
-
base
|
25
|
+
def basename
|
26
|
+
File.basename path
|
24
27
|
end
|
28
|
+
alias_method :base, :basename
|
25
29
|
|
26
|
-
def
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
d.dirname.as d.bare}
|
30
|
+
def barename
|
31
|
+
basename.sub(/\.#{ext}$/,'')
|
32
|
+
rescue
|
33
|
+
basename
|
31
34
|
end
|
35
|
+
alias_method :bare, :barename
|
32
36
|
|
33
|
-
|
34
|
-
|
35
|
-
|
37
|
+
def ef; @ef ||= docBase.a('.e') end
|
38
|
+
def nt; @nt ||= docBase.a('.nt') end
|
39
|
+
def ttl; @ttl||= docBase.a('.ttl') end
|
36
40
|
|
41
|
+
def docBase
|
42
|
+
uri.split(/#/)[0].E.do{|d|
|
43
|
+
d.dirname.as d.bare }
|
44
|
+
end
|
45
|
+
|
46
|
+
# same as above, but w/ URI errors
|
37
47
|
def docBaseURI
|
38
48
|
u = URI uri
|
39
49
|
s = u.scheme
|
@@ -49,21 +59,50 @@ class E
|
|
49
59
|
uri.frag
|
50
60
|
end
|
51
61
|
|
52
|
-
def
|
53
|
-
(
|
54
|
-
|
55
|
-
|
62
|
+
def parent
|
63
|
+
E Pathname.new(uri).parent
|
64
|
+
end
|
65
|
+
|
66
|
+
def parents
|
67
|
+
parent.do{|p|
|
68
|
+
p.uri.match(/^[.\/]+$/) ? [p] : [p].concat(p.parents)}
|
69
|
+
end
|
70
|
+
|
71
|
+
def cascade
|
72
|
+
[self].concat parents
|
56
73
|
end
|
57
74
|
|
58
75
|
def dirname
|
59
|
-
|
76
|
+
n = node.dirname
|
77
|
+
n = '/' if n.to_s.size <= BaseLen
|
78
|
+
n.E
|
60
79
|
end
|
61
|
-
|
62
|
-
|
80
|
+
alias_method :dir, :dirname
|
81
|
+
|
82
|
+
# local URL from unlocatable identifier (mail MSGID, etc)
|
63
83
|
def url
|
64
84
|
path? ? uri : Prefix + (CGI.escape uri)
|
65
|
-
|
66
|
-
|
85
|
+
end
|
86
|
+
|
87
|
+
# local URL even if locatable-identifier
|
88
|
+
def localURL e
|
89
|
+
# path
|
90
|
+
if uri.index('/') == 0
|
91
|
+
uri
|
92
|
+
# host match
|
93
|
+
elsif uri.index('http://'+e['SERVER_NAME']+'/') == 0
|
94
|
+
pathSegment.uri
|
95
|
+
# non-local
|
96
|
+
else
|
97
|
+
Prefix + (CGI.escape uri)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def pathSegment
|
102
|
+
m = uri.match(/^([a-z]+:\/\/[^\/]+)?(\/.*)/)
|
103
|
+
m && m[2] && m[2].E || nil
|
104
|
+
end
|
105
|
+
|
67
106
|
# URI extension :: E -> string
|
68
107
|
def ext
|
69
108
|
File.extname(uri).tail||''
|
@@ -77,84 +116,115 @@ class E
|
|
77
116
|
uri.expand.E
|
78
117
|
end
|
79
118
|
|
80
|
-
|
81
|
-
|
82
|
-
def s b
|
83
|
-
u.a E(b).path
|
119
|
+
def prependURI u
|
120
|
+
E u.to_s + uri
|
84
121
|
end
|
85
122
|
|
86
|
-
def
|
87
|
-
|
123
|
+
def appendURI u
|
124
|
+
E uri + u.to_s
|
88
125
|
end
|
89
126
|
|
90
|
-
def
|
91
|
-
|
127
|
+
def appendSlashURI u
|
128
|
+
E uri.t + u.to_s
|
92
129
|
end
|
93
|
-
alias_method :a, :appendURI
|
94
|
-
alias_method :+, :appendURI
|
95
130
|
|
96
|
-
def
|
97
|
-
|
131
|
+
def concatURI b
|
132
|
+
u.appendURI b.E.path
|
98
133
|
end
|
134
|
+
|
135
|
+
alias_method :a, :appendURI
|
136
|
+
alias_method :+, :appendURI
|
99
137
|
alias_method :as, :appendSlashURI
|
100
138
|
|
101
|
-
# path? :: E -> Bool
|
102
139
|
def path?
|
103
140
|
uri.path?
|
104
141
|
end
|
105
142
|
|
106
|
-
#
|
143
|
+
# URI -> path
|
107
144
|
def path
|
108
145
|
@path ||=
|
109
|
-
|
110
|
-
|
111
|
-
|
146
|
+
(if path?
|
147
|
+
if uri.match /^\//
|
148
|
+
uri
|
149
|
+
else
|
150
|
+
'/' + uri
|
151
|
+
end
|
152
|
+
else
|
153
|
+
'/E/' + uri.h.dive[0..5] + (Base64.urlsafe_encode64 uri)
|
154
|
+
end)
|
112
155
|
end
|
113
156
|
|
114
157
|
def u
|
115
|
-
|
158
|
+
# data-storage path for resource
|
159
|
+
@u ||= E (f ? dirname + '/.' + (File.basename path) : path.t + '._')
|
116
160
|
end
|
117
161
|
|
118
|
-
#
|
119
|
-
def
|
120
|
-
uri.split
|
162
|
+
# (_ _ o) -> o
|
163
|
+
def innerPath
|
164
|
+
(uri.split S)[-1].unpath
|
121
165
|
end
|
166
|
+
alias_method :ro, :innerPath
|
122
167
|
|
123
168
|
def sh
|
124
169
|
d.force_encoding('UTF-8').sh
|
125
170
|
end
|
126
171
|
|
127
|
-
#
|
172
|
+
# literals to URIs
|
173
|
+
|
174
|
+
def E.literal o
|
175
|
+
E['/'].literal o
|
176
|
+
end
|
177
|
+
|
128
178
|
def literal o
|
179
|
+
|
180
|
+
# already a URI
|
181
|
+
return self if o.class == E
|
182
|
+
|
183
|
+
# blob for non-strings
|
129
184
|
return literalBlob o unless o.class == String
|
185
|
+
|
186
|
+
# whitelisted predicateURIs to paths
|
130
187
|
return literalURI o if (Literal[uri] || o.size<=88) && !o.match(/\//)
|
188
|
+
|
189
|
+
# string matches URI format
|
131
190
|
return E o if o.match %r{\A[a-z]+://[^\s]+\Z}
|
191
|
+
|
192
|
+
# blob
|
132
193
|
literalBlob o
|
194
|
+
|
133
195
|
end
|
134
196
|
|
135
197
|
# pathname for short literals
|
136
198
|
def literalURI o
|
137
|
-
E "/
|
199
|
+
E "/l/"+(Literal[uri] && o.gsub(/[\.:\-T+]/,'/'))+'/'+o
|
138
200
|
end
|
139
201
|
|
140
202
|
def literalBlobURI o
|
141
203
|
if o.class == String
|
142
|
-
E "/blob/"+o.h.dive
|
204
|
+
E "/E/blob/"+o.h.dive
|
143
205
|
else
|
144
|
-
E "/json/"+[o].to_json.h.dive
|
206
|
+
E "/E/json/"+[o].to_json.h.dive
|
145
207
|
end
|
146
208
|
end
|
147
209
|
|
210
|
+
def literalBlob o
|
211
|
+
u = literalBlobURI o
|
212
|
+
u.w o, !o.class == String unless u.f
|
213
|
+
end
|
214
|
+
|
148
215
|
# spaceship
|
149
216
|
def <=> c
|
150
217
|
to_s <=> c.to_s
|
151
218
|
end
|
152
219
|
|
153
|
-
|
154
|
-
def to_s # string
|
220
|
+
def to_s
|
155
221
|
uri
|
156
222
|
end
|
157
223
|
|
224
|
+
def to_h
|
225
|
+
{'uri' => uri}
|
226
|
+
end
|
227
|
+
|
158
228
|
end
|
159
229
|
|
160
230
|
class Hash
|
@@ -199,34 +269,41 @@ class String
|
|
199
269
|
Shellwords.escape self
|
200
270
|
end
|
201
271
|
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
self[BaseLen..-1].unpath r
|
272
|
+
def unpathFs
|
273
|
+
self[E::BaseLen..-1].do{|p|
|
274
|
+
(p.match(/^\/([a-z]+:)\/+(.*)/).do{|m|m[1]+'//'+m[2]}||p).E}
|
206
275
|
end
|
207
276
|
|
208
|
-
#
|
209
|
-
def unpath
|
277
|
+
# path -> URI || literal
|
278
|
+
def unpath
|
210
279
|
|
211
|
-
|
212
|
-
|
280
|
+
# URI with scheme
|
281
|
+
if m = (match /^\/([a-z]+:)\/+(.*)/)
|
282
|
+
(m[1] + '//' + m[2]).E
|
213
283
|
|
214
|
-
|
215
|
-
|
284
|
+
# String literal in store
|
285
|
+
elsif match /^\/E\/blob/
|
286
|
+
self.E.r
|
216
287
|
|
217
|
-
|
218
|
-
|
288
|
+
# JSON literal in store
|
289
|
+
elsif match /^\/E\/json/
|
290
|
+
self.E.r true
|
219
291
|
|
220
|
-
|
221
|
-
|
292
|
+
# String literal in basename
|
293
|
+
elsif match /^\/l\//
|
294
|
+
File.basename self
|
222
295
|
|
223
|
-
|
224
|
-
|
296
|
+
# URI (opaque)
|
297
|
+
elsif match /^\/E\/..\//
|
298
|
+
self[9..-1].match(/([^.]+)(.*)/).do{|c|
|
225
299
|
(Base64.urlsafe_decode64 c[1]) + c[2]
|
226
300
|
}.E
|
227
|
-
|
228
|
-
|
301
|
+
|
302
|
+
# path
|
303
|
+
else
|
304
|
+
self.E
|
229
305
|
end
|
306
|
+
|
230
307
|
end
|
231
308
|
|
232
309
|
def E
|