This is an implementation for some of the basic operations to communicate with a WebDAV server using Nim.
The client is synchronous and is built on top of
puppy. On Linux puppy uses libcurl, so
install it (e.g. libcurl4-openssl-dev) to build; macOS and Windows use the
native HTTP stack and need no extra dependency.
Example usage:
import webdavclient, tables
# Only Basic auth is currently supported. Make sure you're
# connecting over ssl.
let wd = newWebDAV(
address = "https://dav.example.com",
username = "username",
password = "password"
)
# Get the property names available for a resource (propname request)
let possibleProps = wd.props("/", depth = ZERO)
for href, names in possibleProps:
echo href, ": ", names
# List files.
# Default webdav properties don't require a namespace.
let t = wd.ls(
"/",
@[
"getcontentlength",
"getlastmodified",
"creationdate",
"getcontenttype",
"nc:has-preview",
"oc:favorite",
],
namespaces = @[
("oc", "http://owncloud.org/ns"),
("nc", "http://nextcloud.org/ns")
],
depth = ONE
)
for url, prop in t.pairs:
echo(url)
for pname, pval in prop.pairs:
echo(" - ", pname, ": ", pval)
echo("---")
# Download a file (buffered in memory, then written to disk)
wd.download(path = "files/example.md", destination = "/home/me/example.md")
# Upload a file
wd.upload(filepath = "files/example.md", destination = "/home/me/example.md")
# Delete a file
wd.rm("files/example.md")
# Create a collection (directory)
wd.mkdir("files/new/")
# Move a file
wd.mv(path = "files/example.md", destination = "files/new/example.md", overwrite = true)
# Copy a file
wd.cp(path = "files/new/example.md", destination = "files/example.md", overwrite = true)
# Set and/or remove properties (PROPPATCH)
discard wd.proppatch(
"files/example.md",
setProps = @[("oc:favorite", "1")],
removeProps = @["oc:tag"],
namespaces = @[("oc", "http://owncloud.org/ns")]
)
# Take an exclusive write lock (LOCK), then pass the token on writes that
# touch the locked resource. Without the token the server returns 423 Locked.
let lock = wd.lock("files/example.md", owner = "me")
wd.upload(filepath = "files/example.md", destination = "files/example.md", token = lock.token)
# Release the lock (UNLOCK)
wd.unlock("files/example.md", lock.token)