gestion 1.9.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (233) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +48 -0
  3. data/.project +14 -0
  4. data/Binaries/adduser_to_buzz +15 -0
  5. data/Binaries/backup +7 -0
  6. data/Binaries/check_gestion +8 -0
  7. data/Binaries/gestion.gnumail +22 -0
  8. data/Binaries/gestion.logrotate +34 -0
  9. data/Binaries/gestion.service +12 -0
  10. data/Binaries/gestion_update.rb +183 -0
  11. data/Binaries/gestion_update.service +10 -0
  12. data/Binaries/get_compta +11 -0
  13. data/Binaries/kill_gestion +16 -0
  14. data/Binaries/ldap/add_indexes +51 -0
  15. data/Binaries/ldap/backup +2 -0
  16. data/Binaries/ldap/install_ldap +92 -0
  17. data/Binaries/ldap/restore +7 -0
  18. data/Binaries/lib_backup +5 -0
  19. data/Binaries/log_scan_errors +8 -0
  20. data/Binaries/loop_gestion +64 -0
  21. data/Binaries/onetimers/sync_courses_from_compta.rb +74 -0
  22. data/Binaries/onetimers/transfer_cash_from_ldap_to_csv +26 -0
  23. data/Binaries/reboot +5 -0
  24. data/Binaries/restore +3 -0
  25. data/Binaries/restore_do +22 -0
  26. data/Binaries/sort_events +31 -0
  27. data/Binaries/start_gestion +18 -0
  28. data/Binaries/swipe_gestion +18 -0
  29. data/Binaries/update_africompta +21 -0
  30. data/Binaries/update_users +3 -0
  31. data/Diplomas.src/accredited.odg +0 -0
  32. data/Diplomas.src/diploma.odg +0 -0
  33. data/Diplomas.src/label.odg +0 -0
  34. data/Diplomas.src/presence_sheet.ods +0 -0
  35. data/Diplomas.src/presence_sheet_small.ods +0 -0
  36. data/Diplomas.src/student_card.odg +0 -0
  37. data/Doc/130514-it-ideas.odt +0 -0
  38. data/Doc/Compta-cash.mm +179 -0
  39. data/Doc/General.odt +0 -0
  40. data/Entities/AccessGroups.rb +117 -0
  41. data/Entities/Activity.rb +178 -0
  42. data/Entities/ChatMsg.rb +142 -0
  43. data/Entities/Classroom.rb +11 -0
  44. data/Entities/Client.rb +19 -0
  45. data/Entities/Computer.rb +21 -0
  46. data/Entities/ConfigBase.rb +280 -0
  47. data/Entities/Course.rb +1588 -0
  48. data/Entities/CourseType.rb +171 -0
  49. data/Entities/DFiles.rb +466 -0
  50. data/Entities/FilesManage.rb +226 -0
  51. data/Entities/Grade.rb +186 -0
  52. data/Entities/Internet.rb +300 -0
  53. data/Entities/Netdev.rb +10 -0
  54. data/Entities/Person.rb +1175 -0
  55. data/Entities/Plug.rb +98 -0
  56. data/Entities/Quiz.rb +33 -0
  57. data/Entities/Recharges.rb +37 -0
  58. data/Entities/Report.rb +136 -0
  59. data/Entities/Room.rb +12 -0
  60. data/Entities/SMS.rb +30 -0
  61. data/Entities/ScheduleType.rb +33 -0
  62. data/Entities/Share.rb +120 -0
  63. data/Entities/Task.rb +51 -0
  64. data/Entities/Ticket.rb +72 -0
  65. data/Entities/Usage.rb +143 -0
  66. data/Entities/Worker.rb +29 -0
  67. data/Files/apache-profeda.conf +36 -0
  68. data/Files/label.erb +121 -0
  69. data/Files/label_notfound.erb +64 -0
  70. data/Files/label_notpassed.erb +84 -0
  71. data/Files/mobileinfo.erb +115 -0
  72. data/Files/smb.conf +333 -0
  73. data/Files/timetable.html +36 -0
  74. data/Files/timetable.js +239 -0
  75. data/Gemfile +12 -0
  76. data/Gemfile.dev +12 -0
  77. data/Gemfile.dev.lock +127 -0
  78. data/Gemfile.lock +127 -0
  79. data/Gemfile.prod +8 -0
  80. data/Gestion +35 -0
  81. data/Gestion.rb +220 -0
  82. data/INSTALL +40 -0
  83. data/Images/connection.xcf +0 -0
  84. data/Images/connection_no.png +0 -0
  85. data/Images/connection_wait.png +0 -0
  86. data/Images/connection_yes.png +0 -0
  87. data/Paths/Exas.rb +13 -0
  88. data/Paths/Files.rb +19 -0
  89. data/Paths/GetDiplomas.rb +20 -0
  90. data/Paths/Info.rb +114 -0
  91. data/Paths/Label.rb +187 -0
  92. data/Paths/MobileInfo.rb +19 -0
  93. data/Paths/internetCash.rb +34 -0
  94. data/Paths/internetWifi.rb +54 -0
  95. data/README.md +60 -0
  96. data/Rakefile +13 -0
  97. data/TODO +1391 -0
  98. data/Test/.gitignore +3 -0
  99. data/Test/Diplomas/base_gestion.odt +0 -0
  100. data/Test/Diplomas/base_report.odt +0 -0
  101. data/Test/Diplomas/carte_etudiant.odg +0 -0
  102. data/Test/Diplomas/exam_language.odt +0 -0
  103. data/Test/Diplomas/label.odg +0 -0
  104. data/Test/Diplomas/presence_sheet.ods +0 -0
  105. data/Test/Diplomas/presence_sheet_small.ods +0 -0
  106. data/Test/Diplomas/student_card.odg +0 -0
  107. data/Test/Manual/testMerge +18 -0
  108. data/Test/config_test.yaml +26 -0
  109. data/Test/db.testGestion +0 -0
  110. data/Test/dfiles/descs/avg-rescue.desc +10 -0
  111. data/Test/dfiles/descs/avg.desc +8 -0
  112. data/Test/dfiles/descs/driver.desc +8 -0
  113. data/Test/dfiles/descs/linuxmint.desc +7 -0
  114. data/Test/dfiles/files/avg-160203.exe +1 -0
  115. data/Test/dfiles/files/avg.iso +1 -0
  116. data/Test/dfiles/files/driver.exe +1 -0
  117. data/Test/dfiles/index_post.html +3 -0
  118. data/Test/dfiles/index_pre.html +8 -0
  119. data/Test/dfiles/priorities +5 -0
  120. data/Test/ge_activity.rb +124 -0
  121. data/Test/ge_chat.rb +106 -0
  122. data/Test/ge_compta.rb +67 -0
  123. data/Test/ge_configbase.rb +54 -0
  124. data/Test/ge_course.rb +1114 -0
  125. data/Test/ge_dfiles.rb +121 -0
  126. data/Test/ge_filesmanage.rb +180 -0
  127. data/Test/ge_info.rb +27 -0
  128. data/Test/ge_internet.rb +246 -0
  129. data/Test/ge_login.rb +55 -0
  130. data/Test/ge_person.rb +373 -0
  131. data/Test/ge_qvinfo.rb +28 -0
  132. data/Test/ge_report.rb +97 -0
  133. data/Test/ge_share.rb +27 -0
  134. data/Test/ge_sms.rb +34 -0
  135. data/Test/ge_tasks.rb +19 -0
  136. data/Test/ge_usage.rb +168 -0
  137. data/Test/ge_view.rb +46 -0
  138. data/Test/multiconf-captive +29 -0
  139. data/Test/test.conf +7 -0
  140. data/Test/test.rb +49 -0
  141. data/Test/test_bytes.png +0 -0
  142. data/VERSION +140 -0
  143. data/Views/Admin/Backup.rb +91 -0
  144. data/Views/Admin/Configuration.rb +44 -0
  145. data/Views/Admin/Credit.rb +32 -0
  146. data/Views/Admin/FilesManage.rb +219 -0
  147. data/Views/Admin/Function.rb +39 -0
  148. data/Views/Admin/Power.rb +49 -0
  149. data/Views/Admin/Printer.rb +37 -0
  150. data/Views/Admin/Server.rb +252 -0
  151. data/Views/Admin/Tabs.rb +5 -0
  152. data/Views/Admin/Update.rb +73 -0
  153. data/Views/Admin/UpdateSystem.rb +26 -0
  154. data/Views/Cashbox/Activity.rb +191 -0
  155. data/Views/Cashbox/Course.rb +141 -0
  156. data/Views/Cashbox/Credit.rb +79 -0
  157. data/Views/Cashbox/Report.rb +115 -0
  158. data/Views/Cashbox/Service.rb +105 -0
  159. data/Views/Cashbox/Tabs.rb +10 -0
  160. data/Views/Compta/Accounts.rb +36 -0
  161. data/Views/Compta/Course.rb +96 -0
  162. data/Views/Compta/Show.rb +6 -0
  163. data/Views/Compta/Transfer.rb +66 -0
  164. data/Views/Course/Diploma.rb +203 -0
  165. data/Views/Course/Grade.rb +401 -0
  166. data/Views/Course/Modify.rb +447 -0
  167. data/Views/Course/Print.rb +94 -0
  168. data/Views/Course/Responsible.rb +44 -0
  169. data/Views/Course/Stats.rb +76 -0
  170. data/Views/Course/Students.rb +92 -0
  171. data/Views/Course/Tabs.rb +220 -0
  172. data/Views/Internet/Access.rb +134 -0
  173. data/Views/Internet/ClassEdit.rb +24 -0
  174. data/Views/Internet/ClassUsers.rb +81 -0
  175. data/Views/Internet/Config.rb +32 -0
  176. data/Views/Internet/Mobile.rb +213 -0
  177. data/Views/Internet/Recharges.rb +49 -0
  178. data/Views/Internet/Tabs.rb +6 -0
  179. data/Views/Inventory/Computer.rb +24 -0
  180. data/Views/Inventory/Room.rb +18 -0
  181. data/Views/Inventory/Tabs.rb +9 -0
  182. data/Views/Inventory/TicketClosed.rb +7 -0
  183. data/Views/Inventory/TicketOpen.rb +23 -0
  184. data/Views/Library/Person.rb +36 -0
  185. data/Views/Library/Tabs.rb +7 -0
  186. data/Views/Network/Block.rb +87 -0
  187. data/Views/Network/Netdevs.rb +21 -0
  188. data/Views/Network/Restriction.rb +37 -0
  189. data/Views/Network/Share.rb +167 -0
  190. data/Views/Network/Tables.rb +28 -0
  191. data/Views/Network/Tabs.rb +6 -0
  192. data/Views/Person/Admin.rb +99 -0
  193. data/Views/Person/Center.rb +48 -0
  194. data/Views/Person/Course.rb +72 -0
  195. data/Views/Person/Modify.rb +153 -0
  196. data/Views/Person/Tabs.rb +162 -0
  197. data/Views/Report/ComptaExecutive.rb +221 -0
  198. data/Views/Report/ComptaFlat.rb +79 -0
  199. data/Views/Report/ReportCourse.rb +47 -0
  200. data/Views/Report/Tabs.rb +8 -0
  201. data/Views/Report/Usage.rb +52 -0
  202. data/Views/Report/UsageCases.rb +59 -0
  203. data/Views/Self/Cash.rb +67 -0
  204. data/Views/Self/Chat.rb +55 -0
  205. data/Views/Self/Concours.rb +109 -0
  206. data/Views/Self/Email.rb +34 -0
  207. data/Views/Self/Internet.rb +255 -0
  208. data/Views/Self/Results.rb +17 -0
  209. data/Views/Self/Services.rb +85 -0
  210. data/Views/Self/Show.rb +47 -0
  211. data/Views/Self/Tabs.rb +5 -0
  212. data/Views/Special/DFileEdit.rb +13 -0
  213. data/Views/Special/PlugEdit.rb +56 -0
  214. data/Views/Special/Tabs.rb +6 -0
  215. data/Views/Special/Vnc.rb +39 -0
  216. data/Views/Task/Client.rb +21 -0
  217. data/Views/Task/Edit.rb +33 -0
  218. data/Views/Task/List.rb +55 -0
  219. data/Views/Task/Tabs.rb +9 -0
  220. data/Views/Task/Worker.rb +30 -0
  221. data/Views/Template/Activity.rb +33 -0
  222. data/Views/Template/CourseType.rb +63 -0
  223. data/Views/Template/ScheduleType.rb +29 -0
  224. data/Views/Template/Tabs.rb +5 -0
  225. data/Views/Welcome.rb +121 -0
  226. data/config.yaml.default +36 -0
  227. data/po/Gestion-ar.po +2356 -0
  228. data/po/Gestion-en.mo +0 -0
  229. data/po/Gestion-en.po +4363 -0
  230. data/po/Gestion-fr.mo +0 -0
  231. data/po/Gestion-fr.po +4345 -0
  232. data/po/traduction-ar.rtf +76 -0
  233. metadata +381 -0
