diff --git a/lib/qasim.rb b/lib/qasim.rb index 232ca7e..855edb1 100644 --- a/lib/qasim.rb +++ b/lib/qasim.rb @@ -12,11 +12,3 @@ require 'qasim/config' require 'qasim/map' require 'qasim/map_manager' -## Plugins for maps -require 'qasim/map/generic' -require 'qasim/map/smb' -require 'qasim/map/ssh' -require 'qasim/map/webdav' - - - diff --git a/lib/qasim/gui.rb b/lib/qasim/gui.rb index ad26b58..166d93c 100644 --- a/lib/qasim/gui.rb +++ b/lib/qasim/gui.rb @@ -2,10 +2,7 @@ require 'qasim/qasim_qrc' require 'qasim/ui' module Qasim - class QasimApp - def initialize - end - end + class QasimApp ; end class QasimGui < QasimApp @@ -58,13 +55,15 @@ module Qasim previous_host = nil @map_manager.sort do |mx,my| - mx.host <=> my.host + mx.name <=> my.name end.each do |map| - if map.host != previous_host and not previous_host.nil? then - @map_menu.addSeparator - end + #if map.host != previous_host and not previous_host.nil? then + # @map_menu.addSeparator + #end itemx = Qt::Action.new(map.name, @map_menu) itemx.setCheckable true; + + #puts "Loading #{map.inspect}" if map.mounted? then itemx.setChecked true end @@ -72,7 +71,7 @@ module Qasim action_trigger_map_item map, itemx end @map_menu.addAction itemx; - previous_host = map.host + #previous_host = map.name end end @@ -80,8 +79,8 @@ module Qasim # Action when map item triggered # def action_trigger_map_item map, item - @connect_error[map.path] = Set.new - @connect_running[map.path] = 0 + @connect_error[map.filename] = Set.new + @connect_running[map.filename] = 0 method = if map.mounted? then :umount else :mount end @@ -91,14 +90,14 @@ module Qasim process = Qt::Process.new process.connect(SIGNAL('finished(int, QProcess::ExitStatus)')) do |exitcode,exitstatus| #puts "exitcode = %s, exitstatus = %s" % [exitcode, exitstatus] - @connect_running[map.path] -= 1 + @connect_running[map.filename] -= 1 if exitcode != 0 then - @connect_error[map.path].add linkname + @connect_error[map.filename].add linkname else end - if @connect_running[map.path] == 0 then + if @connect_running[map.filename] == 0 then # display someting - if @connect_error[map.path].empty? then + if @connect_error[map.filename].empty? then dbus_notify "%s (%s)" % [APP_NAME, map.name], ("Map %sed successfully" % method.to_s), diff --git a/lib/qasim/map.rb b/lib/qasim/map.rb index eb5ee45..9b89926 100644 --- a/lib/qasim/map.rb +++ b/lib/qasim/map.rb @@ -1,6 +1,7 @@ require 'fileutils' require 'qasim/map/generic' +require 'qasim/map/smb' require 'qasim/map/ssh' require 'qasim/map/webdav' @@ -12,7 +13,9 @@ module Qasim ; module Map def class_for type plugin = nil ObjectSpace.each_object(Class) do |cls| + if cls < Qasim::Map::Generic then + puts "Searching #{type} in " + cls.handles.inspect plugin = cls if cls.handles.include? type.to_sym end end diff --git a/lib/qasim/map/generic.rb b/lib/qasim/map/generic.rb index 0d82203..e9989c7 100644 --- a/lib/qasim/map/generic.rb +++ b/lib/qasim/map/generic.rb @@ -8,8 +8,7 @@ module Qasim ; module Map; class Generic attr_reader :name def initialize app_config, params - @app_config = app_config - + @app_config = app_config @links = params[:links] params.delete :links @@ -26,13 +25,106 @@ module Qasim ; module Map; class Generic # Format : # Hash of (name:Symbol * [value:Object, optional:Boolean]) def self.parameters - { + return { map_name: [nil , true], map_enable: [true, false], map_mountpoint: [nil, true] } end + # + # Test if mount list include some path & fs type + # + def mount_include? fs_type, local_path + f = File.open("/proc/mounts") + fs_mounts = (f.readlines.select do |line| + line =~ /\s+#{fs_type}\s+/ + end).map do |line| + line.split(/\s+/)[1] + end + f.close + fs_mounts.include? local_path + end + + + # + # Test if map is connected / mounted + # + def mounted? + score = @links.size + @links.each do |name, remotepath| + local_path = File.join @app_config.mount_dir, name + + if mount_include?(self.mount_id, local_path) then + score -= 1 + end + end + + # FIXME: handle the case of partial mounts (for remount/umount) + return true if score == 0 + return false + end + + # + # Connect all maps + # + def mount &block + @links.each do |name, remotepath| + mount_link(name, remotepath) + if block_given? then + yield name, cmd, cmd_args + else + system cmd, cmd_args + if $?.exitstatus != 0 then + raise ConnectError, self + end + end + end + end + + + # + # Disconnect all maps + # + def umount &block + @links.each do |name, remotepath| + localpath = File.join ENV['HOME'], "mnt", name + cmd = "fusermount" + cmd_args = [ + "-u", #umount + "-z" ,#lazy + localpath ] + if block_given? then + yield name, cmd, cmd_args + else + system cmd, cmd_args + if $?.exitstatus != 0 then + raise ConnectError, self + end + end + end + end + + + # + # Connect a single map + # + # MUST BE IMPLEMENTED BY SUBCLASSES + # + def mount_link name, remotepath + raise NotImplementedError + end + + + # + # Return the name of fuse helper (show in mount list) + # + # MUST BE IMPLEMENTED BY SUBCLASSES + # + def mount_id + raise NotImplementedError + end + # # Test map liveness (connected & working) # @@ -41,31 +133,4 @@ module Qasim ; module Map; class Generic def alive? raise NotImplementedError end - - # - # Test map - # - # MUST BE IMPLEMENTED BY SUBCLASSES - # - def mounted? - raise NotImplementedError - end - - # - # Mount - # - # MUST BE IMPLEMENTED BY SUBCLASSES - # - def mount - raise NotImplementedError - end - - # - # Umount - # - # MUST BE IMPLEMENTED BY SUBCLASSES - # - def umount - raise NotImplementedError - end end ; end ; end diff --git a/lib/qasim/map/smb.rb b/lib/qasim/map/smb.rb index 6edae76..5828b3f 100644 --- a/lib/qasim/map/smb.rb +++ b/lib/qasim/map/smb.rb @@ -3,7 +3,7 @@ require 'fileutils' require 'qasim/map/generic' -module Qasim; module Map; class Webdav < Qasim::Map::Generic +module Qasim; module Map; class Samba < Qasim::Map::Generic def initialize *opts super end @@ -16,7 +16,38 @@ module Qasim; module Map; class Webdav < Qasim::Map::Generic end def self.handles - [ :samba, :cifs, :smb ] + return [ :samba, :cifs, :smb ] end + + def mount_id + return "fuse.fusesmb" + end + + def mount_link name, remotepath + localpath = File.join ENV['HOME'], "mnt", name + FileUtils.mkdir_p localpath + cmd = "sshfs" + cmd_args = [ + "-o","allow_root" , + "-o","idmap=user" , + "-o","uid=%s" % Process.uid, + "-o","gid=%s" % Process.gid, + "-o","reconnect", # auto-reconnection + "-o","workaround=all", + "-o","cache_timeout=900", # 15 min cache for files + "-o","cache_stat_timeout=1800", # 30 min cache for directories + "-o","cache_link_timeout=1800", # 30 min cache for links + "-o","attr_timeout=1800", # 30 min attr cache + "-o","entry_timeout=1800", # 30 min entry cache + "-o","ServerAliveInterval=15", # prevent I/O hang + "-o","ServerAliveCountMax=3", # prevent I/O hang + "-o","no_readahead", + #"-o","Ciphers=arcfour", # force cypher + "-o","Port=%s" % @params[:ssh_port], + "%s@%s:%s" % [@params[:ssh_user],@params[:ssh_host],remotepath], + localpath ] + STDERR.puts cmd + ' ' + cmd_args.join(' ') + end + end ; end ; end diff --git a/lib/qasim/map/ssh.rb b/lib/qasim/map/ssh.rb index bdb1dd6..132b912 100644 --- a/lib/qasim/map/ssh.rb +++ b/lib/qasim/map/ssh.rb @@ -29,7 +29,7 @@ module Qasim ; module Map ; class Ssh < Qasim::Map::Generic end def self.handles - [ :ssh, :sshfs ] + return [ :ssh, :sshfs ] end # @@ -39,96 +39,44 @@ module Qasim ; module Map ; class Ssh < Qasim::Map::Generic super end - def mount_include? fs_type, local_path - f = File.open("/proc/mounts") - fs_mounts = (f.readlines.select do |line| - line =~ /\s+#{fs_type}\s+/ - end).map do |line| - line.split(/\s+/)[1] - end - f.close - fs_mounts.include? local_path + + def mount_id + return "fuse.sshfs" end # - # Test if map is connected / mounted + # Connect single map # - def mounted? - score = @links.size - @links.each do |name, remotepath| - local_path = File.join @app_config.mount_dir, name - - if mount_include?("fuse.sshfs", local_path) then - score -= 1 - end - end - # FIXME: handle the case of partial mounts (for remount/umount) - return true if score == 0 - return false - end + # FIXME: test connexion with Net::SSH + timeout or ask password + def mount_link name, remotepath + localpath = File.join ENV['HOME'], "mnt", name + FileUtils.mkdir_p localpath + cmd = "sshfs" + cmd_args = [ + "-o","allow_root" , + "-o","idmap=user" , + "-o","uid=%s" % Process.uid, + "-o","gid=%s" % Process.gid, + "-o","reconnect", # auto-reconnection + "-o","workaround=all", + "-o","cache_timeout=900", # 15 min cache for files + "-o","cache_stat_timeout=1800", # 30 min cache for directories + "-o","cache_link_timeout=1800", # 30 min cache for links + "-o","attr_timeout=1800", # 30 min attr cache + "-o","entry_timeout=1800", # 30 min entry cache + "-o","ServerAliveInterval=15", # prevent I/O hang + "-o","ServerAliveCountMax=3", # prevent I/O hang + "-o","no_readahead", + #"-o","Ciphers=arcfour", # force cypher + "-o","Port=%s" % @params[:ssh_port], + "%s@%s:%s" % [@params[:ssh_user],@params[:ssh_host],remotepath], + localpath ] + STDERR.puts cmd + ' ' + cmd_args.join(' ') + end + - # - # Connect map - # - def mount &block - # FIXME: test connexion with Net::SSH + timeout or ask password - @links.each do |name, remotepath| - localpath = File.join ENV['HOME'], "mnt", name - FileUtils.mkdir_p localpath - cmd = "sshfs" - cmd_args = [ - "-o","allow_root" , - "-o","idmap=user" , - "-o","uid=%s" % Process.uid, - "-o","gid=%s" % Process.gid, - "-o","reconnect", # auto-reconnection - "-o","workaround=all", - "-o","cache_timeout=900", # 15 min cache for files - "-o","cache_stat_timeout=1800", # 30 min cache for directories - "-o","cache_link_timeout=1800", # 30 min cache for links - "-o","attr_timeout=1800", # 30 min attr cache - "-o","entry_timeout=1800", # 30 min entry cache - "-o","ServerAliveInterval=15", # prevent I/O hang - "-o","ServerAliveCountMax=3", # prevent I/O hang - "-o","no_readahead", - #"-o","Ciphers=arcfour", # force cypher - "-o","Port=%s" % @params[:ssh_port], - "%s@%s:%s" % [@params[:ssh_user],@params[:ssh_host],remotepath], - localpath ] - STDERR.puts cmd + ' ' + cmd_args.join(' ') - if block_given? then - yield name, cmd, cmd_args - else - system cmd, cmd_args - if $?.exitstatus != 0 then - raise ConnectError, self - end - end - end - end - # - # Disconnect map - # - def umount &block - @links.each do |name, remotepath| - localpath = File.join ENV['HOME'], "mnt", name - cmd = "fusermount" - cmd_args = [ - "-u", #umount - "-z" ,#lazy - localpath ] - if block_given? then - yield name, cmd, cmd_args - else - system cmd, cmd_args - if $?.exitstatus != 0 then - raise ConnectError, self - end - end - end - end end ; end ; end diff --git a/lib/qasim/map/webdav.rb b/lib/qasim/map/webdav.rb index fb76501..7164405 100644 --- a/lib/qasim/map/webdav.rb +++ b/lib/qasim/map/webdav.rb @@ -10,16 +10,23 @@ module Qasim; module Map; class Webdav < Qasim::Map::Generic def self.parameters super.merge({ + webdav_host: { required: true}, # ex : http, https webdav_user: { required: true}, # ex : foo webdav_password: { required: true}, # ex : bar webdav_port: { default: 80}, # ex : 80, 8080, 443 - webdav_protocol: { default: :http} # ex : http, https + webdav_protocol: { default: :http}, # ex : http, https + webdav_path: { default: '/'} # ex : http, https }) end def self.handles - [ :webdav, :webdavs ] + return [ :webdav, :webdavs ] end + + def mount_id + return "fuse.fusedav" + end + end ; end ; end