davclient 0.0.4 → 0.0.5
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/README.rdoc +20 -1
- data/lib/davclient.rb +44 -48
- data/lib/davclient/dav-ls.rb +87 -7
- data/lib/davclient/dav-put.rb +81 -15
- data/lib/davclient/davcli.rb +130 -13
- metadata +2 -2
    
        data/README.rdoc
    CHANGED
    
    | @@ -5,9 +5,15 @@ | |
| 5 5 |  | 
| 6 6 | 
             
            == DESCRIPTION:
         | 
| 7 7 |  | 
| 8 | 
            +
            A scriptable WebDAV command line client for
         | 
| 9 | 
            +
             | 
| 8 10 | 
             
            WebDAV command line client written in Ruby for managing content on
         | 
| 9 11 | 
             
            webservers that support the WebDAV extensions.
         | 
| 10 12 |  | 
| 13 | 
            +
            This is still very much work in progress. Especially the command line interface
         | 
| 14 | 
            +
            is changed a lot recently. The ruby library however is starting to settle.
         | 
| 15 | 
            +
             | 
| 16 | 
            +
             | 
| 11 17 | 
             
            == Requirements
         | 
| 12 18 |  | 
| 13 19 | 
             
            The command line utility curl installed and available in your unix path.
         | 
| @@ -70,7 +76,20 @@ authentication. DavClient instead uses the command line tool 'curl' to do all th | |
| 70 76 | 
             
            authentication and networking. To avoid handling authentication all togheter, curl
         | 
| 71 77 | 
             
            are told to look up all usernames and passwords are in a file named ~/.netrc.
         | 
| 72 78 |  | 
| 73 | 
            -
            The command 'dav' is | 
| 79 | 
            +
            The command line utility 'dav' is non-interactive and inspired by git, making it more suitable for
         | 
| 74 80 | 
             
            use in scripts. If you can script in Ruby, the examples folder includes sample
         | 
| 75 81 | 
             
            scripts using the davclient Ruby library.
         | 
| 76 82 |  | 
| 83 | 
            +
            == Licence
         | 
| 84 | 
            +
             | 
| 85 | 
            +
            DavClient (davclient and the dav utility) is copyrighted free software by Thomas Flemming
         | 
| 86 | 
            +
            <thomas dot flemming at usit.uio.no> and contributors. You can redistribute it
         | 
| 87 | 
            +
            and/or modify it under either the terms of the GPL2 or the conditions below:
         | 
| 88 | 
            +
             | 
| 89 | 
            +
            See LICENCE file for details.
         | 
| 90 | 
            +
             | 
| 91 | 
            +
            == Comments
         | 
| 92 | 
            +
             | 
| 93 | 
            +
            Feel free to contact me at thomas dot flemming at usit.uio.no.
         | 
| 94 | 
            +
             | 
| 95 | 
            +
             | 
    
        data/lib/davclient.rb
    CHANGED
    
    | @@ -19,7 +19,7 @@ require 'davclient/curl_commands' | |
| 19 19 | 
             
            module WebDAV
         | 
| 20 20 |  | 
| 21 21 | 
             
              # :stopdoc:
         | 
| 22 | 
            -
              VERSION = '0.0. | 
| 22 | 
            +
              VERSION = '0.0.4'
         | 
| 23 23 | 
             
              # :startdoc:
         | 
| 24 24 |  | 
| 25 25 | 
             
              # Returns the version string for the library.
         | 
| @@ -61,6 +61,18 @@ module WebDAV | |
| 61 61 | 
             
                return url
         | 
| 62 62 | 
             
              end
         | 
| 63 63 |  | 
| 64 | 
            +
              # Returns true if url is a collection
         | 
| 65 | 
            +
              def self.isCollection?(url)
         | 
| 66 | 
            +
                url = absoluteUrl(url)
         | 
| 67 | 
            +
                url = url + "/" if(not(url =~ /\/$/))
         | 
| 68 | 
            +
                resource = WebDAV.propfind(url)
         | 
| 69 | 
            +
                if(resource == nil)
         | 
| 70 | 
            +
                  return false
         | 
| 71 | 
            +
                else
         | 
| 72 | 
            +
                  return resource.isCollection?
         | 
| 73 | 
            +
                end
         | 
| 74 | 
            +
              end
         | 
| 75 | 
            +
             | 
