fernyb_davclient 0.0.9
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/LICENSE +53 -0
- data/Manifest +38 -0
- data/README.rdoc +134 -0
- data/Rakefile +95 -0
- data/bin/dav +6 -0
- data/examples/clean_files.rb +131 -0
- data/examples/meta_tags_in_use.rb +64 -0
- data/examples/remove_ds_store.rb +15 -0
- data/examples/scrape_site.rb +36 -0
- data/examples/simple_find.rb +10 -0
- data/fernyb_davclient.gemspec +35 -0
- data/lib/davclient.rb +513 -0
- data/lib/davclient/curl_commands.rb +70 -0
- data/lib/davclient/dav-ls.rb +168 -0
- data/lib/davclient/dav-propfind.rb +92 -0
- data/lib/davclient/dav-put.rb +137 -0
- data/lib/davclient/davcli.rb +286 -0
- data/lib/davclient/hpricot_extensions.rb +149 -0
- data/lib/davclient/simple.rb +44 -0
- data/lib/davclient/termutil.rb +55 -0
- data/lib/davclient/util.rb +256 -0
- data/tests/dav.rb +12 -0
- data/tests/tc_dav-cat.rb +34 -0
- data/tests/tc_dav-cd.rb +45 -0
- data/tests/tc_dav-cp.rb +51 -0
- data/tests/tc_dav-delete.rb +37 -0
- data/tests/tc_dav-get.rb +63 -0
- data/tests/tc_dav-ls.rb +45 -0
- data/tests/tc_dav-mkcol.rb +64 -0
- data/tests/tc_dav-mv.rb +65 -0
- data/tests/tc_dav-propfind.rb +40 -0
- data/tests/tc_dav-put.rb +132 -0
- data/tests/tc_util.rb +39 -0
- data/tests/tc_webdav_basic.rb +86 -0
- data/tests/tc_webdav_publish.rb +63 -0
- data/tests/test_helper.rb +2 -0
- data/tests/ts_davclient.rb +12 -0
- data/todo +32 -0
- metadata +118 -0
@@ -0,0 +1,70 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
#
|
4
|
+
# Templates for curl commands
|
5
|
+
#
|
6
|
+
|
7
|
+
# Used to improve readability of curl commands that always
|
8
|
+
# needs to be on one line
|
9
|
+
def remove_newlines(string)
|
10
|
+
string.gsub("\n","").gsub(/ +/," ") + " "
|
11
|
+
end
|
12
|
+
|
13
|
+
# Templates for curl commands:
|
14
|
+
curl_propfind_cmd = <<EOF
|
15
|
+
--request PROPFIND
|
16
|
+
--max-redirs 1
|
17
|
+
--header 'Content-Type: text/xml; charset="utf-8"'
|
18
|
+
--header "Depth: 1"
|
19
|
+
--data-ascii '<?xml version="1.0" encoding="utf-8"?>
|
20
|
+
<DAV:propfind xmlns:DAV="DAV:"><DAV:allprop/></DAV:propfind>'
|
21
|
+
EOF
|
22
|
+
CURL_PROPFIND = remove_newlines(curl_propfind_cmd)
|
23
|
+
|
24
|
+
curl_proppatch_cmd = <<EOF
|
25
|
+
--request PROPPATCH
|
26
|
+
--header 'Content-Type: text/xml; charset="utf-8"'
|
27
|
+
--header "Depth: 1"
|
28
|
+
--data-ascii '<?xml version="1.0"?>
|
29
|
+
<d:propertyupdate xmlns:d="DAV:" xmlns:v="vrtx">
|
30
|
+
<d:set>
|
31
|
+
<d:prop>
|
32
|
+
<!--property-and-value-->
|
33
|
+
</d:prop>
|
34
|
+
</d:set>
|
35
|
+
</d:propertyupdate>'
|
36
|
+
EOF
|
37
|
+
CURL_PROPPATCH = remove_newlines(curl_proppatch_cmd)
|
38
|
+
|
39
|
+
curl_delete_cmd = <<EOF
|
40
|
+
--request DELETE
|
41
|
+
--header 'Content-Type: text/xml; charset="utf-8"'
|
42
|
+
EOF
|
43
|
+
CURL_DELETE = remove_newlines(curl_delete_cmd)
|
44
|
+
|
45
|
+
curl_mkcol_cmd = <<EOF
|
46
|
+
--request MKCOL
|
47
|
+
--header 'Content-Type: text/xml; charset="utf-8"'
|
48
|
+
EOF
|
49
|
+
CURL_MKCOL = remove_newlines(curl_mkcol_cmd)
|
50
|
+
|
51
|
+
CURL_OPTIONS = "-i -X OPTIONS "
|
52
|
+
|
53
|
+
curl_copy = <<EOF
|
54
|
+
--request COPY
|
55
|
+
--header 'Content-Type: text/xml; charset="utf-8"'
|
56
|
+
--header 'Destination: <!--destination-->'
|
57
|
+
EOF
|
58
|
+
|
59
|
+
CURL_COPY = remove_newlines(curl_copy)
|
60
|
+
|
61
|
+
|
62
|
+
curl_move = <<EOF
|
63
|
+
--request MOVE
|
64
|
+
--header 'Content-Type: text/xml; charset="utf-8"'
|
65
|
+
--header 'Destination: <!--destination-->'
|
66
|
+
EOF
|
67
|
+
|
68
|
+
CURL_MOVE = remove_newlines(curl_move)
|
69
|
+
|
70
|
+
CURL_UPLOAD = "--upload-file"
|
@@ -0,0 +1,168 @@
|
|
1
|
+
# WebDav ls command line utility
|
2
|
+
# Synopsis:
|
3
|
+
# dav ls [options][url]
|
4
|
+
#
|
5
|
+
# or standalone:
|
6
|
+
#
|
7
|
+
# ruby dav-ls [options][url]
|
8
|
+
|
9
|
+
# require 'rubygems'
|
10
|
+
require 'davclient'
|
11
|
+
require 'optparse'
|
12
|
+
|
13
|
+
class LsCLI
|
14
|
+
|
15
|
+
def self.ls(args)
|
16
|
+
options = read_options(args)
|
17
|
+
url = args[0]
|
18
|
+
tmp_cwurl = WebDAV.CWURL
|
19
|
+
if(not url)then
|
20
|
+
url = WebDAV.CWURL
|
21
|
+
if(not url)then
|
22
|
+
puts "#{$0} ls: no current working url"
|
23
|
+
puts "Usage: Use '#{$0} cd [url|dir] to set current working url"
|
24
|
+
exit
|
25
|
+
end
|
26
|
+
else
|
27
|
+
WebDAV.cd(url) # TODO Hva er denne til?. Crasher 'dav-ls filnavn.html'!
|
28
|
+
end
|
29
|
+
|
30
|
+
url = WebDAV.CWURL
|
31
|
+
names = []
|
32
|
+
items_data = { }
|
33
|
+
|
34
|
+
WebDAV.find(url, :recursive => false ) do |item|
|
35
|
+
if(options[:showUrl])then
|
36
|
+
puts item.href
|
37
|
+
|
38
|
+
elsif(options[:longFormat])
|
39
|
+
locked = item.search("d:lockdiscovery").search("d:owner").inner_text
|
40
|
+
items_data.merge!(item.basename => [item.href,
|
41
|
+
locked,
|
42
|
+
item.getlastmodified,
|
43
|
+
item.getcontentlength])
|
44
|
+
|
45
|
+
else
|
46
|
+
# Collect all names in a folder and show them with multiple columns
|
47
|
+
|
48
|
+
name = item.basename
|
49
|
+
if(item.isCollection?)
|
50
|
+
path = item.href.sub(/#{name}\/$/,"")
|
51
|
+
else
|
52
|
+
path = item.href.sub(/#{name}$/,"")
|
53
|
+
end
|
54
|
+
|
55
|
+
name += "/" if item.isCollection?
|
56
|
+
|
57
|
+
# puts name.ljust(35) + path
|
58
|
+
names << name
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
if(options[:oneColumn])
|
63
|
+
puts names.sort.join("\n")
|
64
|
+
|
65
|
+
elsif(options[:longFormat])
|
66
|
+
max_key_size = max_string_size(items_data.keys)
|
67
|
+
items_data.keys.sort.each do |key|
|
68
|
+
locked = ""
|
69
|
+
locked = "Locked by: " + items_data[key][1] if(items_data[key][1] != "")
|
70
|
+
puts key.ljust(max_key_size) + " " + items_data[key][2] +
|
71
|
+
" " + items_data[key][3].rjust(12) +
|
72
|
+
" " + locked
|
73
|
+
end
|
74
|
+
|
75
|
+
else
|
76
|
+
multicolumn_print(names.sort)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Restore CWURL
|
80
|
+
WebDAV.cd(tmp_cwurl)
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def self.read_options(args)
|
86
|
+
options = {}
|
87
|
+
|
88
|
+
optparse = OptionParser.new do|opts|
|
89
|
+
opts.banner = "Usage: #{$0} ls [options] url"
|
90
|
+
|
91
|
+
opts.on( '-h', '--help', 'Display this screen' ) do
|
92
|
+
puts opts
|
93
|
+
exit
|
94
|
+
end
|
95
|
+
|
96
|
+
options[:longFormat] = false
|
97
|
+
opts.on( '-l', '--long',"List in long format" ) do
|
98
|
+
options[:longFormat] = true
|
99
|
+
end
|
100
|
+
|
101
|
+
options[:showUrl] = false
|
102
|
+
opts.on('-u', '--url',"Include full url in names.") do
|
103
|
+
options[:showUrl] = true
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
options[:oneColumn] = false
|
108
|
+
opts.on( '-1', "Force output to be one entry per line" ) do
|
109
|
+
options[:oneColumn] = true
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
begin
|
116
|
+
optparse.parse! args
|
117
|
+
rescue
|
118
|
+
puts "Error: " + $!
|
119
|
+
puts optparse
|
120
|
+
exit
|
121
|
+
end
|
122
|
+
|
123
|
+
return options
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
# Used to make adjust to number of columns to terminal size
|
128
|
+
# when printing names of files and folders
|
129
|
+
def self.terminal_size
|
130
|
+
`stty size`.split.map { |x| x.to_i }.reverse
|
131
|
+
end
|
132
|
+
|
133
|
+
def self.max_string_size(string_array)
|
134
|
+
return string_array.max {|a,b| a.length <=> b.length }.size
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
# Spread output across multiple columns like unix ls does.
|
139
|
+
def self.multicolumn_print(files)
|
140
|
+
if(files.size == 0)
|
141
|
+
return
|
142
|
+
end
|
143
|
+
terminal_width, terminal_height = terminal_size()
|
144
|
+
max_filename_size = max_string_size(files)
|
145
|
+
columns = terminal_width / max_filename_size
|
146
|
+
column_width = max_filename_size + 2
|
147
|
+
row_size = (files.size.to_f / columns.to_f).ceil
|
148
|
+
|
149
|
+
row_size.times do |row_number|
|
150
|
+
columns.times do |column_number|
|
151
|
+
filename = files[row_number+(column_number*row_size)].to_s + ""
|
152
|
+
if(column_number == columns - 1)then
|
153
|
+
print filename
|
154
|
+
else
|
155
|
+
print filename.ljust(column_width)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
print "\n"
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
162
|
+
|
163
|
+
end
|
164
|
+
|
165
|
+
# Make this file an executable script
|
166
|
+
if $0 == __FILE__
|
167
|
+
LsCLI.ls(ARGV)
|
168
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# Handle 'dav propfind [URL]' command
|
2
|
+
require 'rubygems'
|
3
|
+
require 'davclient'
|
4
|
+
require 'optparse'
|
5
|
+
|
6
|
+
class PropfindCLI
|
7
|
+
|
8
|
+
def self.propfind(args)
|
9
|
+
options = read_options(args)
|
10
|
+
|
11
|
+
url = args[0]
|
12
|
+
if(not(url)) then
|
13
|
+
url = WebDAV.CWURL
|
14
|
+
end
|
15
|
+
|
16
|
+
if(not(url)) then
|
17
|
+
puts "Error: Missing mandatory url"
|
18
|
+
puts optparse
|
19
|
+
exit
|
20
|
+
end
|
21
|
+
|
22
|
+
if(options[:xml])then
|
23
|
+
puts WebDAV.propfind(url, :xml => true)
|
24
|
+
else
|
25
|
+
|
26
|
+
# TODO This is experimental code in desperat need
|
27
|
+
# of love and attention
|
28
|
+
item = WebDAV.propfind(url)
|
29
|
+
puts item.collection
|
30
|
+
|
31
|
+
prev_url = nil
|
32
|
+
WebDAV.find(url, :children => options[:children]) do | url, item |
|
33
|
+
if(prev_url != url) then
|
34
|
+
puts
|
35
|
+
puts "url = " + url.to_s
|
36
|
+
prev_url = url
|
37
|
+
end
|
38
|
+
|
39
|
+
name = item.prefix
|
40
|
+
if(item.namespace)then
|
41
|
+
name = name + "(" + item.namespace + ")"
|
42
|
+
end
|
43
|
+
name = name + item.name
|
44
|
+
puts name.ljust(40) + " = '" + item.text.to_s + "'"
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def self.read_options(args)
|
54
|
+
options = {}
|
55
|
+
|
56
|
+
title = nil
|
57
|
+
optparse = OptionParser.new do|opts|
|
58
|
+
opts.banner = "Usage: #{$0} propfind [options] url"
|
59
|
+
|
60
|
+
opts.on( '-h', '--help', 'Display this screen' ) do
|
61
|
+
puts opts
|
62
|
+
exit
|
63
|
+
end
|
64
|
+
|
65
|
+
options[:xml] = true
|
66
|
+
opts.on( '-p', '--pretty', "Pretty print output instead of returning xml" ) do
|
67
|
+
options[:xml] = false
|
68
|
+
end
|
69
|
+
|
70
|
+
options[:children] = false
|
71
|
+
opts.on('-c', '--children', "Show children if viewing collection (folder)") do
|
72
|
+
options[:children] = true
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
begin
|
78
|
+
optparse.parse!
|
79
|
+
rescue
|
80
|
+
puts "Error: " + $!
|
81
|
+
puts optparse
|
82
|
+
exit
|
83
|
+
end
|
84
|
+
|
85
|
+
return options
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
if $0 == __FILE__
|
91
|
+
PropfindCLI.propfind(ARGV)
|
92
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
# Implementation of the 'dav-put' command line utility.
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'davclient'
|
5
|
+
require 'optparse'
|
6
|
+
|
7
|
+
class PutCLI
|
8
|
+
|
9
|
+
def self.put(args)
|
10
|
+
|
11
|
+
options = read_options(args)
|
12
|
+
url = args[0]
|
13
|
+
if(options[:string])then
|
14
|
+
|
15
|
+
# Put string
|
16
|
+
if(!url.match(/^http.*\/\/([^\/]*)/) and !WebDAV.CWURL)
|
17
|
+
raise "Error: No current working url set. Use '#{$0} cd url' to set url."
|
18
|
+
end
|
19
|
+
|
20
|
+
begin
|
21
|
+
WebDAV.put_string(url,options[:string])
|
22
|
+
rescue
|
23
|
+
puts $0 + ": " + $!
|
24
|
+
end
|
25
|
+
puts "Published content to: " + url
|
26
|
+
else
|
27
|
+
|
28
|
+
# Put files(s)
|
29
|
+
|
30
|
+
# puts "DEBUG: size:" + args.size.to_s
|
31
|
+
|
32
|
+
if(args.size == 1 )
|
33
|
+
local_file = args[0]
|
34
|
+
if(not(File.exists?(local_file)))
|
35
|
+
raise "File not found: #{local_file}"
|
36
|
+
end
|
37
|
+
if(!WebDAV.CWURL)
|
38
|
+
raise "Error: No current working url set. Use '#{$0} cd url' to set url."
|
39
|
+
end
|
40
|
+
|
41
|
+
WebDAV.put(WebDAV.CWURL, local_file)
|
42
|
+
|
43
|
+
elsif(args.size == 2 and args[1].match(/^http.*\/\/([^\/]*)/) )
|
44
|
+
local_file = args[0]
|
45
|
+
url = args[1]
|
46
|
+
|
47
|
+
if(not(File.exists?(local_file)))
|
48
|
+
raise "File not found: #{local_file}"
|
49
|
+
end
|
50
|
+
|
51
|
+
if(WebDAV.isCollection?(url))
|
52
|
+
url += File.basename(local_file)
|
53
|
+
end
|
54
|
+
|
55
|
+
WebDAV.put(url, local_file)
|
56
|
+
|
57
|
+
else
|
58
|
+
|
59
|
+
# Put more than one file
|
60
|
+
|
61
|
+
if(args.last.match(/^http.*\/\/([^\/]*)/) )
|
62
|
+
url = args.last
|
63
|
+
if(!WebDAV.isCollection?(url))
|
64
|
+
raise "Destination collection not found: " + url
|
65
|
+
end
|
66
|
+
args = args[0..(args.size-2)]
|
67
|
+
else
|
68
|
+
url = WebDAV.CWURL
|
69
|
+
end
|
70
|
+
|
71
|
+
count = 0
|
72
|
+
args.each do | arg|
|
73
|
+
# puts "arg:" + arg
|
74
|
+
if(File.ftype(arg) == 'directory')
|
75
|
+
raise "Upload directories not implemented"
|
76
|
+
end
|
77
|
+
if(File.exists?(arg))
|
78
|
+
basename = File.basename(arg)
|
79
|
+
WebDAV.put(url + basename, arg)
|
80
|
+
count = count + 1
|
81
|
+
else
|
82
|
+
raise "Error: File not found " + arg
|
83
|
+
end
|
84
|
+
end
|
85
|
+
puts "Published #{count} files to #{url}"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def self.read_options(args)
|
94
|
+
options = {}
|
95
|
+
|
96
|
+
optparse = OptionParser.new do|opts|
|
97
|
+
opts.banner = "Usage: #{$0} put [options] [filelist][url]"
|
98
|
+
|
99
|
+
opts.on( '-h', '--help', 'Display this screen' ) do
|
100
|
+
puts opts
|
101
|
+
puts
|
102
|
+
puts "Upload local file or files to server."
|
103
|
+
puts
|
104
|
+
puts "Examples:"
|
105
|
+
puts
|
106
|
+
puts " #{$0} put local_file"
|
107
|
+
puts " #{$0} put local_filename https://dav.org/remote_filename"
|
108
|
+
puts " #{$0} put *.html https://dav.org/remote_collection/"
|
109
|
+
puts " #{$0} put --string \"Hello world\" hello_world.html"
|
110
|
+
puts
|
111
|
+
exit
|
112
|
+
end
|
113
|
+
|
114
|
+
options[:string] = false
|
115
|
+
opts.on( '-s', '--string STRING', "Put contents of string" ) do |str |
|
116
|
+
options[:string] = str
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
begin
|
122
|
+
optparse.parse! args
|
123
|
+
rescue
|
124
|
+
puts "Error: " + $!
|
125
|
+
puts optparse
|
126
|
+
exit
|
127
|
+
end
|
128
|
+
|
129
|
+
return options
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
# Make this file an executable script
|
135
|
+
if $0 == __FILE__
|
136
|
+
PutCLI.put(ARGV)
|
137
|
+
end
|