qasim 0.1.11.dev.2014102811

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +31 -0
  3. data/Gemfile +7 -0
  4. data/LICENSE-GPL-3 +674 -0
  5. data/Makefile +180 -0
  6. data/README.md +81 -0
  7. data/Rakefile +1 -0
  8. data/TODO.md +28 -0
  9. data/bin/qasim-cli +89 -0
  10. data/bin/qasim-gui +300 -0
  11. data/conf/config +2 -0
  12. data/conf/default.map +32 -0
  13. data/conf/qasim.desktop +13 -0
  14. data/data/icons/qasim.128.png +0 -0
  15. data/data/icons/qasim.16.png +0 -0
  16. data/data/icons/qasim.256.png +0 -0
  17. data/data/icons/qasim.32.png +0 -0
  18. data/data/icons/qasim.64.png +0 -0
  19. data/data/icons/qasim.png +0 -0
  20. data/data/icons/qasim.svg +192 -0
  21. data/data/text/authors.html +7 -0
  22. data/data/text/gpl-3.0-standalone.html +694 -0
  23. data/data/text/thanks.html +0 -0
  24. data/debian/changelog +73 -0
  25. data/debian/compat +1 -0
  26. data/debian/control +13 -0
  27. data/debian/copyright +38 -0
  28. data/debian/dirs +3 -0
  29. data/debian/docs +0 -0
  30. data/debian/rules +80 -0
  31. data/debian/source/format +1 -0
  32. data/demo.map +29 -0
  33. data/examples/config +2 -0
  34. data/examples/default.map +32 -0
  35. data/lib/qasim.rb +11 -0
  36. data/lib/qasim/config.rb +56 -0
  37. data/lib/qasim/configold.rb +123 -0
  38. data/lib/qasim/constants.rb +11 -0
  39. data/lib/qasim/map.rb +225 -0
  40. data/lib/qasim/qasim.qrc +8 -0
  41. data/lib/qasim/ui.rb +7 -0
  42. data/lib/qasim/ui/about.rb +58 -0
  43. data/lib/qasim/ui/about.ui +192 -0
  44. data/lib/qasim/ui/listmaps.ui +59 -0
  45. data/lib/qasim/ui/preferences.rb +12 -0
  46. data/lib/qasim/ui/preferences.ui +90 -0
  47. data/lib/qasim/version.rb +5 -0
  48. data/man/qasim-cli.1 +98 -0
  49. data/man/qasim-gui.1 +98 -0
  50. data/man/sshfs-mapper.1 +98 -0
  51. data/mapparser.y +155 -0
  52. data/qasim.gemspec +34 -0
  53. data/sshfs-mapper.completion +24 -0
  54. data/sshfs-mapper.sh +253 -0
  55. metadata +147 -0
