haveapi-fs 0.1.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.
- checksums.yaml +7 -0
- data/.yardopts +1 -0
- data/CHANGELOG +2 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +21 -0
- data/README.md +338 -0
- data/Rakefile +1 -0
- data/assets/css/bootstrap.min.css +6 -0
- data/assets/css/local.css +11 -0
- data/bin/haveapi-fs +5 -0
- data/haveapi-fs.gemspec +30 -0
- data/lib/core_ext/string.rb +9 -0
- data/lib/haveapi/fs/auth/base.rb +56 -0
- data/lib/haveapi/fs/auth/basic.rb +29 -0
- data/lib/haveapi/fs/auth/noauth.rb +9 -0
- data/lib/haveapi/fs/auth/token.rb +39 -0
- data/lib/haveapi/fs/cache.rb +71 -0
- data/lib/haveapi/fs/cleaner.rb +56 -0
- data/lib/haveapi/fs/component.rb +237 -0
- data/lib/haveapi/fs/components/action_dir.rb +106 -0
- data/lib/haveapi/fs/components/action_errors.rb +49 -0
- data/lib/haveapi/fs/components/action_exec.rb +12 -0
- data/lib/haveapi/fs/components/action_exec_edit.rb +90 -0
- data/lib/haveapi/fs/components/action_input.rb +40 -0
- data/lib/haveapi/fs/components/action_message.rb +19 -0
- data/lib/haveapi/fs/components/action_output.rb +79 -0
- data/lib/haveapi/fs/components/action_status.rb +32 -0
- data/lib/haveapi/fs/components/cache_stats.rb +19 -0
- data/lib/haveapi/fs/components/component_list.rb +24 -0
- data/lib/haveapi/fs/components/create_action_dir.rb +15 -0
- data/lib/haveapi/fs/components/delete_action_dir.rb +22 -0
- data/lib/haveapi/fs/components/directory.rb +45 -0
- data/lib/haveapi/fs/components/directory_reset.rb +8 -0
- data/lib/haveapi/fs/components/executable.rb +75 -0
- data/lib/haveapi/fs/components/file.rb +43 -0
- data/lib/haveapi/fs/components/groff_help_file.rb +9 -0
- data/lib/haveapi/fs/components/help_file.rb +28 -0
- data/lib/haveapi/fs/components/html_help_file.rb +24 -0
- data/lib/haveapi/fs/components/index_filter.rb +63 -0
- data/lib/haveapi/fs/components/info_files.rb +19 -0
- data/lib/haveapi/fs/components/instance_create.rb +20 -0
- data/lib/haveapi/fs/components/instance_edit.rb +49 -0
- data/lib/haveapi/fs/components/list_item.rb +28 -0
- data/lib/haveapi/fs/components/md_help_file.rb +24 -0
- data/lib/haveapi/fs/components/meta_dir.rb +42 -0
- data/lib/haveapi/fs/components/meta_file.rb +21 -0
- data/lib/haveapi/fs/components/parameter.rb +132 -0
- data/lib/haveapi/fs/components/pry.rb +9 -0
- data/lib/haveapi/fs/components/remote_control_file.rb +92 -0
- data/lib/haveapi/fs/components/resource_action_dir.rb +72 -0
- data/lib/haveapi/fs/components/resource_dir.rb +161 -0
- data/lib/haveapi/fs/components/resource_id.rb +15 -0
- data/lib/haveapi/fs/components/resource_instance_dir.rb +146 -0
- data/lib/haveapi/fs/components/rfuse_check.rb +3 -0
- data/lib/haveapi/fs/components/root.rb +75 -0
- data/lib/haveapi/fs/components/save_instance.rb +11 -0
- data/lib/haveapi/fs/components/unsaved_list.rb +24 -0
- data/lib/haveapi/fs/components/update_action_dir.rb +31 -0
- data/lib/haveapi/fs/context.rb +43 -0
- data/lib/haveapi/fs/exceptions.rb +0 -0
- data/lib/haveapi/fs/factory.rb +59 -0
- data/lib/haveapi/fs/fs.rb +198 -0
- data/lib/haveapi/fs/help.rb +91 -0
- data/lib/haveapi/fs/main.rb +134 -0
- data/lib/haveapi/fs/remote_control.rb +29 -0
- data/lib/haveapi/fs/version.rb +5 -0
- data/lib/haveapi/fs/worker.rb +77 -0
- data/lib/haveapi/fs.rb +65 -0
- data/templates/help/html/action_dir.erb +33 -0
- data/templates/help/html/action_errors.erb +4 -0
- data/templates/help/html/action_input.erb +40 -0
- data/templates/help/html/action_output.erb +21 -0
- data/templates/help/html/index_filter.erb +16 -0
- data/templates/help/html/layout.erb +45 -0
- data/templates/help/html/resource_action_dir.erb +18 -0
- data/templates/help/html/resource_dir.erb +18 -0
- data/templates/help/html/resource_instance_dir.erb +64 -0
- data/templates/help/html/root.erb +42 -0
- data/templates/help/md/action_dir.erb +29 -0
- data/templates/help/md/action_errors.erb +2 -0
- data/templates/help/md/action_input.erb +23 -0
- data/templates/help/md/action_output.erb +11 -0
- data/templates/help/md/index_filter.erb +11 -0
- data/templates/help/md/layout.erb +14 -0
- data/templates/help/md/resource_action_dir.erb +10 -0
- data/templates/help/md/resource_dir.erb +15 -0
- data/templates/help/md/resource_instance_dir.erb +42 -0
- data/templates/help/md/root.erb +34 -0
- metadata +231 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module HaveAPI::Fs::Components
|
|
2
|
+
class DeleteActionDir < ActionDir
|
|
3
|
+
help_file :action_dir
|
|
4
|
+
|
|
5
|
+
def exec
|
|
6
|
+
ret = super
|
|
7
|
+
|
|
8
|
+
if ret.is_a?(HaveAPI::Client::Response) && ret.ok?
|
|
9
|
+
if @resource.is_a?(HaveAPI::Client::ResourceInstance)
|
|
10
|
+
id = @resource.id
|
|
11
|
+
|
|
12
|
+
else
|
|
13
|
+
id = @resource.prepared_args.last
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
context[:resource_dir].delete(id)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
ret
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module HaveAPI::Fs::Components
|
|
2
|
+
# Base class for all components that act as directories.
|
|
3
|
+
#
|
|
4
|
+
# Every directory contains some special hidden files:
|
|
5
|
+
#
|
|
6
|
+
# - `.components` contains a list of all descendant component objects that are
|
|
7
|
+
# created in memory
|
|
8
|
+
# - `.pry` is an executable that opens a developer console
|
|
9
|
+
class Directory < HaveAPI::Fs::Component
|
|
10
|
+
include HaveAPI::Fs::Help
|
|
11
|
+
|
|
12
|
+
def directory?
|
|
13
|
+
true
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def contents
|
|
17
|
+
help_contents + %w(.reset .unsaved)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
protected
|
|
21
|
+
def new_child(name)
|
|
22
|
+
return help_file(name) if help_file?(name)
|
|
23
|
+
|
|
24
|
+
case name
|
|
25
|
+
when HaveAPI::Fs::Fs::CHECK_FILE
|
|
26
|
+
RFuseCheck
|
|
27
|
+
|
|
28
|
+
when :'.reset'
|
|
29
|
+
DirectoryReset
|
|
30
|
+
|
|
31
|
+
when :'.unsaved'
|
|
32
|
+
UnsavedList
|
|
33
|
+
|
|
34
|
+
when :'.components'
|
|
35
|
+
ComponentList
|
|
36
|
+
|
|
37
|
+
when :'.pry'
|
|
38
|
+
HaveAPI::Fs::Components::Pry
|
|
39
|
+
|
|
40
|
+
else
|
|
41
|
+
nil
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
module HaveAPI::Fs::Components
|
|
2
|
+
# Base class for all executables. Executables can be executed either by
|
|
3
|
+
# writing `1` into them or by running them, as they contain a Ruby script.
|
|
4
|
+
#
|
|
5
|
+
# The Ruby script communicates with the file system using {RemoteControlFile}.
|
|
6
|
+
# In short, it tells the file system to execute a component at a certain path,
|
|
7
|
+
# which results in the same action as when `1` is written to the file.
|
|
8
|
+
#
|
|
9
|
+
# In both cases, the file system itself does the operation, the outer process
|
|
10
|
+
# only signals it to do so and then waits for a reply.
|
|
11
|
+
#
|
|
12
|
+
# When the component is to be executed, method {#exec} is called.
|
|
13
|
+
class Executable < File
|
|
14
|
+
def executable?
|
|
15
|
+
true
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def writable?
|
|
19
|
+
true
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def read
|
|
23
|
+
abs_path = ::File.join(context.mountpoint, path)
|
|
24
|
+
|
|
25
|
+
<<END
|
|
26
|
+
#!#{RbConfig.ruby}
|
|
27
|
+
#
|
|
28
|
+
# This action can be executed either by running this file or by writing "1" to
|
|
29
|
+
# it, e.g.:
|
|
30
|
+
#
|
|
31
|
+
# .#{abs_path}
|
|
32
|
+
#
|
|
33
|
+
# or
|
|
34
|
+
#
|
|
35
|
+
# echo 1 > #{abs_path}
|
|
36
|
+
#
|
|
37
|
+
require 'yaml'
|
|
38
|
+
|
|
39
|
+
f = ::File.open(
|
|
40
|
+
'#{::File.join(context.mountpoint, '.remote_control')}',
|
|
41
|
+
'w+'
|
|
42
|
+
)
|
|
43
|
+
f.write(YAML.dump({
|
|
44
|
+
action: :execute,
|
|
45
|
+
path: '/#{path}',
|
|
46
|
+
}))
|
|
47
|
+
f.write(#{RemoteControlFile::MSG_DELIMITER.dump})
|
|
48
|
+
f.flush
|
|
49
|
+
f.seek(0)
|
|
50
|
+
|
|
51
|
+
ret = YAML.load(f.read)
|
|
52
|
+
f.close
|
|
53
|
+
|
|
54
|
+
unless ret[:status]
|
|
55
|
+
warn "Action failed: \#{ret[:message]}"
|
|
56
|
+
if ret[:errors]
|
|
57
|
+
ret[:errors].each do |k, v|
|
|
58
|
+
warn " \#{k}: \#{v.join('; ')}"
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
exit(ret[:status])
|
|
64
|
+
END
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def write(str)
|
|
68
|
+
exec if str.strip == '1'
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def exec
|
|
72
|
+
raise NotImplementedError
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module HaveAPI::Fs::Components
|
|
2
|
+
class File < HaveAPI::Fs::Component
|
|
3
|
+
def file?
|
|
4
|
+
true
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def size
|
|
8
|
+
read.length
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def read
|
|
12
|
+
raise NotImplementedError
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def write(str)
|
|
16
|
+
raise NotImplementedError
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def raw_open(path, mode, rfusefs = nil)
|
|
20
|
+
nil
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def raw_read(path, offset, size, raw = nil)
|
|
24
|
+
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def raw_write(path, offset, size, buf, raw = nil)
|
|
28
|
+
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def raw_sync(path, datasync, raw = nil)
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def raw_truncate(path, offset, raw= nil)
|
|
36
|
+
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def raw_close(path, raw = nil)
|
|
40
|
+
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'erb'
|
|
2
|
+
|
|
3
|
+
module HaveAPI::Fs::Components
|
|
4
|
+
class HelpFile < File
|
|
5
|
+
def initialize(component, format)
|
|
6
|
+
super()
|
|
7
|
+
@component = @c = component
|
|
8
|
+
@context = component.context
|
|
9
|
+
@format = format
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
protected
|
|
13
|
+
def template_path(klass)
|
|
14
|
+
if klass.is_a?(::String)
|
|
15
|
+
name = klass
|
|
16
|
+
|
|
17
|
+
else
|
|
18
|
+
name = klass.help_file ? klass.help_file.to_s : klass.name.split('::').last.underscore
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
HaveAPI::Fs::Help.find!(::File.join(@format.to_s, name + ".erb"))
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def layout(layout_erb)
|
|
25
|
+
layout_erb.result(binding { yield })
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module HaveAPI::Fs::Components
|
|
2
|
+
class HtmlHelpFile < HelpFile
|
|
3
|
+
def initialize(*args)
|
|
4
|
+
super
|
|
5
|
+
|
|
6
|
+
@layout = ERB.new(::File.open(template_path('layout')).read, 0, '-')
|
|
7
|
+
@template = ERB.new(
|
|
8
|
+
::File.open(template_path(@c.class)).read,
|
|
9
|
+
0, '-'
|
|
10
|
+
)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def read
|
|
14
|
+
layout(@layout) do
|
|
15
|
+
@template.result(binding)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
protected
|
|
20
|
+
def asset(path)
|
|
21
|
+
::File.join(@context.mountpoint, '.assets', path)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
module HaveAPI::Fs::Components
|
|
2
|
+
class IndexFilter < Directory
|
|
3
|
+
component :index_filter
|
|
4
|
+
attr_reader :resource_dir, :param, :filters
|
|
5
|
+
|
|
6
|
+
def initialize(resource_dir, param, filters = {})
|
|
7
|
+
super()
|
|
8
|
+
|
|
9
|
+
@resource_dir = resource_dir
|
|
10
|
+
@param = param
|
|
11
|
+
@filters = filters
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def title
|
|
15
|
+
"Filter by #{@param}"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
protected
|
|
19
|
+
def new_child(value)
|
|
20
|
+
if child = super
|
|
21
|
+
child
|
|
22
|
+
|
|
23
|
+
else
|
|
24
|
+
f = @filters.clone
|
|
25
|
+
f[ @param ] = value.to_s
|
|
26
|
+
[IndexFilterValue, @resource_dir.resource, f]
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class IndexFilterValue < ResourceDir
|
|
32
|
+
component :resource_dir
|
|
33
|
+
help_file :resource_dir
|
|
34
|
+
|
|
35
|
+
def initialize(resource, filters)
|
|
36
|
+
super(resource)
|
|
37
|
+
|
|
38
|
+
@filters = filters
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def setup
|
|
42
|
+
super
|
|
43
|
+
|
|
44
|
+
@filters.each do |k, v|
|
|
45
|
+
@index.find(:input).find(k).write(v)
|
|
46
|
+
@last = v
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def title
|
|
51
|
+
@last.to_s
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
protected
|
|
55
|
+
def new_child(name)
|
|
56
|
+
child = super(name)
|
|
57
|
+
return child unless child
|
|
58
|
+
|
|
59
|
+
child << @filters.clone if [child].flatten.first == IndexFilter
|
|
60
|
+
child
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module HaveAPI::Fs::Components
|
|
2
|
+
class ClientVersion < File
|
|
3
|
+
def read
|
|
4
|
+
HaveAPI::Client::VERSION + "\n"
|
|
5
|
+
end
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
class FsVersion < File
|
|
9
|
+
def read
|
|
10
|
+
HaveAPI::Fs::VERSION + "\n"
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class ProtocolVersion < File
|
|
15
|
+
def read
|
|
16
|
+
HaveAPI::Client::PROTOCOL_VERSION + "\n"
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'yaml'
|
|
2
|
+
|
|
3
|
+
module HaveAPI::Fs::Components
|
|
4
|
+
class InstanceCreate < ActionExecEdit
|
|
5
|
+
def header
|
|
6
|
+
<<END
|
|
7
|
+
# This file is in YAML format. Lines beginning with a hash (#) are comments and
|
|
8
|
+
# are ignored. The new resource instance will be created once this file is saved
|
|
9
|
+
# and closed. The success of this operation can be later checked in
|
|
10
|
+
# actions/create/status.
|
|
11
|
+
#
|
|
12
|
+
# Only required parameters that need to be set are uncommented by default.
|
|
13
|
+
# Parameters that are not specified when this file is closed will not be sent
|
|
14
|
+
# to the API.
|
|
15
|
+
#
|
|
16
|
+
# To cancel the operation, either do not save the file or save it empty.
|
|
17
|
+
END
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require 'yaml'
|
|
2
|
+
|
|
3
|
+
module HaveAPI::Fs::Components
|
|
4
|
+
class InstanceEdit < ActionExecEdit
|
|
5
|
+
def header
|
|
6
|
+
<<END
|
|
7
|
+
# This file is in YAML format. Lines beginning with a hash (#) are comments and
|
|
8
|
+
# are ignored. The resource instance will be updated once this file is saved
|
|
9
|
+
# and closed. The success of this operation can be later checked in
|
|
10
|
+
# actions/update/status.
|
|
11
|
+
#
|
|
12
|
+
# To avoid updating a parameter, simply comment or delete it from this file.
|
|
13
|
+
# Values of parameters that are not present when the file is closed are not
|
|
14
|
+
# changed.
|
|
15
|
+
#
|
|
16
|
+
# To cancel the update, either do not save the file or save it empty.
|
|
17
|
+
END
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def read
|
|
21
|
+
ret = header + "\n"
|
|
22
|
+
instance_dir = context[:resource_instance_dir]
|
|
23
|
+
|
|
24
|
+
@action_dir.action.input_params.each do |name, p|
|
|
25
|
+
if p[:type] == 'Resource'
|
|
26
|
+
v = instance_dir.resource.attributes[name][ p[:value_id].to_sym ]
|
|
27
|
+
|
|
28
|
+
else
|
|
29
|
+
v = instance_dir.resource.attributes[name]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
ret += "# #{p[:label]}; #{p[:type]}\n"
|
|
33
|
+
ret += "# #{p[:description]}\n"
|
|
34
|
+
ret += "# Defaults to '#{p[:default]}'\n" unless p[:default].nil?
|
|
35
|
+
ret += "##{name}: #{v}\n\n"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
ret
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def save?(data)
|
|
42
|
+
data.any?
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def save
|
|
46
|
+
context[:resource_instance_dir].save
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module HaveAPI::Fs::Components
|
|
2
|
+
class ListItem < Directory
|
|
3
|
+
component :list_item
|
|
4
|
+
|
|
5
|
+
def initialize(action, dir, data)
|
|
6
|
+
super()
|
|
7
|
+
|
|
8
|
+
@action = action
|
|
9
|
+
@dir = dir
|
|
10
|
+
@data = data
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def contents
|
|
14
|
+
@action.params.keys.map(&:to_s)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
protected
|
|
18
|
+
def new_child(name)
|
|
19
|
+
[
|
|
20
|
+
Parameter,
|
|
21
|
+
@action,
|
|
22
|
+
name,
|
|
23
|
+
@dir,
|
|
24
|
+
@data,
|
|
25
|
+
]
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module HaveAPI::Fs::Components
|
|
2
|
+
class MdHelpFile < HelpFile
|
|
3
|
+
def initialize(*args)
|
|
4
|
+
super
|
|
5
|
+
|
|
6
|
+
@layout = ERB.new(::File.open(template_path('layout')).read, 0, '-')
|
|
7
|
+
@template = ERB.new(
|
|
8
|
+
::File.open(template_path(@c.class)).read,
|
|
9
|
+
0, '-'
|
|
10
|
+
)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def read
|
|
14
|
+
layout(@layout) do
|
|
15
|
+
@template.result(binding)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
protected
|
|
20
|
+
def safe_print(str)
|
|
21
|
+
str.to_s.gsub('_', '\_')
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
module HaveAPI::Fs::Components
|
|
2
|
+
class MetaDir < Directory
|
|
3
|
+
def initialize(path)
|
|
4
|
+
super()
|
|
5
|
+
@path = path
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def setup
|
|
9
|
+
super
|
|
10
|
+
|
|
11
|
+
@dir = ::Dir.new(@path)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def contents
|
|
15
|
+
@dir.entries[2..-1]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def times
|
|
19
|
+
st = ::File.stat(@path)
|
|
20
|
+
[st.atime, st.mtime, st.ctime]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
protected
|
|
24
|
+
def new_child(name)
|
|
25
|
+
if child = super
|
|
26
|
+
return child
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
real_name = name.to_s
|
|
30
|
+
return unless contents.include?(real_name)
|
|
31
|
+
|
|
32
|
+
path = ::File.join(@dir.path, real_name)
|
|
33
|
+
|
|
34
|
+
if ::File.directory?(path)
|
|
35
|
+
[MetaDir, path]
|
|
36
|
+
|
|
37
|
+
else
|
|
38
|
+
[MetaFile, path]
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module HaveAPI::Fs::Components
|
|
2
|
+
class MetaFile < File
|
|
3
|
+
def initialize(path)
|
|
4
|
+
super()
|
|
5
|
+
@path = path
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def times
|
|
9
|
+
st = ::File.stat(@path)
|
|
10
|
+
[st.atime, st.mtime, st.ctime]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def size
|
|
14
|
+
::File.size(@path)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def read
|
|
18
|
+
::File.read(@path)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
require 'time'
|
|
2
|
+
|
|
3
|
+
module HaveAPI::Fs::Components
|
|
4
|
+
class Parameter < File
|
|
5
|
+
attr_reader :new_value
|
|
6
|
+
|
|
7
|
+
def initialize(action, name, dir, value = nil, opts = {})
|
|
8
|
+
super()
|
|
9
|
+
|
|
10
|
+
@action = action
|
|
11
|
+
@name = name
|
|
12
|
+
@dir = dir
|
|
13
|
+
@value = value
|
|
14
|
+
@set = false
|
|
15
|
+
@mirror = opts[:mirror]
|
|
16
|
+
|
|
17
|
+
if dir == :input
|
|
18
|
+
@params = @action.input_params
|
|
19
|
+
|
|
20
|
+
else
|
|
21
|
+
@params = @action.params
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
@desc = @params[@name]
|
|
25
|
+
|
|
26
|
+
if opts[:editable].nil?
|
|
27
|
+
@writable = dir == :input
|
|
28
|
+
|
|
29
|
+
else
|
|
30
|
+
@writable = opts[:editable]
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def writable?
|
|
35
|
+
@writable
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def read
|
|
39
|
+
str = value.to_s
|
|
40
|
+
str.empty? ? str : str + "\n"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def write(raw)
|
|
44
|
+
@set = true
|
|
45
|
+
str = raw.strip
|
|
46
|
+
|
|
47
|
+
if str.empty?
|
|
48
|
+
@new_value = nil
|
|
49
|
+
@mirror.write_safe(@new_value) if @mirror
|
|
50
|
+
return
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
@new_value = case @desc[:type]
|
|
54
|
+
when 'Resource'
|
|
55
|
+
str.to_i
|
|
56
|
+
|
|
57
|
+
when 'Boolean'
|
|
58
|
+
HaveAPI::Client::Parameters::Typed.Boolean.to_b(str)
|
|
59
|
+
|
|
60
|
+
when 'Integer'
|
|
61
|
+
str.to_i
|
|
62
|
+
|
|
63
|
+
when 'Float'
|
|
64
|
+
str.to_f
|
|
65
|
+
|
|
66
|
+
when 'Datetime'
|
|
67
|
+
Time.iso8601(str)
|
|
68
|
+
|
|
69
|
+
else
|
|
70
|
+
str.strip
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
changed
|
|
74
|
+
@mirror.write_safe(@new_value) if @mirror
|
|
75
|
+
|
|
76
|
+
rescue => e
|
|
77
|
+
@set = false
|
|
78
|
+
raise e
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def write_safe(v)
|
|
82
|
+
@new_value = v
|
|
83
|
+
@set = true
|
|
84
|
+
changed
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def value
|
|
88
|
+
# Value in ResourceInstance
|
|
89
|
+
# Value in hash
|
|
90
|
+
# Value changed, saved in instance variable
|
|
91
|
+
|
|
92
|
+
hash = @value.is_a?(::Hash)
|
|
93
|
+
|
|
94
|
+
if @desc[:type] == 'Resource'
|
|
95
|
+
return @new_value if @new_value
|
|
96
|
+
return nil if @value.nil?
|
|
97
|
+
return nil if @value.attributes[@name].nil?
|
|
98
|
+
@value.attributes[@name][@desc[:value_id].to_sym]
|
|
99
|
+
|
|
100
|
+
else
|
|
101
|
+
if @new_value
|
|
102
|
+
v = @new_value
|
|
103
|
+
|
|
104
|
+
else
|
|
105
|
+
return nil if @value.nil?
|
|
106
|
+
|
|
107
|
+
v = hash ? @value[@name] : @value.send(@name)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
case @desc[:type]
|
|
111
|
+
when 'Boolean'
|
|
112
|
+
v ? 1 : 0
|
|
113
|
+
|
|
114
|
+
when 'Datetime'
|
|
115
|
+
v.is_a?(::Time) ? v.iso8601 : v
|
|
116
|
+
|
|
117
|
+
else
|
|
118
|
+
v
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def set?
|
|
125
|
+
@set
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def unsaved?(n = nil)
|
|
129
|
+
set?
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|