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.
- checksums.yaml +7 -0
- data/.gitignore +48 -0
- data/.project +14 -0
- data/Binaries/adduser_to_buzz +15 -0
- data/Binaries/backup +7 -0
- data/Binaries/check_gestion +8 -0
- data/Binaries/gestion.gnumail +22 -0
- data/Binaries/gestion.logrotate +34 -0
- data/Binaries/gestion.service +12 -0
- data/Binaries/gestion_update.rb +183 -0
- data/Binaries/gestion_update.service +10 -0
- data/Binaries/get_compta +11 -0
- data/Binaries/kill_gestion +16 -0
- data/Binaries/ldap/add_indexes +51 -0
- data/Binaries/ldap/backup +2 -0
- data/Binaries/ldap/install_ldap +92 -0
- data/Binaries/ldap/restore +7 -0
- data/Binaries/lib_backup +5 -0
- data/Binaries/log_scan_errors +8 -0
- data/Binaries/loop_gestion +64 -0
- data/Binaries/onetimers/sync_courses_from_compta.rb +74 -0
- data/Binaries/onetimers/transfer_cash_from_ldap_to_csv +26 -0
- data/Binaries/reboot +5 -0
- data/Binaries/restore +3 -0
- data/Binaries/restore_do +22 -0
- data/Binaries/sort_events +31 -0
- data/Binaries/start_gestion +18 -0
- data/Binaries/swipe_gestion +18 -0
- data/Binaries/update_africompta +21 -0
- data/Binaries/update_users +3 -0
- data/Diplomas.src/accredited.odg +0 -0
- data/Diplomas.src/diploma.odg +0 -0
- data/Diplomas.src/label.odg +0 -0
- data/Diplomas.src/presence_sheet.ods +0 -0
- data/Diplomas.src/presence_sheet_small.ods +0 -0
- data/Diplomas.src/student_card.odg +0 -0
- data/Doc/130514-it-ideas.odt +0 -0
- data/Doc/Compta-cash.mm +179 -0
- data/Doc/General.odt +0 -0
- data/Entities/AccessGroups.rb +117 -0
- data/Entities/Activity.rb +178 -0
- data/Entities/ChatMsg.rb +142 -0
- data/Entities/Classroom.rb +11 -0
- data/Entities/Client.rb +19 -0
- data/Entities/Computer.rb +21 -0
- data/Entities/ConfigBase.rb +280 -0
- data/Entities/Course.rb +1588 -0
- data/Entities/CourseType.rb +171 -0
- data/Entities/DFiles.rb +466 -0
- data/Entities/FilesManage.rb +226 -0
- data/Entities/Grade.rb +186 -0
- data/Entities/Internet.rb +300 -0
- data/Entities/Netdev.rb +10 -0
- data/Entities/Person.rb +1175 -0
- data/Entities/Plug.rb +98 -0
- data/Entities/Quiz.rb +33 -0
- data/Entities/Recharges.rb +37 -0
- data/Entities/Report.rb +136 -0
- data/Entities/Room.rb +12 -0
- data/Entities/SMS.rb +30 -0
- data/Entities/ScheduleType.rb +33 -0
- data/Entities/Share.rb +120 -0
- data/Entities/Task.rb +51 -0
- data/Entities/Ticket.rb +72 -0
- data/Entities/Usage.rb +143 -0
- data/Entities/Worker.rb +29 -0
- data/Files/apache-profeda.conf +36 -0
- data/Files/label.erb +121 -0
- data/Files/label_notfound.erb +64 -0
- data/Files/label_notpassed.erb +84 -0
- data/Files/mobileinfo.erb +115 -0
- data/Files/smb.conf +333 -0
- data/Files/timetable.html +36 -0
- data/Files/timetable.js +239 -0
- data/Gemfile +12 -0
- data/Gemfile.dev +12 -0
- data/Gemfile.dev.lock +127 -0
- data/Gemfile.lock +127 -0
- data/Gemfile.prod +8 -0
- data/Gestion +35 -0
- data/Gestion.rb +220 -0
- data/INSTALL +40 -0
- data/Images/connection.xcf +0 -0
- data/Images/connection_no.png +0 -0
- data/Images/connection_wait.png +0 -0
- data/Images/connection_yes.png +0 -0
- data/Paths/Exas.rb +13 -0
- data/Paths/Files.rb +19 -0
- data/Paths/GetDiplomas.rb +20 -0
- data/Paths/Info.rb +114 -0
- data/Paths/Label.rb +187 -0
- data/Paths/MobileInfo.rb +19 -0
- data/Paths/internetCash.rb +34 -0
- data/Paths/internetWifi.rb +54 -0
- data/README.md +60 -0
- data/Rakefile +13 -0
- data/TODO +1391 -0
- data/Test/.gitignore +3 -0
- data/Test/Diplomas/base_gestion.odt +0 -0
- data/Test/Diplomas/base_report.odt +0 -0
- data/Test/Diplomas/carte_etudiant.odg +0 -0
- data/Test/Diplomas/exam_language.odt +0 -0
- data/Test/Diplomas/label.odg +0 -0
- data/Test/Diplomas/presence_sheet.ods +0 -0
- data/Test/Diplomas/presence_sheet_small.ods +0 -0
- data/Test/Diplomas/student_card.odg +0 -0
- data/Test/Manual/testMerge +18 -0
- data/Test/config_test.yaml +26 -0
- data/Test/db.testGestion +0 -0
- data/Test/dfiles/descs/avg-rescue.desc +10 -0
- data/Test/dfiles/descs/avg.desc +8 -0
- data/Test/dfiles/descs/driver.desc +8 -0
- data/Test/dfiles/descs/linuxmint.desc +7 -0
- data/Test/dfiles/files/avg-160203.exe +1 -0
- data/Test/dfiles/files/avg.iso +1 -0
- data/Test/dfiles/files/driver.exe +1 -0
- data/Test/dfiles/index_post.html +3 -0
- data/Test/dfiles/index_pre.html +8 -0
- data/Test/dfiles/priorities +5 -0
- data/Test/ge_activity.rb +124 -0
- data/Test/ge_chat.rb +106 -0
- data/Test/ge_compta.rb +67 -0
- data/Test/ge_configbase.rb +54 -0
- data/Test/ge_course.rb +1114 -0
- data/Test/ge_dfiles.rb +121 -0
- data/Test/ge_filesmanage.rb +180 -0
- data/Test/ge_info.rb +27 -0
- data/Test/ge_internet.rb +246 -0
- data/Test/ge_login.rb +55 -0
- data/Test/ge_person.rb +373 -0
- data/Test/ge_qvinfo.rb +28 -0
- data/Test/ge_report.rb +97 -0
- data/Test/ge_share.rb +27 -0
- data/Test/ge_sms.rb +34 -0
- data/Test/ge_tasks.rb +19 -0
- data/Test/ge_usage.rb +168 -0
- data/Test/ge_view.rb +46 -0
- data/Test/multiconf-captive +29 -0
- data/Test/test.conf +7 -0
- data/Test/test.rb +49 -0
- data/Test/test_bytes.png +0 -0
- data/VERSION +140 -0
- data/Views/Admin/Backup.rb +91 -0
- data/Views/Admin/Configuration.rb +44 -0
- data/Views/Admin/Credit.rb +32 -0
- data/Views/Admin/FilesManage.rb +219 -0
- data/Views/Admin/Function.rb +39 -0
- data/Views/Admin/Power.rb +49 -0
- data/Views/Admin/Printer.rb +37 -0
- data/Views/Admin/Server.rb +252 -0
- data/Views/Admin/Tabs.rb +5 -0
- data/Views/Admin/Update.rb +73 -0
- data/Views/Admin/UpdateSystem.rb +26 -0
- data/Views/Cashbox/Activity.rb +191 -0
- data/Views/Cashbox/Course.rb +141 -0
- data/Views/Cashbox/Credit.rb +79 -0
- data/Views/Cashbox/Report.rb +115 -0
- data/Views/Cashbox/Service.rb +105 -0
- data/Views/Cashbox/Tabs.rb +10 -0
- data/Views/Compta/Accounts.rb +36 -0
- data/Views/Compta/Course.rb +96 -0
- data/Views/Compta/Show.rb +6 -0
- data/Views/Compta/Transfer.rb +66 -0
- data/Views/Course/Diploma.rb +203 -0
- data/Views/Course/Grade.rb +401 -0
- data/Views/Course/Modify.rb +447 -0
- data/Views/Course/Print.rb +94 -0
- data/Views/Course/Responsible.rb +44 -0
- data/Views/Course/Stats.rb +76 -0
- data/Views/Course/Students.rb +92 -0
- data/Views/Course/Tabs.rb +220 -0
- data/Views/Internet/Access.rb +134 -0
- data/Views/Internet/ClassEdit.rb +24 -0
- data/Views/Internet/ClassUsers.rb +81 -0
- data/Views/Internet/Config.rb +32 -0
- data/Views/Internet/Mobile.rb +213 -0
- data/Views/Internet/Recharges.rb +49 -0
- data/Views/Internet/Tabs.rb +6 -0
- data/Views/Inventory/Computer.rb +24 -0
- data/Views/Inventory/Room.rb +18 -0
- data/Views/Inventory/Tabs.rb +9 -0
- data/Views/Inventory/TicketClosed.rb +7 -0
- data/Views/Inventory/TicketOpen.rb +23 -0
- data/Views/Library/Person.rb +36 -0
- data/Views/Library/Tabs.rb +7 -0
- data/Views/Network/Block.rb +87 -0
- data/Views/Network/Netdevs.rb +21 -0
- data/Views/Network/Restriction.rb +37 -0
- data/Views/Network/Share.rb +167 -0
- data/Views/Network/Tables.rb +28 -0
- data/Views/Network/Tabs.rb +6 -0
- data/Views/Person/Admin.rb +99 -0
- data/Views/Person/Center.rb +48 -0
- data/Views/Person/Course.rb +72 -0
- data/Views/Person/Modify.rb +153 -0
- data/Views/Person/Tabs.rb +162 -0
- data/Views/Report/ComptaExecutive.rb +221 -0
- data/Views/Report/ComptaFlat.rb +79 -0
- data/Views/Report/ReportCourse.rb +47 -0
- data/Views/Report/Tabs.rb +8 -0
- data/Views/Report/Usage.rb +52 -0
- data/Views/Report/UsageCases.rb +59 -0
- data/Views/Self/Cash.rb +67 -0
- data/Views/Self/Chat.rb +55 -0
- data/Views/Self/Concours.rb +109 -0
- data/Views/Self/Email.rb +34 -0
- data/Views/Self/Internet.rb +255 -0
- data/Views/Self/Results.rb +17 -0
- data/Views/Self/Services.rb +85 -0
- data/Views/Self/Show.rb +47 -0
- data/Views/Self/Tabs.rb +5 -0
- data/Views/Special/DFileEdit.rb +13 -0
- data/Views/Special/PlugEdit.rb +56 -0
- data/Views/Special/Tabs.rb +6 -0
- data/Views/Special/Vnc.rb +39 -0
- data/Views/Task/Client.rb +21 -0
- data/Views/Task/Edit.rb +33 -0
- data/Views/Task/List.rb +55 -0
- data/Views/Task/Tabs.rb +9 -0
- data/Views/Task/Worker.rb +30 -0
- data/Views/Template/Activity.rb +33 -0
- data/Views/Template/CourseType.rb +63 -0
- data/Views/Template/ScheduleType.rb +29 -0
- data/Views/Template/Tabs.rb +5 -0
- data/Views/Welcome.rb +121 -0
- data/config.yaml.default +36 -0
- data/po/Gestion-ar.po +2356 -0
- data/po/Gestion-en.mo +0 -0
- data/po/Gestion-en.po +4363 -0
- data/po/Gestion-fr.mo +0 -0
- data/po/Gestion-fr.po +4345 -0
- data/po/traduction-ar.rtf +76 -0
- 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
|
data/Views/Admin/Tabs.rb
ADDED
|
@@ -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
|