@@ -0,0 +1,219 @@
1
+ # AdminFilesManage offers an interface to add files to the files.profeda.org
2
+ # site. Files are stored in a two-level structure: first os, then
3
+ # categories. A possible structure is as follows:
4
+ # Windows/Antivirus
5
+ # Windows/Office
6
+ # Mac/Office
7
+ # Mac/Utils
8
+ # Each file in the directory is accompanied by a .file that holds information
9
+ # about it like description, URL, tags.
10
+
11
+ class AdminFilesManage < View
12
+ attr_accessor :files_dir
13
+
14
+ def layout
15
+ @order = 50
16
+ @update = true
17
+ @functions_need = [:files_manage]
18
+
19
+ @files_dir = '/opt/Files'
20
+ gui_vbox do
21
+ gui_hboxg :nogroup do
22
+ gui_vbox :nogroup do
23
+ gui_vbox :nogroup do
24
+ show_list_single :dirs_os, callback: true, flexheight: 1
25
+ show_button :dirs_os_add, :dirs_os_del
26
+ end
27
+
28
+ gui_vbox :nogroup do
29
+ show_list_single :dirs_type, callback: true, flexheight: 1
30
+ end
31
+ end
32
+
33
+ gui_vbox :nogroup do
34
+ show_list_single :files_stored, '[]', callback: true, flexheight: 1
35
+ show_button :file_del
36
+ end
37
+
38
+ gui_vbox :nogroup do
39
+ show_str_ro :name, width: 300
40
+ show_str_ro :url_file
41
+ show_str :url_page
42
+ show_str :description
43
+ show_str :tags
44
+ show_button :file_save, :file_rename
45
+ end
46
+
47
+ gui_window :win_chose do
48
+ show_list :win_list
49
+ show_button :win_add_os
50
+ end
51
+
52
+ gui_window :win_rename do
53
+ show_str :new_name, width: 300
54
+ show_button :rename_ok, :cancel
55
+ end
56
+
57
+ gui_window :win_update do
58
+ show_html :update_txt
59
+ show_button :update_ok
60
+ end
61
+ end
62
+ gui_vbox :nogroup do
63
+ show_button :files_search, :files_update
64
+ end
65
+ end
66
+ end
67
+
68
+ def list_dirs(base)
69
+ Dir.glob("#{base}/*").collect { |d| d.gsub(/^#{base}\//, '') }.sort
70
+ end
71
+
72
+ def rpc_button_dirs_os_del(session, data)
73
+ dir = FMDirs.search_by_path(data._dirs_os.first)
74
+ return unless dir
75
+ dir.delete
76
+ rpc_update(session)
77
+ end
78
+
79
+ def rpc_button_dirs_os_add(session, data)
80
+ dirs = list_dirs(@files_dir)
81
+ FMDirs.base_dirs.each { |d|
82
+ dirs.delete(d._name)
83
+ }
84
+ reply(:window_show, :win_chose) +
85
+ reply(:empty_update, win_list: dirs)
86
+ end
87
+
88
+ def rpc_button_win_add_os(session, data)
89
+ data._win_list.each { |name|
90
+ if FMDirs.search_by_name(name).size == 0
91
+ FMDirs.create({name: name})
92
+ else
93
+ dputs(1) { "Os-dir #{name} already exists" }
94
+ end
95
+ }
96
+ reply(:window_hide) +
97
+ rpc_update(nil)
98
+ end
99
+
100
+ def rpc_button_files_update(session, data)
101
+ Thread.start {
102
+ System.run_bool "#{FMDirs.dir_base}/update_files do_dokuwiki"
103
+ }
104
+ rpc_update(session) +
105
+ reply(:window_show, :win_update) +
106
+ reply(:update, update_txt: 'Update might take quite some time<br>'+
107
+ 'Check on <a href="http://local.bardai.profeda.org" target="other">local.bardai.profeda.org</a>')
108
+ end
109
+
110
+ def rpc_button_files_search(session, data)
111
+ FMDirs.base_dirs.each { |d|
112
+ d.update_dirs
113
+ d.sub_dirs.each { |sub|
114
+ sub.update_files
115
+ }
116
+ }
117
+ end
118
+
119
+ def rpc_button_update_ok(session, data)
120
+ reply(:window_hide)
121
+ end
122
+
123
+ def rpc_button_file_save(session, data)
124
+ file = get_file(data)
125
+ return unless file
126
+ data._tags = (data._tags || '').split(/,/).map { |t| t.sub(/^ */, '') }
127
+ in_file { |f| file.data_set(f, data[f]) }
128
+ file.save_file(true)
129
+ rpc_list_choice_files_stored(session, data)
130
+ end
131
+
132
+ def rpc_button_file_del(session, data)
133
+ file = get_file(data)
134
+ return unless file
135
+ file.delete
136
+ rpc_list_choice_dirs_type(session, data)
137
+ end
138
+
139
+ def rpc_button_file_rename(session, data)
140
+ file = get_file(data)
141
+ return unless file
142
+ reply(:update, new_name: file.file_name) +
143
+ reply(:window_show, :win_rename)
144
+ end
145
+
146
+ def rpc_button_rename_ok(session, data)
147
+ file = get_file(data)
148
+ return unless file
149
+ file.rename(data._new_name)
150
+ reply(:window_hide) +
151
+ rpc_list_choice_dirs_type(session, data)
152
+ end
153
+
154
+ def rpc_button_cancel(session, data)
155
+ reply(:window_hide)
156
+ end
157
+
158
+ def rpc_update(session)
159
+ empty_fields(3) +
160
+ reply(:update, dirs_os: FMDirs.base_dirs.map { |f| f._name }.sort)
161
+ end
162
+
163
+
164
+ def rpc_list_choice_dirs_os(session, data)
165
+ return [] unless data._dirs_os.length > 0
166
+ dir = data._dirs_os.first
167
+ dirs = FMDirs.sub_dirs(dir).map { |f| f._name }.sort
168
+ empty_fields(2) +
169
+ reply(:update, dirs_type: dirs)
170
+ end
171
+
172
+ def rpc_list_choice_dirs_type(session, data)
173
+ return [] unless data._dirs_type.length > 0
174
+ dir = FMDirs.search_by_path(data._dirs_type.first, data._dirs_os.first)
175
+ entries = FMEntries.search_by_directory(dir)
176
+ empty_fields(1) +
177
+ reply(:update, files_stored: entries.map { |e| e._name }.sort)
178
+ end
179
+
180
+ def rpc_list_choice_files_stored(session, data)
181
+ file = get_file(data)
182
+ fields = {}
183
+ in_file { |f| fields[f] = file.data_get(f) }
184
+ fields._tags = fields._tags.join(', ')
185
+ empty_fields(0) +
186
+ reply(:update, fields)
187
+ end
188
+
189
+ def empty_fields(lvl)
190
+ rep = %w(name url_file url_page description tags)
191
+ if lvl > 0
192
+ rep.push :files_stored
193
+ end
194
+ if lvl > 1
195
+ rep.push :dirs_type
196
+ end
197
+ if lvl > 2
198
+ rep.push :dirs_os
199
+ end
200
+ reply(:empty, rep)
201
+ end
202
+
203
+ def get_file(data)
204
+ unless data._dirs_type.length > 0 && data._dirs_os.length > 0 &&
205
+ data._files_stored.length > 0
206
+ return nil
207
+ end
208
+ dir = FMDirs.search_by_path(data._dirs_type.first, data._dirs_os.first)
209
+ FMEntries.search_by_name(data._files_stored.first).find { |e|
210
+ e._directory == dir
211
+ }
212
+ end
213
+
214
+ def in_file
215
+ %w(name url_file url_page description tags).each { |f|
216
+ yield f
217
+ }
218
+ end
219
+ end
@@ -0,0 +1,39 @@
1
+ class AdminFunction < View
2
+ def layout
3
+ @order = 700
4
+ @update = true
5
+ set_data_class(:ConfigBases)
6
+
7
+ gui_vbox do
8
+ gui_hboxg :nogroup do
9
+ gui_vboxg :nogroup do
10
+ show_field :functions, :flexheight => 1
11
+ end
12
+ gui_vbox :nogroup do
13
+ show_field :welcome_text, :width => 400, :flexheight => 1
14
+ end
15
+ end
16
+ show_button :save
17
+ end
18
+ end
19
+
20
+ def rpc_update(session)
21
+ reply(:empty_nonlists) +
22
+ update_form_data(ConfigBases.singleton)
23
+ end
24
+
25
+ def rpc_button_save(session, data)
26
+ ConfigBase.store(data.to_sym)
27
+ dputs(3) { "Configuration is now #{ConfigBase.get_functions.inspect}" }
28
+
29
+ rpc_update(session)
30
+ end
31
+
32
+ def list_usage
33
+ index = 0
34
+ @@usages.collect { |c|
35
+ index += 1
36
+ [index, c.to_sym]
37
+ }
38
+ end
39
+ end
@@ -0,0 +1,49 @@
1
+ # Permits a reboot of both the Gestion and the Dreamplug itself
2
+
3
+ class AdminPower < View
4
+ def layout
5
+ @order = 400
6
+
7
+ gui_vbox do
8
+ gui_vbox do
9
+ show_button :reboot_gestion
10
+ end
11
+ gui_vbox do
12
+ show_button :reboot_dreamplug
13
+ end
14
+ gui_vbox do
15
+ show_button :update_files
16
+ end
17
+ gui_window :reload do
18
+ show_html :txt
19
+ show_button :OK
20
+ end
21
+ end
22
+ end
23
+
24
+ def rpc_button(session, name, data)
25
+ msg = ''
26
+ case name
27
+ when /reboot_gestion/ then
28
+ Thread.new {
29
+ Platform.restart('gestion')
30
+ }
31
+ msg = '<h1>Recharger le navigateur avec ctrl+r ou F5</h1>'
32
+ when /reboot_dreamplug/ then
33
+ Thread.new {
34
+ System.run_bool "#{GESTION_DIR}/Binaries/reboot"
35
+ }
36
+ msg = '<h1>Recharger le navigateur avec ctrl+r ou F5</h1><br>' +
37
+ '<h2>Attention: il faudra attendre au moins 2 minutes!</h2>'
38
+ when /update_files/ then
39
+ Thread.new {
40
+ System.run_bool('nohup /home/ftp/Files/update_files')
41
+ }
42
+ msg = '<h1>Les fichiers vont être mises à jour - patience</h1>'
43
+ when /OK/ then
44
+ return reply(:window_hide)
45
+ end
46
+ reply(:window_show, :reload) +
47
+ reply(:update, :txt => msg)
48
+ end
49
+ end
@@ -0,0 +1,37 @@
1
+ class AdminPrinter < View
2
+ def layout
3
+ @order = 550
4
+ @cups_dir = '/etc/cups'
5
+ @visible = false
6
+
7
+ gui_hbox do
8
+ gui_vbox do
9
+ show_list :printers, :single, :flexheight => 1
10
+ show_button :delete, :add
11
+ end
12
+ gui_vbox do
13
+ show_str :cups_name
14
+ show_str :device
15
+ show_str :driver
16
+ show_button :save
17
+ end
18
+ end
19
+ end
20
+
21
+ def get_printers
22
+ printers = "#{cups_dir}/printers.conf"
23
+ return [] unless File.exists? printers
24
+ config = IO.read(printers).split(/^<\/Printer>/)
25
+ config.collect{|c|
26
+ cl = c.split("\n")
27
+ name = cl.select{|l| l =~ /^<Printer/}.match(/^<Printer (.*)>/)[0]
28
+ device = cl.select{|l| l =~ /^DeviceURI/}.match(/^DeviceURI (.*)>/)[0]
29
+ driver = cl.select{|l| l =~ /^DeviceURI/}.match(/^DeviceURI (.*)>/)[0]
30
+ }
31
+ end
32
+
33
+ def rpc_show(session)
34
+ reply(:empty_all) +
35
+ reply(:update, :printers => get_printers )
36
+ end
37
+ end
@@ -0,0 +1,252 @@
1
+ class AdminServer < View
2
+ def layout
3
+ @functions_need = [:course_client]
4
+ @order = 300
5
+
6
+ gui_vbox do
7
+ show_button :import_ctypes
8
+ show_button :import_courses
9
+
10
+ gui_window :win_import do
11
+ show_html :status
12
+ show_list :import_list
13
+ show_button :download, :close
14
+ end
15
+ end
16
+ end
17
+
18
+ def check_availability(t)
19
+ if ConfigBase.server_url.to_s.length == 0
20
+ [false, 'No server defined, aborting']
21
+ else
22
+ if Persons.center
23
+ [true, "Fetching #{t} from server"]
24
+ else
25
+ [false, 'There is no center defined, aborting']
26
+ end
27
+ end
28
+ end
29
+
30
+ def status_list(show_status, status: '', list: [])
31
+ reply_one_two(show_status, :close, :download) +
32
+ reply_one_two(show_status, :status, :import_list) +
33
+ if show_status
34
+ reply(:update, status: status)
35
+ else
36
+ reply(:empty, :import_list) + reply(:update, import_list: list)
37
+ end
38
+ end
39
+
40
+ def rpc_button_import_ctypes(session, data)
41
+ ms = MakeSteps.new(session, -1) { |session, data, step|
42
+ case step
43
+ when 0
44
+ ms.auto_update = -1
45
+ downloading, status = check_availability(:CourseTypes)
46
+ reply(:window_show, :win_import) +
47
+ if downloading
48
+ status_list(true, status: status)
49
+ else
50
+ ms.step = 3
51
+ status_list(true, status: "Error: #{status}")
52
+ end
53
+ when 1
54
+ res = ICC.get(:CourseTypes, :list)
55
+ if res._code == 'Error'
56
+ ms.step = 3
57
+ status_list(true, status: "Error: #{res._msg}")
58
+ else
59
+ ms.auto_update = 0
60
+ status_list(false, list: res._msg)
61
+ end
62
+ when 2
63
+ ms.auto_update = -1
64
+ if (cts_names = data._import_list).length == 0
65
+ log_msg :CourseType, 'Nothing to download'
66
+ status_list(true, status: 'Nothing to download')
67
+ else
68
+ ms.status = status_list(true, status: "Downloading #{cts_names.length} CourseTypes")
69
+ data._import_list.each { |ct|
70
+ get_ctype(ct, ms)
71
+ }
72
+ ms.auto_update = 0
73
+ status_list(true, status: "Downloaded #{cts_names.length} CourseTypes")
74
+ end
75
+ when 3
76
+ ms.auto_update = 0
77
+ reply(:window_hide)
78
+ end
79
+ }
80
+
81
+ ms.make_step(session, data)
82
+ end
83
+
84
+ def get_ctype(name, ms)
85
+ ms.status = status_list(true, status: "Downloading CourseType #{name}")
86
+ cts = ICC.get(:CourseTypes, :fetch,
87
+ args: {course_type_names: name.to_a})
88
+ if cts._code == 'Error'
89
+ raise StandardError(cts._msg)
90
+ end
91
+
92
+ log_msg :CourseType, "Downloaded #{name}"
93
+ ct = cts._msg.first
94
+ ct = if ct_exist = CourseTypes.match_by_name(ct._name)
95
+ log_msg :CourseType, "Updating CourseType #{ct._name}"
96
+ ct_exist.data_set_hash(ct)
97
+ else
98
+ log_msg :CourseType, "Creating CourseType #{ct._name}"
99
+ CourseTypes.create(ct)
100
+ end
101
+ [ct._file_diploma, ct._file_exam].compact.each { |f|
102
+ file = f.first
103
+ if file.length > 0
104
+ ms.status = status_list(true, status: "Downloading file #{file}")
105
+ rep = ICC.get(:CourseTypes, :_file, args: {name: [file]})
106
+ if rep._code == 'OK'
107
+ data = rep._msg
108
+ log_msg :CourseType, "Got file #{file} with length #{data.length}"
109
+ IO.write("#{ConfigBase.template_dir}/#{file}", data)
110
+ else
111
+ log_msg :CourseType, "Got error #{rep._msg}"
112
+ end
113
+ end
114
+ }
115
+ ct
116
+ end
117
+
118
+ def rpc_update_with_values(session, data)
119
+ MakeSteps.make_step(session, data)
120
+ end
121
+
122
+ def rpc_button_download(session, data)
123
+ MakeSteps.make_step(session, data)
124
+ end
125
+
126
+ def get_person(name, ms)
127
+ if p = Persons.match_by_login_name(name)
128
+ return p
129
+ end
130
+ ms.status = status_list(true, status: "Fetching person #{name}")
131
+ person = ICC.get(:Persons, :get, args: {center: Persons.center, name: [name]})
132
+ if person._code == 'Error'
133
+ raise StandardError(person._msg)
134
+ end
135
+ Persons.create(person._msg.to_sym)
136
+ end
137
+
138
+ def rpc_button_import_courses(session, data)
139
+ ms = MakeSteps.new(session, -1) { |session, data, step|
140
+ # dputs_func
141
+ case step
142
+ when 0
143
+ ms.auto_update = -1
144
+ downloading, status = check_availability(:Courses)
145
+ ms.step = (downloading ? 1 : 10)
146
+ reply(:window_show, :win_import) +
147
+ status_list(true, status: status)
148
+ when 1
149
+ ms.auto_update = 0
150
+ ms.data = ICC.get(:Courses, :courses, args: {center: Persons.center})
151
+ if ms.data._code == 'Error'
152
+ ms.step = 10
153
+ status_list(true, status: "Error: #{ms.data._msg}")
154
+ elsif ms.data._msg
155
+ status_list(false, list: ms.data._msg.collect { |c| [c._course_id, c._name] })
156
+ else
157
+ ms.step = 10
158
+ ms.auto_update = 0
159
+ ms.status = status_list(true, status: 'Nothing received')
160
+ end
161
+ when 2
162
+ ms.auto_update = -1
163
+ data._import_list.each { |id|
164
+ course = ms.data._msg.find { |d| d._course_id == id }
165
+ ms.status = status_list(true, status: "Checking CourseType for #{course._name}")
166
+ sleep 2
167
+ if !ctype = CourseTypes.find_by_name(course._ctype)
168
+ ms.status = status_list(true, status: "Fetching CourseType #{course._ctype}")
169
+ sleep 2
170
+ begin
171
+ ctype = get_ctype(course._ctype, ms)
172
+ rescue StandardError => e
173
+ ms.step = 10
174
+ ms.auto_update = 0
175
+ ms.status = status_list(true, status: "Error: #{e.inspect}")
176
+ return
177
+ end
178
+ end
179
+ course._ctype = ctype
180
+ sleep 2
181
+ begin
182
+ %w(teacher responsible assistant).each { |p|
183
+ person = course[p]
184
+ if person.to_s.length == 0 || person.first == 0
185
+ course[p] = 0
186
+ next
187
+ end
188
+ dputs(3) { "Fetching person #{person} for #{p}" }
189
+ course[p] = Persons.match_by_login_name(person) || get_person(person, ms)
190
+ }
191
+ course._students.each { |p|
192
+ next if p.to_s.length == 0
193
+ next if p.first == 0
194
+ next if Persons.match_by_login_name(p)
195
+ dputs(3) { "Fetching student #{p}" }
196
+ get_person(p, ms)
197
+ }
198
+ course = Courses.create(course)
199
+
200
+ # Fetch grades
201
+ m = ICC.get(:Courses, :grades_get, args: {course: course._name,
202
+ center: Persons.center._login_name})
203
+ if m._code == 'OK'
204
+ m._msg.each { |g|
205
+ student = Persons.find_by_login_name(g._student)
206
+ if !student
207
+ dputs(0) { "Got grade #{g} with unexisting student" }
208
+ else
209
+ grade = Grades.match_by_course_person(course, student)
210
+ if grade
211
+ dputs(3) { "Updating for #{g}" }
212
+ grade.means = g._means
213
+ grade.remark = g._remark
214
+ grade.random = g._random
215
+ else
216
+ dputs(3) { "Making new grade with #{g}" }
217
+ g.delete('grade_id')
218
+ g._course = course
219
+ g._student = student
220
+ g._center = nil
221
+ grade = Grades.create(g)
222
+ end
223
+ dputs(3) { "Grade is now #{grade}" }
224
+ end
225
+ }
226
+ else
227
+ ms.step = 10
228
+ ms.status = status_list(true, status: "Error while fetching grades #{m._msg}")
229
+ return
230
+ end
231
+ rescue StandardError => e
232
+ ms.step = 10
233
+ ms.auto_update = 0
234
+ ms.status = status_list(true, status: "Couldn't fetch person - #{e}")
235
+ return
236
+ end
237
+
238
+ log_msg :AdminServer, "Created course #{course}"
239
+ }
240
+ ms.auto_update = 0
241
+ ms.step = 10
242
+ status_list(true, status: 'Everything downloaded')
243
+ when 10
244
+ ms.step = -1
245
+ reply(:window_hide)
246
+ end
247
+ }
248
+
249
+ ms.make_step(session, data)
250
+ end
251
+
252
+ end
@@ -0,0 +1,5 @@
1
+ class AdminTabs < View
2
+ def layout
3
+ @order = 40
4
+ end
5
+ end
@@ -0,0 +1,73 @@
1
+ class AdminUpdate < View
2
+ def layout
3
+ @order = 550
4
+ @update = true
5
+
6
+ gui_hbox do
7
+ gui_vbox :nogroup do
8
+ show_list_single :update_files, width: 300
9
+ show_upload :upload_update, callback: true
10
+ show_button :update, :delete
11
+ end
12
+
13
+ gui_window :confirm_win do
14
+ show_html :confirm_html
15
+ show_button :confirm_ok, :close
16
+ end
17
+ end
18
+ end
19
+
20
+ def list_http
21
+ []
22
+ end
23
+
24
+ def list_usb
25
+ []
26
+ end
27
+
28
+ def list_tmp
29
+ Dir.glob('/tmp/*.pkg.tar.*z').collect { |f| "file://#{f}" }
30
+ end
31
+
32
+ def list_files
33
+ list_http + list_usb + list_tmp
34
+ end
35
+
36
+ def rpc_update(_session, select = [])
37
+ reply(:empty_update, update_files: (list_files + select)) +
38
+ reply(:update, upload_update: 'Upload')
39
+ end
40
+
41
+ def rpc_button_update(session, data)
42
+ reply(:window_show, :confirm_win) +
43
+ reply(:update, confirm_html: '<h1>Updating - Danger!</h1>' +
44
+ 'Are you sure you want to update with<br>' +
45
+ "<strong>#{data._update_files.first}</strong>?") +
46
+ reply(:select, update_files: [data._update_files.first])
47
+ end
48
+
49
+ def rpc_button_confirm_ok(session, data)
50
+ file = data._update_files.first
51
+ log_msg :AdminUpdate, "Preparing update with #{file}"
52
+ Entities.save_all
53
+ log_msg :backup, 'Creating new backup'
54
+ System.run_bool "#{GESTION_DIR}/Binaries/backup"
55
+ System.run_bool "#{GESTION_DIR}/Binaries/gestion_update.rb #{file}"
56
+ Platform.start 'gestion_update'
57
+ reply(:eval, "document.location.href='http://local.profeda.org/update_progress.html'")
58
+ end
59
+
60
+ def rpc_button_delete(session, data)
61
+ return unless session.owner.permissions.index :admin
62
+ case data._update_files
63
+ when /^file:\/\/(.*)/
64
+ File.exists? $1 and FileUtils.rm $1
65
+ end
66
+ end
67
+
68
+ def rpc_button_upload_update(session, data)
69
+ file = ["file:///tmp/#{data._filename}"]
70
+ rpc_update(session, file) +
71
+ rpc_button_update(session, update_files: file)
72
+ end
73
+ end
@@ -0,0 +1,26 @@
1
+ class AdminUpdateSystem < View
2
+ def layout
3
+ @order = 60
4
+ @functions_need = [:files_manage]
5
+ @visible = false
6
+
7
+ gui_vbox do
8
+ show_upload :update, :callback => true
9
+ end
10
+ end
11
+
12
+ def rpc_button_update(session, data)
13
+ file = UploadFiles.escape_chars(data._filename)
14
+ return unless File.exists?("/tmp/#{file}")
15
+ dir = /^[^-]*-(.*)-files.*/.match(file)[1].gsub(/_/, '/')
16
+ if dir =~ /\./
17
+ dputs(0){"Error: tried to upload file to #{dir}"}
18
+ return reply(:window_hide)
19
+ end
20
+ files_dir = View.AdminFilesSave.files_dir
21
+ FileUtils.rm_rf("#{files_dir}/#{dir}")
22
+ System.run_str("tar xf /tmp/#{file} -C #{files_dir}")
23
+ log_msg :Files, "Installed #{file}"
24
+ reply(:window_hide)
25
+ end
26
+ end