As a part of my idea of Yandex Disk as ActiveStorage service implementation, I decided to implement PROPPATCH method into yandex disk gem.
As described in webdav documentation - all what we need - make a special PROPPATCH request with PATH of our folder or file.
I’ve added simple feature here: publication branch with this functionality support.
Or you can use main repo, feature already merged to master branch.
Let’s take a look into WebDav request implementation as described above:
PROPPATCH /public_folder/readme.txt HTTP/1.1
User-Agent: my_application/0.0.1
Host: webdav.yandex.ru
Authorization: OAuth 0c4182a7c2cf4521964a72ff57a34a07
Content-Length: 158
<propertyupdate xmlns="DAV:">
<set>
<prop>
<public_url xmlns="urn:yandex:disk:meta">true</public_url>
</prop>
</set>
</propertyupdate>
Let’s take a look into my Yandex::Disk::Client::Request::Publication implementation:
require 'nokogiri'
class Yandex::Disk::Client::Request::Publication
BODY =
'<propertyupdate xmlns="DAV:">
<set>
<prop>
<public_url xmlns="urn:yandex:disk:meta">true</public_url>
</prop>
</set>
</propertyupdate>'
HEADERS = {
}
def initialize http, path
@http = http
@path = path
end
def perform
response = @http.run_request :proppatch, @path, BODY, HEADERS
parse_result = parse(response.body)
{ :public_url => parse_result.public_url }
end
private
class AttributesParser < Nokogiri::XML::SAX::Document
attr_reader :public_url
def start_element name, attributes = []
case name
when 'public_url'
@public_url = true
end
end
def characters string
@public_url = string if @public_url
end
end
def parse body
attributes_parser = AttributesParser.new
parser = Nokogiri::XML::SAX::Parser.new(attributes_parser)
parser.parse(body)
attributes_parser
end
end
One important thing here - we specify new :proppatch method for the Faraday request, and need to extend it like this:
Faraday::Connection::METHODS << :proppatch
Let’s create sample example, and make our file public:
irb(main):001:0> client = Yandex::Disk::Client.new(:access_token => 'XXXXXXXXXX')
=> #<Yandex::Disk::Client:0x00007ffd5c0bd5b8 @timeout=300, @http=#<Faraday::Connection:0x00007ffd5c0bd4a0 @parallel_manager=nil, @headers={"User-Agent"=>"Faraday v0.9.2"}, @params={}, @options=#<Faraday::RequestOptions (empty)>, @ssl=#<Faraday::SSLOptions (empty)>, @default_parallel_manager=nil, @builder=#<Faraday::RackBuilder:0x00007ffd5c0bd180 @handlers=[Faraday::Request::Authorization, Faraday::Adapter::Excon]>, @url_prefix=#<URI::HTTPS https://webdav.yandex.ru/>, @proxy=nil>>
irb(main):002:0> client.make_public('/FOLDER/file.png')
=> {:public_url=>"https://yadi.sk/i/XXXXXX"}
Great, now file marked as public, and we can access it via provided URL.