require 'pstore' module RackWebDAV class FileResourceLock attr_accessor :path attr_accessor :token attr_accessor :timeout attr_accessor :depth attr_accessor :user attr_accessor :scope attr_accessor :kind attr_accessor :owner attr_reader :created_at attr_reader :root class << self def explicitly_locked?(path, croot=nil) store = init_pstore(croot) !!store.transaction(true){ store[:paths][path] } end def implicitly_locked?(path, croot=nil) store = init_pstore(croot) !!store.transaction(true){ store[:paths].keys.detect do |check| check.start_with?(path) end } end def explicit_locks(path, croot, args={}) end def implict_locks(path) end def find_by_path(path, croot=nil) lock = self.class.new(:path => path, :root => croot) lock.token.nil? ? nil : lock end def find_by_token(token, croot=nil) store = init_pstore(croot) struct = store.transaction(true){ store[:tokens][token] } if !struct struct = store.transaction(true) { store[:tokens].keys.each { |k| token = k if k.include?(token) } store[:tokens][token] } end if struct self.new(:path => struct[:path], :root => croot) else nil end end def generate(path, user, token, croot) lock = self.new(:root => croot) lock.user = user lock.path = path lock.token = token lock.save lock end def root=(path) @root = path end def root @root || '/tmp/rack-webdav' end def init_pstore(croot) path = File.join(croot, '.attribs', 'locks.pstore') FileUtils.mkdir_p(File.dirname(path)) unless File.directory?(File.dirname(path)) store = IS_18 ? PStore.new(path) : PStore.new(path, true) store.transaction do unless(store[:paths]) store[:paths] = {} store[:tokens] = {} store.commit end end store end end def initialize(args={}) @path = args[:path] @root = args[:root] @owner = args[:owner] @store = init_pstore(@root) @max_timeout = args[:max_timeout] || 86400 @default_timeout = args[:max_timeout] || 60 load_if_exists! @new_record = true if token.nil? end def owner?(user) user == owner end def reload load_if_exists self end def remaining_timeout t = timeout.to_i - (Time.now.to_i - created_at.to_i) t < 0 ? 0 : t end def save struct = { :path => path, :token => token, :timeout => timeout, :depth => depth, :created_at => Time.now, :owner => owner } @store.transaction do @store[:paths][path] = struct @store[:tokens][token] = struct @store.commit end @new_record = false self end def destroy @store.transaction do @store[:paths].delete(path) @store[:tokens].delete(token) @store.commit end nil end private def load_if_exists! struct = @store.transaction do @store[:paths][path] end if(struct) @path = struct[:path] @token = struct[:token] @timeout = struct[:timeout] @depth = struct[:depth] @created_at = struct[:created_at] @owner = struct[:owner] end self end def init_pstore(croot=nil) self.class.init_pstore(croot || @root) end end end