| 64 76 | 
             
              # Change current working url. Takes relative pathnames.
         | 
| 65 77 | 
             
              #
         | 
| 66 78 | 
             
              # Examples:
         | 
| @@ -71,13 +83,11 @@ module WebDAV | |
| 71 83 | 
             
              def self.cd(url)
         | 
| 72 84 | 
             
                url = absoluteUrl(url)
         | 
| 73 85 | 
             
                url = url + "/" if(not(url =~ /\/$/))
         | 
| 74 | 
            -
             | 
| 75 86 | 
             
                resource = WebDAV.propfind(url)
         | 
| 76 87 | 
             
                if(resource and resource.isCollection?)then
         | 
| 77 88 | 
             
                  WebDAV.CWURL = url
         | 
| 78 89 | 
             
                else
         | 
| 79 | 
            -
                  #  | 
| 80 | 
            -
                  raise Exception, "cd: URL '#{cwurl} is not a WebDAV collection."
         | 
| 90 | 
            +
                  raise Exception, "#{$0} cd: #{url}: No such collection on remote server."
         | 
| 81 91 | 
             
                end
         | 
| 82 92 | 
             
              end
         | 
| 83 93 |  | 
| @@ -88,31 +98,6 @@ module WebDAV | |
| 88 98 | 
             
                File.open(cwurl_filename, 'w') {|f| f.write(url) }
         | 
| 89 99 | 
             
              end
         | 
| 90 100 |  | 
| 91 | 
            -
              # Lock resource
         | 
| 92 | 
            -
              #
         | 
| 93 | 
            -
              def self.lock(*args)
         | 
| 94 | 
            -
                url = args[0]
         | 
| 95 | 
            -
             | 
| 96 | 
            -
              end
         | 
| 97 | 
            -
             | 
| 98 | 
            -
            # Original code from davlib.py
         | 
| 99 | 
            -
            #
         | 
| 100 | 
            -
            #   def lock(self, url, owner='', timeout=None, depth=None,
         | 
| 101 | 
            -
            #            scope='exclusive', type='write', extra_hdrs={ }):
         | 
| 102 | 
            -
            #     headers = extra_hdrs.copy()
         | 
| 103 | 
            -
            #     headers['Content-Type'] = XML_CONTENT_TYPE
         | 
| 104 | 
            -
            #     if depth is not None:
         | 
| 105 | 
            -
            #       headers['Depth'] = str(depth)
         | 
| 106 | 
            -
            #     if timeout is not None:
         | 
| 107 | 
            -
            #       headers['Timeout'] = timeout
         | 
| 108 | 
            -
            #     body = XML_DOC_HEADER + \
         | 
| 109 | 
            -
            #            '<DAV:lockinfo xmlns:DAV="DAV:">' + \
         | 
| 110 | 
            -
            #            '<DAV:lockscope><DAV:%s/></DAV:lockscope>' % scope + \
         | 
| 111 | 
            -
            #            '<DAV:locktype><DAV:%s/></DAV:locktype>' % type + \
         | 
| 112 | 
            -
            #            owner + \
         | 
| 113 | 
            -
            #            '</DAV:lockinfo>'
         | 
| 114 | 
            -
            #     return self._request('LOCK', url, body, extra_hdrs=headers)
         | 
| 115 | 
            -
             | 
| 116 101 |  | 
| 117 102 | 
             
              # Get content of resource as string
         | 
| 118 103 | 
             
              #
         | 
| @@ -372,24 +357,29 @@ module WebDAV | |
| 372 357 | 
             
              end
         | 
| 373 358 |  | 
| 374 359 |  | 
| 360 | 
            +
             | 
| 375 361 | 
             
              # Puts content of string to file on server with url
         | 
| 376 362 | 
             
              #
         | 
| 377 363 | 
             
              # Example:
         | 
| 378 364 | 
             
              #
         | 
| 379 365 | 
             
              #   WebDAV.put("https://dav.webdav.org/file.html", "<html><h1>Test</h1></html>"
         | 
