infod 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|