@@ -0,0 +1,11 @@
1
+ module Qasim
2
+ APP_ICON_PATH = File.join QASIM_DATA_DIR, "icons"
3
+
4
+ APP_SYSCONFIG_DIR = "/etc/qasim/maps.d"
5
+
6
+ APP_CONFIG_DIR = if ENV['XDG_CONFIG_HOME'] then
7
+ File.join ENV['XDG_CONFIG_HOME'], 'qasim'
8
+ else
9
+ File.join ENV['HOME'], '.config', 'qasim'
10
+ end
11
+ end
data/lib/qasim/map.rb ADDED
@@ -0,0 +1,225 @@
1
+
2
+ require 'fileutils'
3
+
4
+ #require 'rdebug/base'
5
+ require 'qasim'
6
+
7
+ module Qasim
8
+
9
+ class Map
10
+ attr_reader :path,
11
+ :host,
12
+ :port,
13
+ :enable,
14
+ :user,
15
+ :map,
16
+ :name
17
+
18
+ class MapParseError < RuntimeError ; end
19
+ class ConnectError < RuntimeError ; end
20
+
21
+ CYPHER_ARCFOUR = :arcfour
22
+ CYPHER_AES256CBC = "aes-256-cbc".to_sym
23
+ CYPHERS = [ CYPHER_ARCFOUR, CYPHER_AES256CBC ]
24
+
25
+
26
+ #
27
+ # Set defaults properties for maps
28
+ #
29
+ def initialize config, map_path
30
+ @config = config
31
+ @path = map_path
32
+ @host = nil
33
+ @port = 22
34
+ @enable = false
35
+ @user = nil
36
+ @cypher = :arcfour
37
+ @links = {}
38
+ @debug = false
39
+ @name = (File.basename map_path).gsub(/\.map$/,'')
40
+
41
+ self.load @path
42
+ end
43
+
44
+
45
+ #
46
+ # Load map description from file
47
+ #
48
+ def load path=nil
49
+ @path=path unless path.nil?
50
+ #rdebug "Parsing map #{@path}"
51
+ f = File.open @path
52
+ linect = 0
53
+ local_env = ENV.clone
54
+ f.each do |line|
55
+ line = line.strip
56
+ linect += 1
57
+
58
+ while line =~ /\$(\w+)/ do
59
+ #puts "FOUND PATTERN %s => %s" % [$1, local_env[$1]]
60
+ case line
61
+ when /\$\{(.+)\}/ then
62
+ pattern = $1
63
+ puts pattern
64
+ line.gsub!(/\$\{#{pattern}\}/,local_env[pattern])
65
+ when /\$(\w+)/ then
66
+ pattern = $1
67
+ line.gsub!(/\$#{pattern}/,local_env[pattern])
68
+ else
69
+ puts "w: unknown pattern: %s" % line
70
+ end
71
+ end
72
+
73
+ case line
74
+ when /^\s*REMOTE_USER\s*=\s*(.*)\s*$/ then
75
+ @user = $1
76
+ #rdebug "d: remote_user => #{$1}"
77
+ when /^\s*REMOTE_PORT\s*=\s*(.*)\s*$/ then
78
+ @port = $1.to_i
79
+ #rdebug "d: remote_port => #{$1}"
80
+ when /^\s*REMOTE_HOST\s*=\s*(.*)\s*$/ then
81
+ @host = $1
82
+ #rdebug "d: remote_host => #{$1}"
83
+ when /^\s*REMOTE_CYPHER\s*=\s*(.*)\s*$/ then
84
+ if CYPHERS.map{|x| x.to_s}.include? $1 then
85
+ @host = $1.to_sym
86
+ end
87
+ when /^\s*MAP\s*=\s*(.*)\s+(.*)\s*$/ then
88
+ @links[$1] = $2
89
+ #rdebug "d: link #{$1} => #{$2}"
90
+ when /^\s*$/,/^\s*#/ then
91
+ #rdebug "d: dropping empty line"
92
+ else
93
+ raise MapParseError, "parse error at #{@path}:#{linect}"
94
+ end
95
+ end
96
+ f.close
97
+ end
98
+
99
+
100
+ #
101
+ # Write map description to file
102
+ #
103
+ def write path=nil
104
+ @path=path unless path.nil?
105
+
106
+ File.open(@path, "w") do |f|
107
+ f.puts "REMOTE_USER=%s" % @user
108
+ f.puts "REMOTE_PORT=%s" % @port
109
+ f.puts "REMOTE_HOST=%s" % @host
110
+ f.puts "REMOTE_CYPHER=%s" % @cypher
111
+ end
112
+ end
113
+
114
+
115
+ #
116
+ # Test map liveness (how ?)
117
+ # FIXME: not implemented
118
+ #
119
+ def online?
120
+ #rdebug "testing online? %s " % self.inspect
121
+ #FIXME: test liveness
122
+ end
123
+
124
+
125
+ #
126
+ # Test if map is connected / mounted
127
+ #
128
+ def connected?
129
+ f = File.open("/proc/mounts")
130
+ sshfs_mounted = (f.readlines.select do |line|
131
+ line =~ /\s+fuse.sshfs\s+/
132
+ end).map do |line|
133
+ line.split(/\s+/)[1]
134
+ end
135
+ f.close
136
+
137
+ score = 0
138
+ @links.each do |name, remotepath|
139
+ score += 1
140
+ local_path = File.join @config.mnt_dir, name
141
+
142
+ if sshfs_mounted.include? local_path then
143
+ score -= 1
144
+ end
145
+ end
146
+ if score == 0 then return true
147
+ else return false
148
+ # FIXME: explain why ?
149
+ end
150
+ end
151
+
152
+
153
+ #
154
+ # Connect map
155
+ #
156
+ def connect &block
157
+ puts "[#{File.basename @path}] Connecting..."
158
+ puts " #{@user}@#{@host}:#{@port}"
159
+ #puts " links = %s" % @links.map{ |k,v| "%s => %s" % [ k, v ] }.join(', ')
160
+ # do something
161
+ # test server connection
162
+ # mount
163
+ #
164
+ # FIXME: test connexion with Net::SSH + timeout or ask password
165
+ @links.each do |name, remotepath|
166
+ localpath = File.join ENV['HOME'], "mnt", name
167
+ FileUtils.mkdir_p localpath
168
+ cmd = "sshfs"
169
+ cmd_args = [
170
+ "-o","allow_root" ,
171
+ "-o","idmap=user" ,
172
+ "-o","uid=%s" % Process.uid,
173
+ "-o","gid=%s" % Process.gid,
174
+ "-o","reconnect", # auto-reconnection
175
+ "-o","workaround=all",
176
+ "-o","cache_timeout=900", # 15 min cache for files
177
+ "-o","cache_stat_timeout=1800", # 30 min cache for directories
178
+ "-o","cache_link_timout=1800", # 30 min cache for links
179
+ "-o","attr_timeout=1800", # 30 min attr cache
180
+ "-o","entry_timeout=1800", # 30 min entry cache
181
+ "-o","ServerAliveInterval=15", # prevent I/O hang
182
+ "-o","ServerAliveCountMax=3", # prevent I/O hang
183
+ "-o","no_readahead",
184
+ #"-o","Ciphers=arcfour", # force cypher
185
+ "-o","Port=%s" % @port,
186
+ "%s@%s:%s" % [@user,@host,remotepath],
187
+ localpath ]
188
+ #rdebug "command: %s" % [ cmd, cmd_args ].flatten.join(' ')
189
+ if block_given? then
190
+ yield name, cmd, cmd_args
191
+ else
192
+ system cmd, cmd_args
193
+ if $?.exitstatus != 0 then
194
+ raise ConnectError, self
195
+ end
196
+ end
197
+ end
198
+ end
199
+
200
+
201
+ #
202
+ # Disconnect map
203
+ #
204
+ def disconnect &block
205
+ puts "Disconnecting map #{@path}"
206
+ @links.each do |name, remotepath|
207
+ localpath = File.join ENV['HOME'], "mnt", name
208
+ cmd = "fusermount"
209
+ cmd_args = [
210
+ "-u", #umount
211
+ "-z" ,#lazy
212
+ localpath ]
213
+ #rdebug "command: %s" % [ cmd, cmd_args ].flatten.join(' ')
214
+ if block_given? then
215
+ yield name, cmd, cmd_args
216
+ else
217
+ system cmd, cmd_args
218
+ if $?.exitstatus != 0 then
219
+ raise ConnectError, self
220
+ end
221
+ end
222
+ end
223
+ end
224
+ end
225
+ end
@@ -0,0 +1,8 @@
1
+ <RCC>
2
+ <qresource prefix="qasim">
3
+ <file alias="authors">../../data/text/authors.html</file>
4
+ <file alias="thanks">../../data/text/thanks.html</file>
5
+ <file alias="licence-gpl3">../../data/text/gpl-3.0-standalone.html</file>
6
+ <file alias="qasim-icon">../../data/icons/qasim.svg</file>
7
+ </qresource>
8
+ </RCC>
data/lib/qasim/ui.rb ADDED
@@ -0,0 +1,7 @@
1
+
2
+ require 'qasim/constants'
3
+
4
+ module Qasim ; module Ui
5
+ autoload :About, 'qasim/ui/about'
6
+ autoload :Preferences, 'qasim/ui/preferences'
7
+ end ; end
@@ -0,0 +1,58 @@
1
+
2
+ require 'qasim/ui/about_ui'
3
+
4
+ module Qasim ; module Ui
5
+ class About < Qt::Dialog
6
+ def initialize(parent = nil)
7
+ super
8
+ @ui = Ui_About.new
9
+ @ui.setup_ui(self)
10
+
11
+ #FIXME: attach button events to dialog.close
12
+ #Qt::Object.connect( w, SIGNAL( :clicked ), a, SLOT( :quit ) )
13
+
14
+ # Change title according to current version
15
+ title_str = "Qasim v%s (%s)" % [ Qasim::APP_VERSION, Qasim::APP_DATE ]
16
+ @ui.title_label.text = Qt::Application.translate(
17
+ "About",
18
+ title_str,
19
+ nil,
20
+ Qt::Application::UnicodeUTF8
21
+ )
22
+
23
+ # Read Authors
24
+ file = Qt::File.new(':/qasim/authors')
25
+ if file.open(Qt::File::ReadOnly | Qt::File::Text)
26
+ stream = Qt::TextStream.new( file )
27
+ @ui.authors_textedit.text = stream.readAll()
28
+ file.close
29
+ else
30
+ # FIXME handle error on authors reading
31
+ end
32
+
33
+ # Read Thanks
34
+ file = Qt::File.new(':/qasim/thanks')
35
+ if file.open(Qt::File::ReadOnly | Qt::File::Text)
36
+ stream = Qt::TextStream.new( file )
37
+ @ui.thanks_textedit.text = stream.readAll()
38
+ file.close
39
+ else
40
+ # FIXME handle error on thanks reading
41
+ end
42
+
43
+ # Read License
44
+ file = Qt::File.new(':/qasim/licence-gpl3')
45
+ if file.open(Qt::File::ReadOnly | Qt::File::Text)
46
+ stream = Qt::TextStream.new( file )
47
+ @ui.license_textedit.text = stream.readAll()
48
+ file.close
49
+ else
50
+ # FIXME handle error on licence reading
51
+ end
52
+
53
+ # set first tab
54
+ @ui.tab_widget.setCurrentIndex(0)
55
+ end
56
+
57
+ end
58
+ end ; end
@@ -0,0 +1,192 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <ui version="4.0">
3
+ <class>About</class>
4
+ <widget class="QDialog" name="About">
5
+ <property name="geometry">
6
+ <rect>
7
+ <x>0</x>
8
+ <y>0</y>
9
+ <width>470</width>
10
+ <height>500</height>
11
+ </rect>
12
+ </property>
13
+ <property name="windowTitle">
14
+ <string>About</string>
15
+ </property>
16
+ <property name="windowIcon">
17
+ <iconset resource="../qasim.qrc">
18
+ <normaloff>:/qasim/qasim-icon</normaloff>:/qasim/qasim-icon</iconset>
19
+ </property>
20
+ <property name="sizeGripEnabled">
21
+ <bool>true</bool>
22
+ </property>
23
+ <layout class="QVBoxLayout" name="verticalLayout_2">
24
+ <item>
25
+ <layout class="QVBoxLayout" name="vertical_layout">
26
+ <item>
27
+ <layout class="QHBoxLayout" name="horizontal_layout">
28
+ <item>
29
+ <widget class="QLabel" name="icon_label">
30
+ <property name="text">
31
+ <string/>
32
+ </property>
33
+ <property name="pixmap">
34
+ <pixmap resource="../qasim.qrc">:/qasim/qasim-icon</pixmap>
35
+ </property>
36
+ </widget>
37
+ </item>
38
+ <item>
39
+ <widget class="QLabel" name="title_label">
40
+ <property name="sizePolicy">
41
+ <sizepolicy hsizetype="Expanding" vsizetype="Maximum">
42
+ <horstretch>0</horstretch>
43
+ <verstretch>0</verstretch>
44
+ </sizepolicy>
45
+ </property>
46
+ <property name="font">
47
+ <font>
48
+ <weight>75</weight>
49
+ <bold>true</bold>
50
+ </font>
51
+ </property>
52
+ <property name="text">
53
+ <string>Qasim vVERSION (DATE)</string>
54
+ </property>
55
+ </widget>
56
+ </item>
57
+ </layout>
58
+ </item>
59
+ <item>
60
+ <widget class="QTabWidget" name="tab_widget">
61
+ <property name="currentIndex">
62
+ <number>0</number>
63
+ </property>
64
+ <widget class="QWidget" name="about_tab">
65
+ <attribute name="title">
66
+ <string>About</string>
67
+ </attribute>
68
+ <layout class="QGridLayout" name="gridLayout">
69
+ <item row="0" column="0">
70
+ <widget class="QLabel" name="about_label">
71
+ <property name="sizePolicy">
72
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
73
+ <horstretch>0</horstretch>
74
+ <verstretch>0</verstretch>
75
+ </sizepolicy>
76
+ </property>
77
+ <property name="minimumSize">
78
+ <size>
79
+ <width>300</width>
80
+ <height>200</height>
81
+ </size>
82
+ </property>
83
+ <property name="text">
84
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;A cross platform SSHFS Mapping tool.&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;Copyright © 2011-2012 The Qasim Team&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;br/&gt;&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;http://github.com/Glenux/Qasim&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0057ae;&quot;&gt;http://github.com/Glenux/Qasim&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
85
+ </property>
86
+ <property name="scaledContents">
87
+ <bool>false</bool>
88
+ </property>
89
+ <property name="margin">
90
+ <number>10</number>
91
+ </property>
92
+ </widget>
93
+ </item>
94
+ </layout>
95
+ </widget>
96
+ <widget class="QWidget" name="authors_tab">
97
+ <attribute name="title">
98
+ <string>Authors</string>
99
+ </attribute>
100
+ <layout class="QVBoxLayout" name="_2">
101
+ <item>
102
+ <widget class="QTextEdit" name="authors_textedit">
103
+ <property name="sizePolicy">
104
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
105
+ <horstretch>0</horstretch>
106
+ <verstretch>0</verstretch>
107
+ </sizepolicy>
108
+ </property>
109
+ <property name="html">
110
+ <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
111
+ &lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
112
+ p, li { white-space: pre-wrap; }
113
+ &lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
114
+ &lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
115
+ </property>
116
+ </widget>
117
+ </item>
118
+ </layout>
119
+ </widget>
120
+ <widget class="QWidget" name="thanks_tab">
121
+ <attribute name="title">
122
+ <string>Thanks to</string>
123
+ </attribute>
124
+ <layout class="QVBoxLayout" name="verticalLayout_4">
125
+ <item>
126
+ <widget class="QTextEdit" name="thanks_textedit"/>
127
+ </item>
128
+ </layout>
129
+ </widget>
130
+ <widget class="QWidget" name="license_tab">
131
+ <attribute name="title">
132
+ <string>License</string>
133
+ </attribute>
134
+ <layout class="QVBoxLayout" name="verticalLayout_5">
135
+ <item>
136
+ <widget class="QTextEdit" name="license_textedit">
137
+ <property name="minimumSize">
138
+ <size>
139
+ <width>300</width>
140
+ <height>200</height>
141
+ </size>
142
+ </property>
143
+ <property name="html">
144
+ <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
145
+ &lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
146
+ p, li { white-space: pre-wrap; }
147
+ &lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
148
+ &lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
149
+ </property>
150
+ </widget>
151
+ </item>
152
+ </layout>
153
+ </widget>
154
+ </widget>
155
+ </item>
156
+ </layout>
157
+ </item>
158
+ <item>
159
+ <widget class="QDialogButtonBox" name="button_box">
160
+ <property name="orientation">
161
+ <enum>Qt::Horizontal</enum>
162
+ </property>
163
+ <property name="standardButtons">
164
+ <set>QDialogButtonBox::Close</set>
165
+ </property>
166
+ </widget>
167
+ </item>
168
+ </layout>
169
+ </widget>
170
+ <resources>
171
+ <include location="../qasim.qrc"/>
172
+ <include location="../../../qasim.qrc"/>
173
+ </resources>
174
+ <connections>
175
+ <connection>
176
+ <sender>button_box</sender>
177
+ <signal>clicked(QAbstractButton*)</signal>
178
+ <receiver>About</receiver>
179
+ <slot>accept()</slot>
180
+ <hints>
181
+ <hint type="sourcelabel">
182
+ <x>463</x>
183
+ <y>493</y>
184
+ </hint>
185
+ <hint type="destinationlabel">
186
+ <x>469</x>
187
+ <y>12</y>
188
+ </hint>
189
+ </hints>
190
+ </connection>
191
+ </connections>
192
+ </ui>