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
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
@@ -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).
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ def gemf(ext = '')
2
+ puts `pwd`
3
+ puts `bundle config --local gemfile Gemfile#{ext}`
4
+ puts `bundle install`
5
+ end
6
+
7
+ task :default do
8
+ gemf
9
+ end
10
+
11
+ task :dev do
12
+ gemf( '.dev' )
13
+ end