| 380 | 
            -
              def self.put_string(url, | 
| 366 | 
            +
              def self.put_string(url,str)
         | 
| 381 367 | 
             
                url = absoluteUrl(url)
         | 
| 382 368 |  | 
| 383 369 | 
             
                if(url =~ /\/$/)then
         | 
| 384 370 | 
             
                  raise "Error: WebDAV.put_html: url can not be a collection (folder)."
         | 
| 385 371 | 
             
                end
         | 
| 386 372 |  | 
| 387 | 
            -
                 | 
| 388 | 
            -
                 | 
| 389 | 
            -
             | 
| 390 | 
            -
                File.open(tmp_file, 'w') {|f| f.write(html) }
         | 
| 373 | 
            +
                filename = string2tempfile(str)
         | 
| 374 | 
            +
                put(url,filename)
         | 
| 375 | 
            +
              end
         | 
| 391 376 |  | 
| 392 | 
            -
             | 
| 377 | 
            +
             | 
| 378 | 
            +
              # Upload local file
         | 
| 379 | 
            +
              def self.put(url, file_name)
         | 
| 380 | 
            +
                url = absoluteUrl(url)
         | 
| 381 | 
            +
             | 
| 382 | 
            +
                curl_command = "#{$curl} --netrc --silent --upload-file #{file_name} #{url}"
         | 
| 393 383 | 
             
                response = exec_curl(curl_command)
         | 
| 394 384 | 
             
                if(response != "" and not(response =~ /200 OK/)) then
         | 
| 395 385 | 
             
                  raise "Error:\n WebDAV.put: WebDAV Request:\n" + curl_command + "\n\nResponse: " + response
         | 
| @@ -404,29 +394,35 @@ module WebDAV | |
| 404 394 | 
             
                return self.exec_curl(CURL_OPTIONS + url )
         | 
| 405 395 | 
             
              end
         | 
| 406 396 |  | 
| 407 | 
            -
              #  | 
| 397 | 
            +
              # Returns name of temp folder we're using
         | 
| 398 | 
            +
              # TODO: Move this to utility library
         | 
| 399 | 
            +
              def self.tmp_folder
         | 
| 400 | 
            +
                tmp_file = Tempfile.new("dummy").path
         | 
| 401 | 
            +
                basename = File.basename(tmp_file)
         | 
| 402 | 
            +
                return  tmp_file.gsub(basename, "")
         | 
| 403 | 
            +
              end
         | 
| 408 404 |  | 
| 409 | 
            -
             | 
| 410 | 
            -
              #  | 
| 411 | 
            -
               | 
| 412 | 
            -
             | 
| 413 | 
            -
                 | 
| 414 | 
            -
                 | 
| 415 | 
            -
                 | 
| 405 | 
            +
             | 
| 406 | 
            +
              # TODO: Move this to utility library
         | 
| 407 | 
            +
              # Write string to tempfile and returns filename
         | 
| 408 | 
            +
              def self.string2tempfile(str)
         | 
| 409 | 
            +
                tmp_dir = tmp_folder + rand.to_s[2..10] + "/"
         | 
| 410 | 
            +
                FileUtils.mkdir_p tmp_dir
         | 
| 411 | 
            +
                tmp_file = tmp_dir + "webdav.tmp"
         | 
| 412 | 
            +
                File.open(tmp_file, 'w') {|f| f.write(str) }
         | 
| 413 | 
            +
                return tmp_file
         | 
| 416 414 | 
             
              end
         | 
| 417 | 
            -
              # :startdoc:
         | 
| 418 415 |  | 
| 419 | 
            -
             | 
| 416 | 
            +
             | 
| 420 417 |  | 
| 421 418 | 
             
              # Returns filename /tmp/cwurl.#pid that holds the current working directory
         | 
| 422 419 | 
             
              # for the shell's pid
         | 
| 423 420 | 
             
              def self.cwurl_filename
         | 
| 424 | 
            -
                tmp_file = Tempfile.new("dummy").path
         | 
| 425 | 
            -
                basename = File.basename(tmp_file)
         | 
| 426 | 
            -
                tmp_folder = tmp_file.gsub(basename, "")
         | 
| 427 421 | 
             
                return tmp_folder +  "cwurl." + Process.ppid.to_s
         | 
| 428 422 | 
             
              end
         | 
| 429 423 |  | 
| 424 | 
            +
              private
         | 
| 425 | 
            +
             | 
| 430 426 | 
             
              # Display instructions for adding credentials to .netrc file
         | 
| 431 427 | 
             
              def self.display_unauthorized_message(href)
         | 
| 432 428 | 
             
                puts "Error: 401 Unauthorized: " + href
         | 
    
        data/lib/davclient/dav-ls.rb
    CHANGED
    
    | @@ -6,7 +6,7 @@ | |
| 6 6 | 
             
            #
         | 
| 7 7 | 
             
            #     ruby dav-ls  [options][url]
         | 
| 8 8 |  | 
| 9 | 
            -
            require 'rubygems'
         | 
| 9 | 
            +
            # require 'rubygems'
         | 
| 10 10 | 
             
            require 'davclient'
         | 
| 11 11 | 
             
            require 'optparse'
         | 
| 12 12 |  | 
| @@ -24,22 +24,58 @@ class LsCLI | |
| 24 24 | 
             
                    exit
         | 
| 25 25 | 
             
                  end
         | 
| 26 26 | 
             
                else
         | 
| 27 | 
            -
                  WebDAV.cd(url)
         | 
| 27 | 
            +
                  WebDAV.cd(url)  # TODO Hva er denne til?. Crasher 'dav-ls filnavn.html'!
         | 
| 28 28 | 
             
                end
         | 
| 29 29 |  | 
| 30 30 | 
             
                url = WebDAV.CWURL
         | 
| 31 | 
            +
                names = []
         | 
| 32 | 
            +
                items_data = { }
         | 
| 33 | 
            +
             | 
| 31 34 | 
             
                WebDAV.find(url, :recursive => false ) do |item|
         | 
| 32 35 | 
             
                  if(options[:showUrl])then
         | 
| 33 36 | 
             
                    puts item.href
         | 
| 37 | 
            +
             | 
| 34 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])
         | 
