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
data/Paths/Info.rb
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Used for returning some information about the internal state
|
|
2
|
+
# SHOULD NOT CHANGE ANYTHING IN HERE, JUST READING, INFORMATION!
|
|
3
|
+
|
|
4
|
+
class Info < RPCQooxdooPath
|
|
5
|
+
def self.parse_req( req )
|
|
6
|
+
dputs( 4 ){ "in QVInfo: #{req.inspect}" }
|
|
7
|
+
self.parse( req.request_method, req.path, req.query, RPCQooxdooHandler.get_ip( req ) )
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.parse( m, p, q, ip )
|
|
11
|
+
dputs( 2 ){ "in QVInfo: #{m.inspect} - #{p} - #{q.inspect} - #{ip}" }
|
|
12
|
+
method = p.gsub( /^.info./, '' )
|
|
13
|
+
dputs( 3 ){ "Calling method #{method}" }
|
|
14
|
+
if self.respond_to? method.to_sym
|
|
15
|
+
self.send( method, q.to_sym, ip )
|
|
16
|
+
else
|
|
17
|
+
dputs(0){ "Error: method #{method} not in Info" }
|
|
18
|
+
''
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.date(args)
|
|
23
|
+
dputs( 3 ){ "Arguments are: #{args.inspect}" }
|
|
24
|
+
return Time.new.to_s
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# We allow login for everybody. Things to do:
|
|
28
|
+
# Check on room (info1, info2, others), course and time
|
|
29
|
+
def self.allowed_login(args)
|
|
30
|
+
username = args[:user]
|
|
31
|
+
return 'yes'
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Who is allowed to use internet for free?
|
|
35
|
+
# For the moment everybody in a course that didn't end yet
|
|
36
|
+
def self.internet_free(args)
|
|
37
|
+
dputs( 3 ){ "Can #{args} do it?" }
|
|
38
|
+
username = args[:user]
|
|
39
|
+
user = Entities.Persons.match_by_login_name( username )
|
|
40
|
+
Internet.free( user ) ? 'yes' : 'no'
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def self.isAllowed( args, ip )
|
|
44
|
+
dputs(3){"isAllowed for #{args.inspect} in #{ip}"}
|
|
45
|
+
return "yes"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def self.login( args, ip )
|
|
49
|
+
dputs(3){"Logging in with #{args.inspect}"}
|
|
50
|
+
user = Persons.match_by_login_name( args[:user] )
|
|
51
|
+
if self.autoConnect( args, ip ) == 'yes'
|
|
52
|
+
dputs(2){"Auto-connecting user #{user.login_name} with ip #{ip}"}
|
|
53
|
+
Internet.user_connect( user.login_name, ip )
|
|
54
|
+
return 'connected'
|
|
55
|
+
end
|
|
56
|
+
return 'nothing'
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def self.clientUse( args, ip )
|
|
60
|
+
#return "nopay"
|
|
61
|
+
dputs(3){"Client use with #{args.inspect}"}
|
|
62
|
+
user = Persons.match_by_login_name( args[:user] )
|
|
63
|
+
if user
|
|
64
|
+
dputs(3){"Found user with groups #{user.groups.inspect} and internet_credit #{user.internet_credit.inspect}"}
|
|
65
|
+
if Internet.free( user )
|
|
66
|
+
dputs(3){ 'Found free' }
|
|
67
|
+
return 'nopay'
|
|
68
|
+
elsif user.groups and user.groups.index('localonly')
|
|
69
|
+
dputs(3){ 'Found localonly' }
|
|
70
|
+
return 'local'
|
|
71
|
+
elsif user.internet_credit
|
|
72
|
+
dputs(3){"Credit is #{user.internet_credit.inspect}"}
|
|
73
|
+
return user.internet_credit
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
return 0
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def self.autoConnect( args, ip )
|
|
80
|
+
#return "yes"
|
|
81
|
+
dputs(3){"AutoConnecting for #{args.inspect}"}
|
|
82
|
+
user = Persons.match_by_login_name( args[:user] )
|
|
83
|
+
if user
|
|
84
|
+
cu = self.clientUse( args, ip )
|
|
85
|
+
cost_max = Operator.user_cost_max
|
|
86
|
+
dputs(4){ "clientUse is #{cu.inspect} - cost_max is #{cost_max.inspect}" }
|
|
87
|
+
case cu
|
|
88
|
+
when /nopay/
|
|
89
|
+
return 'yes'
|
|
90
|
+
when /local/
|
|
91
|
+
return 'no'
|
|
92
|
+
when -100...cost_max
|
|
93
|
+
return 'no'
|
|
94
|
+
else
|
|
95
|
+
return 'yes'
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
return 'no'
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def self.query( args, ip )
|
|
102
|
+
dputs(3){"Querying with #{args.inspect}"}
|
|
103
|
+
case args[:action]
|
|
104
|
+
when /isAllowed/
|
|
105
|
+
return self.isAllowed( args, ip )
|
|
106
|
+
when /login/
|
|
107
|
+
return self.login( args, ip )
|
|
108
|
+
when /clientUse/
|
|
109
|
+
return self.clientUse( args, ip )
|
|
110
|
+
when /autoConnect/
|
|
111
|
+
return self.autoConnect( args, ip )
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
data/Paths/Label.rb
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# This works togehter with UploadMgr to retrieve files.
|
|
2
|
+
require 'erb'
|
|
3
|
+
|
|
4
|
+
class Label < RPCQooxdooPath
|
|
5
|
+
@@transfers = {}
|
|
6
|
+
|
|
7
|
+
def self.parse_req(req)
|
|
8
|
+
dputs(4) { "Label: #{req.inspect}" }
|
|
9
|
+
if req.request_method == 'POST'
|
|
10
|
+
dputs(0){ 'Deprecated' }
|
|
11
|
+
exit
|
|
12
|
+
path, query, addr = req.path, req.query.to_sym, RPCQooxdooHandler.get_ip(req)
|
|
13
|
+
dputs(4) { "Got query: #{path} - #{query.inspect} - #{addr}" }
|
|
14
|
+
|
|
15
|
+
if query._field == 'start'
|
|
16
|
+
log_msg :label, "Got start-query: #{path} - #{query.inspect} - #{addr}"
|
|
17
|
+
d = JSON.parse(query._data).to_sym
|
|
18
|
+
dputs(3) { "d is #{d.inspect}" }
|
|
19
|
+
if (user = Persons.match_by_login_name(d._user)) and
|
|
20
|
+
(user.check_pass(d._pass))
|
|
21
|
+
@@transfers[d._tid] = d.merge(:data => '')
|
|
22
|
+
return 'OK: send field'
|
|
23
|
+
else
|
|
24
|
+
dputs(3) { "User #{d._user.inspect} with pass #{d._pass.inspect} unknown" }
|
|
25
|
+
return 'Error: authentification'
|
|
26
|
+
end
|
|
27
|
+
elsif @@transfers.has_key? query._field
|
|
28
|
+
tr = @@transfers[query._field]
|
|
29
|
+
dputs(3) { "Found transfer-id #{query._field}, #{tr._chunks} left" }
|
|
30
|
+
tr._data += query._data
|
|
31
|
+
if (tr._chunks -= 1) == 0
|
|
32
|
+
if Digest::MD5.hexdigest(tr._data) == tr._md5
|
|
33
|
+
dputs(2) { "Successfully received field #{tr._field}" }
|
|
34
|
+
ret = self.field_save(tr)
|
|
35
|
+
else
|
|
36
|
+
dputs(2) { "Field #{tr._field} transmitted with errors" }
|
|
37
|
+
ret = 'Error: wrong MD5'
|
|
38
|
+
end
|
|
39
|
+
@@transfers.delete query._field
|
|
40
|
+
return ret
|
|
41
|
+
else
|
|
42
|
+
return "OK: send #{tr._chunks} more chunks"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
return 'Error: must start or use existing field'
|
|
46
|
+
else
|
|
47
|
+
path = /.*\/([^\/]*)\/([^\/]*)$/.match(req.path)
|
|
48
|
+
dputs(3) { "Path is #{path.inspect}" }
|
|
49
|
+
log_msg :label, "Got label-query: #{path.inspect}"
|
|
50
|
+
self.get_student(path[1], path[2])
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def self.get_student(center, grade_id)
|
|
55
|
+
dputs(3) { "Printing student #{grade_id} of #{center}" }
|
|
56
|
+
if grade = Grades.match_by_random(grade_id)
|
|
57
|
+
dputs(3) { "Grade is #{grade.inspect}" }
|
|
58
|
+
center_short = grade.course.name.sub(/_.*/, '')
|
|
59
|
+
dputs(3) { "Center_short is #{center_short}" }
|
|
60
|
+
center = center_short
|
|
61
|
+
if center_person = Persons.match_by_login_name(center_short)
|
|
62
|
+
center = center_person.full_name
|
|
63
|
+
end
|
|
64
|
+
remark = if grade.remark
|
|
65
|
+
if grade.remark =~ /^http:\/\//
|
|
66
|
+
"Site web: <a href='#{grade.remark}'>#{grade.remark}</a>"
|
|
67
|
+
else
|
|
68
|
+
"Remarques: #{grade.remark}"
|
|
69
|
+
end
|
|
70
|
+
else
|
|
71
|
+
''
|
|
72
|
+
end
|
|
73
|
+
log_msg :show_grade, "Student #{grade.student.full_name} from #{center} in course #{grade.course.name} " +
|
|
74
|
+
"has grade #{grade.mean}"
|
|
75
|
+
if grade.mean >= 10
|
|
76
|
+
ERB.new(File.open('Files/label.erb') { |f| f.read }).result(binding)
|
|
77
|
+
else
|
|
78
|
+
ERB.new(File.open('Files/label_notpassed.erb') { |f| f.read }).result(binding)
|
|
79
|
+
end
|
|
80
|
+
else
|
|
81
|
+
log_msg :show_grade, "Unknown grade-id #{grade_id}"
|
|
82
|
+
ERB.new(File.open('Files/label_notfound.erb') { |f| f.read }).result(binding)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def self.field_save(tr)
|
|
87
|
+
dputs(0){ 'Deprecated'}
|
|
88
|
+
exit
|
|
89
|
+
|
|
90
|
+
if not (course_name = tr._course) =~ /^#{tr._user}_/
|
|
91
|
+
course_name = "#{tr._user}_#{tr._course}"
|
|
92
|
+
end
|
|
93
|
+
dputs(3) { "Course-name is #{course_name} and field is #{tr._field}" }
|
|
94
|
+
case tr._field
|
|
95
|
+
when 'users'
|
|
96
|
+
users = JSON.parse(tr._data)
|
|
97
|
+
dputs(3) { "users are #{users.inspect}" }
|
|
98
|
+
users.each { |s|
|
|
99
|
+
s.to_sym!
|
|
100
|
+
if s._login_name != tr._user
|
|
101
|
+
s._login_name = "#{tr._user}_#{s._login_name}"
|
|
102
|
+
else
|
|
103
|
+
s.delete :password
|
|
104
|
+
end
|
|
105
|
+
%w( person_id groups ).each { |f|
|
|
106
|
+
s.delete f.to_sym
|
|
107
|
+
}
|
|
108
|
+
s._permissions = s._permissions & %w( teacher center )
|
|
109
|
+
dputs(3) { "Person is #{s.inspect}" }
|
|
110
|
+
dputs(4) { "Looking for #{s._login_name}" }
|
|
111
|
+
if stud = Persons.match_by_login_name(s._login_name)
|
|
112
|
+
dputs(3) { "Updating person #{stud.login_name} with #{s._login_name}" }
|
|
113
|
+
stud.data_set_hash(s)
|
|
114
|
+
else
|
|
115
|
+
dputs(3) { "Creating person #{s.inspect}" }
|
|
116
|
+
Persons.create(s)
|
|
117
|
+
end
|
|
118
|
+
}
|
|
119
|
+
"OK: Got users #{users.collect { |u| u._login_name }.join(':')}"
|
|
120
|
+
when 'course'
|
|
121
|
+
course = JSON.parse(tr._data).to_sym
|
|
122
|
+
dputs(3) { "Course is #{course.inspect}" }
|
|
123
|
+
course.delete :course_id
|
|
124
|
+
course._name = "#{course_name}"
|
|
125
|
+
course._responsible = Persons.match_by_login_name(
|
|
126
|
+
"#{tr._user}_#{course._responsible}")
|
|
127
|
+
course._teacher = Persons.match_by_login_name(
|
|
128
|
+
"#{tr._user}_#{course._teacher}")
|
|
129
|
+
course._assistant = Persons.match_by_login_name(
|
|
130
|
+
"#{tr._user}_#{course._assistant}")
|
|
131
|
+
course._students = course._students.collect { |s| "#{tr._user}_#{s}" }
|
|
132
|
+
course._ctype = CourseTypes.match_by_name(course._ctype)
|
|
133
|
+
return "Error: couldn't make course of type #{course.ctype}" unless course._ctype
|
|
134
|
+
course._center = Persons.match_by_login_name(tr._user)
|
|
135
|
+
course._room = Rooms.find_by_name("")
|
|
136
|
+
dputs(3) { "Course is now #{course.inspect}" }
|
|
137
|
+
if c = Courses.match_by_name(course._name)
|
|
138
|
+
dputs(3) { "Updating course #{course._name}" }
|
|
139
|
+
c.data_set_hash(course)
|
|
140
|
+
else
|
|
141
|
+
dputs(3) { "Creating course #{course._name}" }
|
|
142
|
+
Courses.create(course)
|
|
143
|
+
end
|
|
144
|
+
"OK: Updated course #{course._name}"
|
|
145
|
+
when 'grades'
|
|
146
|
+
'OK: ' + JSON.parse(tr._data).collect { |grade|
|
|
147
|
+
grade.to_sym!
|
|
148
|
+
ret = [grade._course, grade._student]
|
|
149
|
+
dputs(3) { "Grades is #{grade.inspect}" }
|
|
150
|
+
grade._course =
|
|
151
|
+
Courses.match_by_name("#{tr._user}_#{grade._course}")
|
|
152
|
+
grade._student =
|
|
153
|
+
Persons.match_by_login_name("#{tr._user}_#{grade._student}")
|
|
154
|
+
grade.delete :grade_id
|
|
155
|
+
grade.delete :random
|
|
156
|
+
if g = Grades.match_by_course_person(grade._course,
|
|
157
|
+
grade._student)
|
|
158
|
+
dputs(3) { "Updating grade #{g.inspect} with #{grade.inspect}" }
|
|
159
|
+
g.data_set_hash(grade)
|
|
160
|
+
else
|
|
161
|
+
g = Grades.create(grade)
|
|
162
|
+
dputs(3) { "Creating grade #{g.inspect} with #{grade.inspect}" }
|
|
163
|
+
end
|
|
164
|
+
dputs(3) { Grades.match_by_course_person(grade._course,
|
|
165
|
+
grade._student).inspect }
|
|
166
|
+
ret.push g.random
|
|
167
|
+
}.to_json
|
|
168
|
+
when 'exams'
|
|
169
|
+
tr._tid.gsub!(/[^a-zA-Z0-9_-]/, '')
|
|
170
|
+
file = "/tmp/#{tr._tid}.zip"
|
|
171
|
+
File.open(file, 'w') { |f| f.write tr._data }
|
|
172
|
+
if course = Courses.match_by_name(course_name)
|
|
173
|
+
dputs(3) { 'Updating exams' }
|
|
174
|
+
course.zip_read(file)
|
|
175
|
+
end
|
|
176
|
+
"OK: Read file #{file}"
|
|
177
|
+
when 'exams_here'
|
|
178
|
+
'OK: ' + if course = Courses.match_by_name(course_name)
|
|
179
|
+
dputs(3) { "Sending md5 of #{course_name}" }
|
|
180
|
+
course.md5_exams
|
|
181
|
+
else
|
|
182
|
+
dputs(3) { "Didn't find #{course_name}" }
|
|
183
|
+
{}
|
|
184
|
+
end.to_json
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
end
|
data/Paths/MobileInfo.rb
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require 'network'
|
|
2
|
+
require 'helper_classes'
|
|
3
|
+
require 'erb'
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class MobileInfo < RPCQooxdooPath
|
|
7
|
+
def self.parse(method, path, query)
|
|
8
|
+
dputs(3) { "Got #{method} - #{path} - #{query}" }
|
|
9
|
+
ERB.new(File.open('Files/mobileinfo.erb') { |f| f.read }).result(binding)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.send_email
|
|
13
|
+
File.open('/tmp/status.html', 'w') { |f|
|
|
14
|
+
f.write(ERB.new(File.open('Files/mobileinfo.erb') { |f| f.read }).result(binding))
|
|
15
|
+
}
|
|
16
|
+
System.run_bool('echo ".-=-." | mail -a /tmp/status.html -s "$( hostname ): Connected" root@localhost')
|
|
17
|
+
log_msg :MobileInfo, 'Sent e-mail'
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
class InternetCash < RPCQooxdooPath
|
|
4
|
+
def self.parse_req_res(req, res)
|
|
5
|
+
ip = RPCQooxdooHandler.get_ip( req )
|
|
6
|
+
query = req.query
|
|
7
|
+
dputs(4) { "InternetCash: #{req.inspect} - #{req.path} - #{ip}" }
|
|
8
|
+
if req.request_method == 'GET'
|
|
9
|
+
case req.path
|
|
10
|
+
when /fetch_users/
|
|
11
|
+
user_list = []
|
|
12
|
+
Persons.search_all.each { |p|
|
|
13
|
+
credit = 0
|
|
14
|
+
if p.internet_credit.to_i > 0
|
|
15
|
+
credit = p.internet_credit.to_i
|
|
16
|
+
p.internet_credit = 0
|
|
17
|
+
end
|
|
18
|
+
free = Permission.can_view(p.permissions, 'FlagInternetFree') or
|
|
19
|
+
Internet.active_course_for(p)
|
|
20
|
+
if free or credit > 0
|
|
21
|
+
dputs(3) { "Putting #{p.login_name} with credit #{credit} - #{free.inspect}" }
|
|
22
|
+
user_list.push [p.login_name, p.password, credit, free]
|
|
23
|
+
end
|
|
24
|
+
}
|
|
25
|
+
return user_list.to_json
|
|
26
|
+
when /update_connection/
|
|
27
|
+
return Internet.update_connection( ip, query._user )
|
|
28
|
+
else
|
|
29
|
+
dputs(0) { "Error: #{req.inspect} is not supported" }
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
class InternetWifi < RPCQooxdooPath
|
|
2
|
+
def self.parse_req_res(req, res)
|
|
3
|
+
ip = RPCQooxdooHandler.get_ip(req)
|
|
4
|
+
path, query = req.path, req.query
|
|
5
|
+
dputs(4) { "InternetWifi: #{req.inspect} - #{req.path} - #{ip}" }
|
|
6
|
+
if req.request_method == 'GET'
|
|
7
|
+
case path
|
|
8
|
+
when /users.cgi/
|
|
9
|
+
return 'mac'
|
|
10
|
+
when /connect.cgi/
|
|
11
|
+
login_name, password = query._user, query._pass
|
|
12
|
+
person = Persons.match_by_login_name(login_name)
|
|
13
|
+
person and dputs(3) { "Person is #{person.inspect} and #{person.password}" }
|
|
14
|
+
if person and person.check_pass(password) then
|
|
15
|
+
session = Sessions.create(person)
|
|
16
|
+
session.web_req = req
|
|
17
|
+
session.client_ip = RPCQooxdooHandler.get_ip(req)
|
|
18
|
+
dputs(3) { "Found login #{person.data_get(:person_id)} for #{login_name}" }
|
|
19
|
+
dputs(3) { "Session is #{session.inspect}" }
|
|
20
|
+
log_msg :InternetWifi, "Authenticated person #{person.login_name} from " +
|
|
21
|
+
"#{session.client_ip} and redirecting"
|
|
22
|
+
end
|
|
23
|
+
addr = 'admin.profeda.org'
|
|
24
|
+
#addr = 'localhost:3302'
|
|
25
|
+
return self.redirect(addr)
|
|
26
|
+
when /favicon.ico/
|
|
27
|
+
return ''
|
|
28
|
+
when /internetwifi/
|
|
29
|
+
return self.redirect('http://admin.profeda.org')
|
|
30
|
+
else
|
|
31
|
+
dputs(0) { "Error: #{path} in #{req.inspect} is not supported" }
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def self.redirect(address, timeout=0)
|
|
37
|
+
"
|
|
38
|
+
<!DOCTYPE HTML>
|
|
39
|
+
<html lang='fr-FR'>
|
|
40
|
+
<head>
|
|
41
|
+
<meta charset='UTF-8'>
|
|
42
|
+
<meta http-equiv='refresh' content='#{timeout};url=#{address}'>
|
|
43
|
+
<script type='text/javascript'>
|
|
44
|
+
window.location.href = '#{address}'
|
|
45
|
+
</script>
|
|
46
|
+
<title>Page Redirection</title>
|
|
47
|
+
</head>
|
|
48
|
+
<body>
|
|
49
|
+
If you are not redirected automatically, follow the <a href='#{address}'>link to example</a>
|
|
50
|
+
</body>
|
|
51
|
+
</html>"
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
data/README.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Gestion
|
|
2
|
+
|
|
3
|
+
Allows for handling of day-to-day tasks in a small school, think cultural center
|
|
4
|
+
that offers classes.
|
|
5
|
+
|
|
6
|
+
## Functions
|
|
7
|
+
|
|
8
|
+
For the cultural center-part, the following functions are implemented:
|
|
9
|
+
|
|
10
|
+
* Rights management (for students, secretary, director, admin, ...)
|
|
11
|
+
* Creation of courses (using templates for different courses)
|
|
12
|
+
* Sign up of students to courses
|
|
13
|
+
* Entering grades of students
|
|
14
|
+
* Creating diplomas
|
|
15
|
+
* Accounting
|
|
16
|
+
* Payments of students
|
|
17
|
+
* Internet-usage
|
|
18
|
+
* Other, simple 2-way accounting
|
|
19
|
+
|
|
20
|
+
There is also a network-part which has the following functions:
|
|
21
|
+
|
|
22
|
+
* Sharing with samba (public, read and read-write access)
|
|
23
|
+
* Internet-gateway using usb-modems or Ethernet-port
|
|
24
|
+
* Access-control of students when installed as captive gateway
|
|
25
|
+
* Controlling internet-credit, works for now only for Chad
|
|
26
|
+
|
|
27
|
+
## Hardware
|
|
28
|
+
|
|
29
|
+
It has been tested on ArchLinux running on different ARM-boxes (Dreamplug,
|
|
30
|
+
Smileplug and Cubox-i). Most of the parts also run on Ubuntu.
|
|
31
|
+
|
|
32
|
+
## Software
|
|
33
|
+
|
|
34
|
+
The user-interface is using http://QooxDoo.org with a ruby-back-end called
|
|
35
|
+
QooxView. Different libraries are used:
|
|
36
|
+
|
|
37
|
+
* AfriCompta - simple accounting program for QooxView
|
|
38
|
+
* HelperClasses - some modules to make life easier
|
|
39
|
+
* HilinkModem - interface for the infamous hilinkmodems which lack USSD-support!
|
|
40
|
+
* Network - captive interface and usb-modems definition
|
|
41
|
+
* QooxView - RPC backend for QooxDoo, also implementing a simple ActiveRecord
|
|
42
|
+
backend with CSV-files
|
|
43
|
+
* SerialModem - interface for simple ttyUSB-modems
|
|
44
|
+
|
|
45
|
+
## Installation
|
|
46
|
+
|
|
47
|
+
Unfortunately there is no gem-package available as yet. But a pacman-version exists
|
|
48
|
+
that you can download under http://github.com/ineiti/Gestion/releases/latest
|
|
49
|
+
|
|
50
|
+
If you're adventurous, you can try the following:
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
for s in AfriCompta Gestion HelperClasses HilinkModem Network QooxView SerialModem; do
|
|
54
|
+
git clone https://github.com/ineiti/$s
|
|
55
|
+
done
|
|
56
|
+
cd Gestion
|
|
57
|
+
./Gestion
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Which 'should work' (tm).
|