| 35 44 |  | 
| 36 45 | 
             
                  else
         | 
| 37 | 
            -
                     | 
| 38 | 
            -
             | 
| 39 | 
            -
                     | 
| 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
         | 
| 40 59 | 
             
                  end
         | 
| 41 60 | 
             
                end
         | 
| 42 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 | 
            +
             | 
| 43 79 | 
             
                # Restore CWURL
         | 
| 44 80 | 
             
                WebDAV.cd(tmp_cwurl)
         | 
| 45 81 | 
             
              end
         | 
| @@ -58,15 +94,22 @@ class LsCLI | |
| 58 94 | 
             
                  end
         | 
| 59 95 |  | 
| 60 96 | 
             
                  options[:longFormat] = false
         | 
| 61 | 
            -
                  opts.on( '-l', "List in long format" ) do
         | 
| 97 | 
            +
                  opts.on( '-l', '--long',"List in long format" ) do
         | 
| 62 98 | 
             
                    options[:longFormat] = true
         | 
| 63 99 | 
             
                  end
         | 
| 64 100 |  | 
| 65 101 | 
             
                  options[:showUrl] = false
         | 
| 66 | 
            -
                  opts.on('- | 
| 102 | 
            +
                  opts.on('-u', '--url',"Include full url in names.") do
         | 
| 67 103 | 
             
                    options[:showUrl] = true
         | 
| 68 104 | 
             
                  end
         | 
| 69 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 | 
            +
             | 
| 70 113 | 
             
                end
         | 
| 71 114 |  | 
| 72 115 | 
             
                begin
         | 
| @@ -80,6 +123,43 @@ class LsCLI | |
| 80 123 | 
             
                return options
         | 
| 81 124 | 
             
              end
         | 
| 82 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 | 
            +
             | 
| 83 163 | 
             
            end
         | 
| 84 164 |  | 
| 85 165 | 
             
            # Make this file an executable script
         | 
    
        data/lib/davclient/dav-put.rb
    CHANGED
    
    | @@ -1,10 +1,4 @@ | |
| 1 | 
            -
            #  | 
| 2 | 
            -
            # Synopsis:
         | 
| 3 | 
            -
            #       dav put [options][url]
         | 
| 4 | 
            -
            #
         | 
| 5 | 
            -
            # or standalone:
         | 
| 6 | 
            -
            #
         | 
| 7 | 
            -
            #     ruby dav-ls  [options][url]
         | 
| 1 | 
            +
            # Implementation of the 'dav-put' command line utility.
         | 
| 8 2 |  | 
| 9 3 | 
             
            require 'rubygems'
         | 
| 10 4 | 
             
            require 'davclient'
         | 
| @@ -13,40 +7,112 @@ require 'optparse' | |
| 13 7 | 
             
            class PutCLI
         | 
| 14 8 |  | 
| 15 9 | 
             
              def self.put(args)
         | 
| 10 | 
            +
             | 
| 16 11 | 
             
                options = read_options(args)
         | 
| 17 12 | 
             
                url = args[0]
         | 
| 18 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 | 
            +
             | 
| 19 20 | 
             
                  begin
         | 
| 20 21 | 
             
                    WebDAV.put_string(url,options[:string])
         | 
| 21 22 | 
             
                  rescue
         | 
| 22 23 | 
             
                    puts $0 + ": " + $!
         | 
| 23 24 | 
             
                  end
         | 
| 24 | 
            -
                  puts "Published content to " + url
         | 
| 25 | 
            +
                  puts "Published content to: " + url
         | 
| 25 26 | 
             
                else
         | 
| 26 | 
            -
             | 
| 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
         | 
| 27 87 | 
             
                end
         | 
| 28 88 |  | 
| 29 89 | 
             
              end
         | 
| 30 90 |  | 
| 31 91 | 
             
              private
         | 
| 32 92 |  | 
| 33 | 
            -
              def self.usage()
         | 
| 34 | 
            -
                puts "Usage: #{$0} put --string \"<html>..</html>\" url"
         | 
| 35 | 
            -
              end
         | 
| 36 | 
            -
             | 
| 37 93 | 
             
              def self.read_options(args)
         | 
| 38 94 | 
             
                options = {}
         | 
| 39 95 |  | 
| 40 96 | 
             
                optparse = OptionParser.new do|opts|
         | 
| 41 | 
            -
                  opts.banner = "Usage: #{$0} put [options] url"
         | 
| 97 | 
            +
                  opts.banner = "Usage: #{$0} put [options] [filelist][url]"
         | 
| 42 98 |  | 
| 43 99 | 
             
                  opts.on( '-h', '--help', 'Display this screen' ) do
         | 
| 44 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
         | 
| 45 111 | 
             
                    exit
         | 
| 46 112 | 
             
                  end
         | 
| 47 113 |  | 
| 48 114 | 
             
                  options[:string] = false
         | 
| 49 | 
            -
                  opts.on( '-s', '--string', "Put contents of string" ) do |str |
         | 
| 115 | 
            +
                  opts.on( '-s', '--string STRING', "Put contents of string" ) do |str |
         | 
| 50 116 | 
             
                    options[:string] = str
         | 
| 51 117 | 
             
                  end
         | 
| 52 118 |  | 
    
        data/lib/davclient/davcli.rb
    CHANGED
    
    | @@ -2,21 +2,93 @@ require 'davclient/dav-ls' | |
| 2 2 | 
             
            require 'davclient/dav-put'
         | 
| 3 3 | 
             
            require 'davclient/dav-propfind'
         | 
| 4 4 |  | 
| 5 | 
            -
            #  | 
| 5 | 
            +
            # DavClient Command Line Utility
         | 
| 6 6 |  | 
| 7 7 | 
             
            class DavCLI
         | 
| 8 8 |  | 
| 9 | 
            +
              def self.print_edit_usage
         | 
| 10 | 
            +
                puts "Usage: #{$0} edit [url|resource-name]"
         | 
| 11 | 
            +
                puts
         | 
| 12 | 
            +
                puts "Edit remote file in editor. File is transfered back to "
         | 
| 13 | 
            +
                puts "server after execution of editor is ended. "
         | 
| 14 | 
            +
                puts
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              def self.edit(args)
         | 
| 18 | 
            +
                if(show_help?(args))
         | 
| 19 | 
            +
                  print_edit_usage
         | 
| 20 | 
            +
                else
         | 
| 21 | 
            +
                  if(args.size == 1)
         | 
| 22 | 
            +
                    url = args[0]
         | 
| 23 | 
            +
                    content = WebDAV.get(url)
         | 
| 24 | 
            +
                    tmp_filename = WebDAV.tmp_folder + File.basename(url)
         | 
| 25 | 
            +
                    File.open(tmp_filename, 'w') {|f| f.write(content) }
         | 
| 26 | 
            +
                    system("emacs --quick -nw " + tmp_filename)
         | 
| 27 | 
            +
                    new_content = nil
         | 
| 28 | 
            +
                    File.open(tmp_filename, 'r') {|f| new_content = f.read() }
         | 
| 29 | 
            +
                    WebDAV.put_string(url, new_content)
         | 
| 30 | 
            +
                  else
         | 
| 31 | 
            +
                    puts "Illegal arguments: " + args[1..100].join(" ")
         | 
| 32 | 
            +
                    print_edit_usage
         | 
| 33 | 
            +
                  end
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
              end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
              # TODO
         | 
| 38 | 
            +
              #  - Handle glob (ie *.gif) => Tell user to quote to avoid shell glob: dav get "*.html"
         | 
| 39 | 
            +
              def self.get(args)
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                puts "DEBUG:"
         | 
| 42 | 
            +
                if(args.size == 1 or args.size == 2 )
         | 
| 43 | 
            +
                  url = args[0]
         | 
| 44 | 
            +
                  content =  WebDAV.get(url)
         | 
| 45 | 
            +
                  filename = ""
         | 
| 46 | 
            +
                  if(args.size == 1)
         | 
| 47 | 
            +
                    filename = File.basename(url)
         | 
| 48 | 
            +
                  else
         | 
| 49 | 
            +
                    # Handle relative paths in local filenames or local dir
         | 
| 50 | 
            +
                    path = Pathname.new(Pathname.pwd)
         | 
| 51 | 
            +
                    path = path + args[1]
         | 
| 52 | 
            +
                    filename = path.to_s
         | 
| 53 | 
            +
                    if(args[1] =~ /\/$/ or args[1] =~ /\.$/)
         | 
| 54 | 
            +
                      path = path + filename = filename + "/" + File.basename(url)
         | 
| 55 | 
            +
                    end
         | 
| 56 | 
            +
                  end
         | 
| 57 | 
            +
                  File.open(filename, 'w') {|f| f.write(content) }
         | 
| 58 | 
            +
                else
         | 
| 59 | 
            +
                  puts "Illegal arguments: " + args[1..100].join(" ")
         | 
| 60 | 
            +
                  puts "#{$0}: usage '#{$0} get remote-url [local]"
         | 
| 61 | 
            +
                end
         | 
| 62 | 
            +
              end
         | 
| 63 | 
            +
             | 
| 9 64 | 
             
              def self.cat(args)
         | 
| 65 | 
            +
                if(show_help?(args))
         | 
| 66 | 
            +
                  puts "Usage: #{$0} cat [url|filename]"
         | 
| 67 | 
            +
                  puts
         | 
| 68 | 
            +
                  puts "Concatenate and print remote files to local terminal."
         | 
| 69 | 
            +
                end
         | 
| 10 70 | 
             
                if(args.size == 1)
         | 
| 11 71 | 
             
                  url = args[0]
         | 
| 12 72 | 
             
                  puts WebDAV.get(url)
         | 
| 13 73 | 
             
                else
         | 
| 14 74 | 
             
                  puts "Illegal arguments: " + args[1..100].join(" ")
         | 
| 15 | 
            -
                  puts " | 
| 75 | 
            +
                  puts "Usage: #{$0} cat [url|filename]"
         | 
| 16 76 | 
             
                end
         | 
| 17 77 | 
             
              end
         | 
| 18 78 |  | 
| 79 | 
            +
              def self.show_help?(args)
         | 
| 80 | 
            +
                return (args.grep("-?").size > 0 or
         | 
| 81 | 
            +
                        args.grep("-h").size > 0 or
         | 
| 82 | 
            +
                        args.grep("--help").size > 0 )
         | 
| 83 | 
            +
              end
         | 
| 84 | 
            +
             | 
| 19 85 | 
             
              def self.pwd(args)
         | 
| 86 | 
            +
                if(show_help?(args))
         | 
| 87 | 
            +
                  puts "Usage: #{$0} pwd"
         | 
| 88 | 
            +
                  puts ""
         | 
| 89 | 
            +
                  puts "Print current working url."
         | 
| 90 | 
            +
                  exit
         | 
| 91 | 
            +
                end
         | 
| 20 92 | 
             
                cwurl = WebDAV.CWURL
         | 
| 21 93 | 
             
                if(cwurl)
         | 
| 22 94 | 
             
                  puts cwurl
         | 
| @@ -27,6 +99,17 @@ class DavCLI | |
| 27 99 | 
             
              end
         | 
| 28 100 |  | 
| 29 101 | 
             
              def self.cd(args)
         | 
| 102 | 
            +
                if(show_help?(args))
         | 
| 103 | 
            +
                  puts "Usage: #{$0} cd [url|remote-path]"
         | 
| 104 | 
            +
                  puts
         | 
| 105 | 
            +
                  puts "Change current working working url."
         | 
| 106 | 
            +
                  puts
         | 
| 107 | 
            +
                  puts "Examples: "
         | 
| 108 | 
            +
                  puts "     #{$0} cd https://www.webdav.org/"
         | 
| 109 | 
            +
                  puts "     #{$0} cd ../test"
         | 
| 110 | 
            +
                  puts
         | 
| 111 | 
            +
                  exit
         | 
| 112 | 
            +
                end
         | 
| 30 113 | 
             
                url = args[0]
         | 
| 31 114 | 
             
                if(url == nil)then
         | 
| 32 115 | 
             
                  puts "#{$0} cd: Missing mandatory url."
         | 
| @@ -41,27 +124,47 @@ class DavCLI | |
| 41 124 | 
             
              end
         | 
| 42 125 |  | 
| 43 126 | 
             
              def self.mkcol(args)
         | 
| 127 | 
            +
                if(show_help?(args))
         | 
| 128 | 
            +
                  puts "Usage: #{$0} mkcol [url|remote-path]"
         | 
| 129 | 
            +
                  puts
         | 
| 130 | 
            +
                  puts "Create collection (folder) on remote server."
         | 
| 131 | 
            +
                  puts "The command 'mkdir' is an alias for 'mkcol'."
         | 
| 132 | 
            +
                  puts
         | 
| 133 | 
            +
                  puts "Examples: "
         | 
| 134 | 
            +
                  puts "     #{$0} mkcol new_collection"
         | 
| 135 | 
            +
                  puts "     #{$0} mkcol https://www.webdav.org/new_collection/"
         | 
| 136 | 
            +
                  puts "     #{$0} mkcol ../new_collection"
         | 
| 137 | 
            +
                  puts
         | 
| 138 | 
            +
                  exit
         | 
| 139 | 
            +
                end
         | 
| 44 140 | 
             
                if(args.size == 1 )
         | 
| 45 | 
            -
                   | 
| 141 | 
            +
                  if( args[0] =~ /^http/ || WebDAV.CWURL )
         | 
| 142 | 
            +
                    WebDAV.mkcol(args[0])
         | 
| 143 | 
            +
                  else
         | 
| 144 | 
            +
                    puts "Error: #{$0} mkcol: No working url set. Use '#{$0} cd url' to set url."
         | 
| 145 | 
            +
                  end
         | 
| 46 146 | 
             
                else
         | 
| 47 | 
            -
                  puts "#{$0}: usage '#{$0} mkcol url|path"
         | 
| 147 | 
            +
                  puts "#{$0}: usage '#{$0} mkcol [url|path]"
         | 
| 48 148 | 
             
                end
         | 
| 49 149 | 
             
              end
         | 
| 50 150 |  | 
| 51 151 | 
             
              def self.delete(args)
         | 
| 52 | 
            -
                if(args.size  | 
| 53 | 
            -
                   | 
| 54 | 
            -
                  puts | 
| 152 | 
            +
                if(show_help?(args) or args.size != 1)
         | 
| 153 | 
            +
                  puts "Usage: #{$0} delete [url|path]"
         | 
| 154 | 
            +
                  puts
         | 
| 155 | 
            +
                  puts "Delete remote collection (folder) or file."
         | 
| 55 156 | 
             
                else
         | 
| 56 | 
            -
                   | 
| 157 | 
            +
                  url = WebDAV.delete(args[0])
         | 
| 57 158 | 
             
                end
         | 
| 58 159 | 
             
              end
         | 
| 59 160 |  | 
| 60 161 | 
             
              def self.options(args)
         | 
| 61 | 
            -
                if(args.size == 0 or args.size == 1)
         | 
| 162 | 
            +
                if((args.size == 0 or args.size == 1) and !show_help?(args))
         | 
| 62 163 | 
             
                  puts WebDAV.options(args[0])
         | 
| 63 164 | 
             
                else
         | 
| 64 | 
            -
                  puts " | 
| 165 | 
            +
                  puts "Usage: #{$0} options [url]"
         | 
| 166 | 
            +
                  puts
         | 
| 167 | 
            +
                  puts "Prints remote server options and http headers. "
         | 
| 65 168 | 
             
                end
         | 
| 66 169 | 
             
              end
         | 
| 67 170 |  | 
| @@ -77,7 +180,9 @@ class DavCLI | |
| 77 180 | 
             
                if(args.size == 2 )
         | 
| 78 181 | 
             
                  WebDAV.cp(args[0], args[1])
         | 
| 79 182 | 
             
                else
         | 
| 80 | 
            -
                  puts " | 
| 183 | 
            +
                  puts "Usage '#{$0} cp src dest"
         | 
| 184 | 
            +
                  puts
         | 
| 185 | 
            +
                  puts "Copy resources on remote server."
         | 
| 81 186 | 
             
                end
         | 
| 82 187 | 
             
              end
         | 
| 83 188 |  | 
| @@ -86,7 +191,9 @@ class DavCLI | |
| 86 191 | 
             
                if(args.size == 2 )
         | 
| 87 192 | 
             
                  WebDAV.mv(args[0], args[1])
         | 
| 88 193 | 
             
                else
         | 
| 89 | 
            -
                  puts " | 
| 194 | 
            +
                  puts "Usage '#{$0} copy mv dest"
         | 
| 195 | 
            +
                  puts
         | 
| 196 | 
            +
                  puts "Move resources on remote server."
         | 
| 90 197 | 
             
                end
         | 
| 91 198 | 
             
              end
         | 
| 92 199 |  | 
| @@ -101,9 +208,13 @@ class DavCLI | |
| 101 208 | 
             
                puts "   mv        Move resource"
         | 
| 102 209 | 
             
                puts "   rm        Remove resource"
         | 
| 103 210 | 
             
                puts "   cat       Print content of resource"
         | 
| 211 | 
            +
                puts "   mkdir     Create remote collection (directory) (mkcol alias)"
         | 
| 212 | 
            +
                puts "   get       Download resource"
         | 
| 213 | 
            +
                puts "   put       Upload local file"
         | 
| 104 214 | 
             
                puts "   propfind  Print webdav properties for url"
         | 
| 105 215 | 
             
                puts "   mkcol     Make collection"
         | 
| 106 216 | 
             
                puts "   options   Display webservers WebDAV options"
         | 
| 217 | 
            +
                puts "   edit      Edit contents of remote file with editor"
         | 
| 107 218 | 
             
                puts ""
         | 
| 108 219 | 
             
                puts "See '#{$0} COMMAND -h' for more information on a specific command."
         | 
| 109 220 | 
             
                exit
         | 
| @@ -115,7 +226,7 @@ class DavCLI | |
| 115 226 |  | 
| 116 227 | 
             
                command =  args[0]
         | 
| 117 228 |  | 
| 118 | 
            -
                if(command == "-h" or command =~ /help/ or command =~ /\?/) then
         | 
| 229 | 
            +
                if(args.size == 0 or command == "-h" or command =~ /help/ or command =~ /\?/) then
         | 
| 119 230 | 
             
                  print_dav_usage
         | 
| 120 231 | 
             
                end
         | 
| 121 232 |  | 
| @@ -126,6 +237,12 @@ class DavCLI | |
| 126 237 |  | 
| 127 238 | 
             
                args = args[1..100]
         | 
| 128 239 | 
             
                case command
         | 
| 240 | 
            +
                  when "put" then
         | 
| 241 | 
            +
                    PutCLI.put(args)
         | 
| 242 | 
            +
                  when "get" then
         | 
| 243 | 
            +
                    get(args)
         | 
| 244 | 
            +
                  when "edit" then
         | 
| 245 | 
            +
                    edit(args)
         | 
| 129 246 | 
             
                  when "cat" then
         | 
| 130 247 | 
             
                    cat(args)
         | 
| 131 248 | 
             
                  when "ls" then
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification 
         | 
| 2 2 | 
             
            name: davclient
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            -
              version: 0.0. | 
| 4 | 
            +
              version: 0.0.5
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors: 
         | 
| 7 7 | 
             
            - Thomas Flemming
         | 
| @@ -9,7 +9,7 @@ autorequire: | |
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 11 |  | 
| 12 | 
            -
            date: 2009-09- | 
| 12 | 
            +
            date: 2009-09-18 00:00:00 +02:00
         | 
| 13 13 | 
             
            default_executable: 
         | 
| 14 14 | 
             
            dependencies: 
         | 
| 15 15 | 
             
            - !ruby/object:Gem::Dependency 
         |