gestion 1.9.12
Sign up to get free protection for your applications and to get access to all the features.
- 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,178 @@
|
|
1
|
+
class Activities < Entities
|
2
|
+
|
3
|
+
PAYMENTS = %w( daily weekly monthly yearly )
|
4
|
+
START = %w( payment period period_overlap )
|
5
|
+
|
6
|
+
def setup_data
|
7
|
+
value_str :name
|
8
|
+
|
9
|
+
value_block :show
|
10
|
+
value_str :description
|
11
|
+
value_int :cost
|
12
|
+
value_list_drop :payment_period, 'Activities::PAYMENTS'
|
13
|
+
value_list_drop :start_type, 'Activities::START'
|
14
|
+
value_int :overlap
|
15
|
+
|
16
|
+
value_block :hidden
|
17
|
+
value_str :card_filename
|
18
|
+
value_list :tags, '%w( library internet club )'
|
19
|
+
value_entity_internetClass_empty_all :internet_limit, :drop, :name
|
20
|
+
end
|
21
|
+
|
22
|
+
def files
|
23
|
+
ConfigBase.templates.collect { |f| f.cut(/^.*\//) }
|
24
|
+
end
|
25
|
+
|
26
|
+
def tagged(*tags)
|
27
|
+
tags.inspect
|
28
|
+
Activities.search_all_.select { |a|
|
29
|
+
(tags - a.tags).length == 0
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
def tagged_users(tags, date = Date.today)
|
34
|
+
#dputs_func
|
35
|
+
tagged(tags).collect { |a|
|
36
|
+
aps = ActivityPayments.search_by_activity(a)
|
37
|
+
dputs(3) { "Found #{aps.inspect} for tag #{a}" }
|
38
|
+
ActivityPayments.active_now(aps, date).collect { |ap|
|
39
|
+
dputs(3) { "Found #{ap.inspect} active for now" }
|
40
|
+
ap.person_paid
|
41
|
+
}
|
42
|
+
}.flatten.uniq
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
class Activity < Entity
|
48
|
+
attr_accessor :print_card
|
49
|
+
|
50
|
+
def setup_instance
|
51
|
+
if card_filename != nil
|
52
|
+
@print_card = OpenPrint.new("#{ConfigBase.template_dir}/#{card_filename.first}")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def start_end(s, d = Date.today)
|
57
|
+
ActivityPayments.search_by_person_paid(s).select { |ap|
|
58
|
+
ap.date_start <= d && d <= ap.date_end && ap.activity == self
|
59
|
+
}.collect { |ap| [ap.date_start, ap.date_end] }.pop || [nil, nil]
|
60
|
+
end
|
61
|
+
|
62
|
+
def cost_mov
|
63
|
+
self._cost.to_i / 1000.0
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
class ActivityPayments < Entities
|
68
|
+
def setup_data
|
69
|
+
value_entity_activity :activity
|
70
|
+
value_entity_person :person_paid
|
71
|
+
value_entity_person :person_cashed
|
72
|
+
value_entity_movement :movement
|
73
|
+
value_date :date_start
|
74
|
+
value_date :date_end
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.week_start(date)
|
78
|
+
date - date.cwday
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.get_one_period(date, period, ceil = false)
|
82
|
+
[date,
|
83
|
+
case period.to_s
|
84
|
+
when /daily/
|
85
|
+
date + 1
|
86
|
+
when /weekly/
|
87
|
+
(ceil ? week_start(date) + 7 : date) + 7
|
88
|
+
when /monthly/
|
89
|
+
(ceil ? Date.new(date.year, date.month + 1) : date).next_month
|
90
|
+
when /yearly/
|
91
|
+
(ceil ? Date.new(date.year + 1) : date).next_year
|
92
|
+
else
|
93
|
+
raise("Unknown period #{period[0].to_s}!")
|
94
|
+
fail
|
95
|
+
end - 1]
|
96
|
+
end
|
97
|
+
|
98
|
+
# Get start and end of a period respecting overlap lesser periods before
|
99
|
+
def self.get_period(date, period, overlap=0)
|
100
|
+
case period.to_s
|
101
|
+
when /daily/
|
102
|
+
return [date - overlap, date]
|
103
|
+
when /weekly/
|
104
|
+
ceil = (date + overlap >= week_start(date) + 7)
|
105
|
+
start = ceil ? date : week_start(date)
|
106
|
+
when /monthly/
|
107
|
+
ceil = (date + overlap * 7 >= Date.new(date.year, date.month + 1))
|
108
|
+
start = ceil ? date : Date.new(date.year, date.month)
|
109
|
+
when /yearly/
|
110
|
+
ceil = (date.next_month(overlap) >= Date.new(date.year + 1))
|
111
|
+
start = ceil ? date : Date.new(date.year)
|
112
|
+
end
|
113
|
+
get_one_period(start, period, ceil)
|
114
|
+
end
|
115
|
+
|
116
|
+
def self.pay(act, p_paid, p_cashed, d_today = Date.today)
|
117
|
+
if !p_cashed.account_due
|
118
|
+
dputs(0) { "Couldn't make #{p_cashed} pay, as he doesn't have an account_due" }
|
119
|
+
return
|
120
|
+
end
|
121
|
+
mov = Movements.create("#{p_paid.login_name} paid #{p_cashed.login_name} #{act.cost} "+
|
122
|
+
"for #{act.name}", Date.today, act.cost_mov,
|
123
|
+
p_cashed.account_due, ConfigBase.account_activities)
|
124
|
+
date_start, date_end =
|
125
|
+
case act.start_type.to_s
|
126
|
+
when /payment/
|
127
|
+
get_one_period(d_today, act.payment_period)
|
128
|
+
when /period/, /period_overlap/
|
129
|
+
get_period(d_today, act.payment_period, act.overlap.to_i)
|
130
|
+
end
|
131
|
+
|
132
|
+
log_msg :ActivityPayments, "#{date_start} - #{date_end}: #{mov.inspect}"
|
133
|
+
ActivityPayments.create(activity: act, person_paid: p_paid, person_cashed: p_cashed,
|
134
|
+
movement: mov, date_start: date_start, date_end: date_end)
|
135
|
+
end
|
136
|
+
|
137
|
+
def self.active_now(actp, d = Date.today)
|
138
|
+
return [] unless actp
|
139
|
+
actp.select { |ap|
|
140
|
+
ap.date_start <= d and d <= ap.date_end
|
141
|
+
}
|
142
|
+
end
|
143
|
+
|
144
|
+
def self.active_for(s, d = Date.today)
|
145
|
+
active_now(for_user(s), d)
|
146
|
+
end
|
147
|
+
|
148
|
+
def self.for_user(s)
|
149
|
+
s == nil and return []
|
150
|
+
ActivityPayments.matches_by_person_paid(s)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
class ActivityPayment < Entity
|
155
|
+
def date_start
|
156
|
+
Date.from_db(self._date_start)
|
157
|
+
end
|
158
|
+
|
159
|
+
def date_end
|
160
|
+
Date.from_db(self._date_end)
|
161
|
+
end
|
162
|
+
|
163
|
+
def print
|
164
|
+
st = person_paid
|
165
|
+
date = System.run_str('LC_ALL=fr_FR.UTF-8 date +"%d %B %Y"')
|
166
|
+
replace = {NAME1: st.first_name, NAME2: st.family_name,
|
167
|
+
BDAY: st.birthday, ADDRESS: st.address, TOWN: st.town,
|
168
|
+
TEL: st.phone, UNAME: st.login_name, PASS: st.password_plain,
|
169
|
+
EMAIL: st.email, PROFESSION: st.profession, STUDY_LEVEL: st.school_grade,
|
170
|
+
DATE: date, PRICE: activity.cost,
|
171
|
+
DATE_START: date_start, DATE_END: date_end, ID: activitypayment_id}
|
172
|
+
|
173
|
+
fname = "#{st.person_id.to_s.rjust(6, '0')}-#{st.full_name.gsub(/ /, '_')}"
|
174
|
+
dputs(3) { "Replace is #{replace.inspect} - fname is #{fname}" }
|
175
|
+
|
176
|
+
activity.print_card.print_hash(replace, nil, fname)
|
177
|
+
end
|
178
|
+
end
|
data/Entities/ChatMsg.rb
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
class ChatMsgs < Entities
|
2
|
+
def setup_data
|
3
|
+
value_time :time
|
4
|
+
value_str :msg
|
5
|
+
value_entity_person :center
|
6
|
+
value_str :login
|
7
|
+
|
8
|
+
@max_msgs ||= 200
|
9
|
+
@static._client_times ||= {}
|
10
|
+
@wait_counter = 0
|
11
|
+
@wait_max = 5
|
12
|
+
end
|
13
|
+
|
14
|
+
# Pushes a message to the server and returns eventual new messages
|
15
|
+
# tr holds the following keys:
|
16
|
+
# center: hash with {login, pass} keys
|
17
|
+
# person: login-name of person
|
18
|
+
# msg: the message written
|
19
|
+
#
|
20
|
+
# It returns the results from icc_msg_pull
|
21
|
+
def icc_msg_push(tr)
|
22
|
+
return 'Error: no course_server' unless ConfigBase.has_function?(:course_server)
|
23
|
+
return unless tr && tr._center
|
24
|
+
center = Persons.check_login(tr._center._login, tr._center._pass)
|
25
|
+
if center && center.has_permission?(:center)
|
26
|
+
new_msg(tr._person, tr._msg, center)
|
27
|
+
else
|
28
|
+
return "Error: center #{center.inspect} has wrong password or is not a center"
|
29
|
+
end
|
30
|
+
icc_msg_pull(tr)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Gets new messages since last call
|
34
|
+
# tr holds the following keys:
|
35
|
+
# center: hash with {login, pass} keys
|
36
|
+
def icc_msg_pull(tr)
|
37
|
+
return 'Error: not a server here' unless ConfigBase.has_function?(:course_server)
|
38
|
+
return unless tr && tr._center
|
39
|
+
center = Persons.check_login(tr._center._login, tr._center._pass)
|
40
|
+
if !center || !center.has_permission?(:center)
|
41
|
+
return "Error: center #{center.inspect} has wrong password or is not a center"
|
42
|
+
end
|
43
|
+
@static._client_times ||= {}
|
44
|
+
last_time = @static._client_times[center.login_name] || Time.new(2000, 1, 1)
|
45
|
+
@static._client_times[center.login_name] = Time.now
|
46
|
+
search_all_.
|
47
|
+
select { |msg| msg.time > last_time && msg.center != center }.
|
48
|
+
collect { |msg|
|
49
|
+
center = msg.center ? msg.center.login_name : Persons.master_center_login_name
|
50
|
+
msg.to_hash.merge(center: center)
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
def center_hash
|
55
|
+
return {} unless center = Persons.center
|
56
|
+
{center: {login: center.login_name, pass: center.password_plain}}
|
57
|
+
end
|
58
|
+
|
59
|
+
def add_remote_msg(ret)
|
60
|
+
dputs(3) { "Got reply #{ret.inspect}" }
|
61
|
+
if ret._code =~ /^error/i
|
62
|
+
dputs(0) { "Error #{ret._msg} while fetching chat-messages" }
|
63
|
+
else
|
64
|
+
ret._msg.each { |m|
|
65
|
+
dputs(2) { "Got message #{m.inspect}" }
|
66
|
+
new_msg("#{m._login}@#{m._center}", m._msg, nil, m._time)
|
67
|
+
}
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def is_remote?
|
72
|
+
ConfigBase.has_function?(:remote_chat) &&
|
73
|
+
ConfigBase.server_url.to_s.length > 0 &&
|
74
|
+
(!ConfigBase.has_function?(:course_server))
|
75
|
+
end
|
76
|
+
|
77
|
+
def new_msg(person, msg, center = nil, time = Time.now)
|
78
|
+
create(time: time, msg: msg, center: center,
|
79
|
+
login: person)
|
80
|
+
log_msg :ChatMsgs, "#{person} from #{center ? center.login_name : 'here'} " +
|
81
|
+
"says - #{msg}"
|
82
|
+
if @data.length > @max_msgs
|
83
|
+
get_data_instance(@data.keys.first).delete
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def new_msg_send(person, msg)
|
88
|
+
if is_remote?
|
89
|
+
log_msg :ChatMsgs, "Sending msg from #{person} to server"
|
90
|
+
arg = center_hash.merge(person: person, msg: msg)
|
91
|
+
# As we'll get the new messages, no need to fetch them again
|
92
|
+
wait_counter_reset
|
93
|
+
(!$MobileControl || $MobileControl.is_connected) and
|
94
|
+
add_remote_msg(ICC.get(:ChatMsgs, :msg_push, args: arg))
|
95
|
+
end
|
96
|
+
new_msg(person, msg)
|
97
|
+
end
|
98
|
+
|
99
|
+
def wait_max=(max)
|
100
|
+
@wait_max = max
|
101
|
+
end
|
102
|
+
|
103
|
+
# if @wait_counter is bigger or equal to @wait_counter, it checks for
|
104
|
+
# new messages.
|
105
|
+
# That way we save precious bandwith
|
106
|
+
def wait_counter_add
|
107
|
+
is_remote? or return
|
108
|
+
@wait_counter += 1
|
109
|
+
if @wait_counter >= @wait_max &&
|
110
|
+
(!$MobileControl || $MobileControl.is_connected)
|
111
|
+
add_remote_msg(ICC.get(:ChatMsgs, :msg_pull, args: center_hash))
|
112
|
+
wait_counter_reset
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def wait_counter_reset
|
117
|
+
@wait_counter = 0
|
118
|
+
end
|
119
|
+
|
120
|
+
def show_list(max = 100)
|
121
|
+
date = ''
|
122
|
+
search_all_.reverse[0...max].collect { |cm|
|
123
|
+
t = cm.time.class == Time ? cm.time : Time.parse(cm.time)
|
124
|
+
name = (ConfigBase.has_function?(:course_server) && cm.center) ?
|
125
|
+
"#{cm.login}@#{cm.center.login_name}" : "#{cm.login}"
|
126
|
+
d = "#{t.strftime('%Y-%m-%d')}\n"
|
127
|
+
if d != date
|
128
|
+
date = d
|
129
|
+
else
|
130
|
+
d = ''
|
131
|
+
end
|
132
|
+
"#{d}#{t.strftime('%H:%M')} - #{name}: #{cm.msg}"
|
133
|
+
}.join("\n")
|
134
|
+
end
|
135
|
+
|
136
|
+
def load
|
137
|
+
super
|
138
|
+
ChatMsgs.search_all_.each { |cm|
|
139
|
+
cm.time = Time.parse(cm.time)
|
140
|
+
}
|
141
|
+
end
|
142
|
+
end
|
data/Entities/Client.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
class Clients < Entities
|
2
|
+
def setup_data
|
3
|
+
value_block :name
|
4
|
+
value_str :name
|
5
|
+
|
6
|
+
value_block :address
|
7
|
+
value_str :addr1
|
8
|
+
value_str :addr2
|
9
|
+
value_str :country
|
10
|
+
|
11
|
+
value_block :prices
|
12
|
+
value_int :price_assistant
|
13
|
+
value_int :price_expert
|
14
|
+
|
15
|
+
value_block :contact
|
16
|
+
value_str :email
|
17
|
+
value_str :phone
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# A classroom has:
|
2
|
+
# - different courses
|
3
|
+
# - inventory (desks, blackboard, computers)
|
4
|
+
|
5
|
+
class Computers < Entities
|
6
|
+
def setup_data
|
7
|
+
value_block :identity
|
8
|
+
value_str :name_service
|
9
|
+
value_entity_room_all :room, :drop, :name
|
10
|
+
value_str :name_place
|
11
|
+
|
12
|
+
value_block :performance
|
13
|
+
value_str :brand
|
14
|
+
value_int :RAM_MB
|
15
|
+
value_int :HD_GB
|
16
|
+
value_int :CPU_GHz
|
17
|
+
|
18
|
+
value_block :ticket
|
19
|
+
value_text :comment
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,280 @@
|
|
1
|
+
class ConfigBases < Entities
|
2
|
+
self.needs %w(Accounts)
|
3
|
+
|
4
|
+
def add_config
|
5
|
+
@convert_values = true
|
6
|
+
|
7
|
+
value_block :vars_narrow
|
8
|
+
value_list_drop :show_passwords, '%w(always lesser students never)'
|
9
|
+
value_list_drop :autosave, '%w(true false)'
|
10
|
+
value_int :autosave_timer
|
11
|
+
value_list_drop :samba_simul, '%w(true false)'
|
12
|
+
value_str :samba_config
|
13
|
+
value_list_drop :persons_add_del_users, '%w(true false)'
|
14
|
+
value_str :persons_adduser_cmd
|
15
|
+
value_str :persons_addeduser_cmd
|
16
|
+
|
17
|
+
value_block :vars_wide
|
18
|
+
value_str :server_url
|
19
|
+
value_str :label_url
|
20
|
+
value_str :html_title
|
21
|
+
value_str :upload_files
|
22
|
+
value_str :connection_status_log
|
23
|
+
|
24
|
+
value_block :templates
|
25
|
+
value_str :template_dir
|
26
|
+
value_str :diploma_dir
|
27
|
+
value_str :exam_dir
|
28
|
+
value_str :presence_sheet
|
29
|
+
value_str :presence_sheet_small
|
30
|
+
value_str :card_student
|
31
|
+
value_str :card_responsible
|
32
|
+
|
33
|
+
value_block :captive_conn
|
34
|
+
value_str :keep_idle_free
|
35
|
+
value_str :keep_idle_minutes
|
36
|
+
value_str :captive_dev
|
37
|
+
|
38
|
+
value_block :captive
|
39
|
+
value_str :prerouting
|
40
|
+
value_str :http_proxy
|
41
|
+
value_str :allow_dst
|
42
|
+
value_str :internal_ips
|
43
|
+
value_str :captive_dnat
|
44
|
+
value_str :openvpn_allow_double
|
45
|
+
value_str :allow_src_direct
|
46
|
+
value_str :allow_src_proxy
|
47
|
+
value_str :allow_double
|
48
|
+
|
49
|
+
value_block :operator
|
50
|
+
value_int :cost_base
|
51
|
+
value_int :cost_shared
|
52
|
+
value_list_drop :allow_free, '%w(false true all)'
|
53
|
+
value_str :phone_main
|
54
|
+
value_str :start_loaded
|
55
|
+
|
56
|
+
value_block :internet
|
57
|
+
value_entity_internetClass_empty_all :iclass_default, :drop, :name
|
58
|
+
|
59
|
+
value_block :mobilecontrol
|
60
|
+
value_text :connection_cmds_up
|
61
|
+
value_text :connection_cmds_down
|
62
|
+
value_str :connection_services_up
|
63
|
+
value_str :connection_services_down
|
64
|
+
value_str :connection_vpns
|
65
|
+
|
66
|
+
value_block :accounts
|
67
|
+
value_entity_account :account_activities, :drop, :path
|
68
|
+
value_entity_account :account_services, :drop, :path
|
69
|
+
value_entity_account :account_lending, :drop, :path
|
70
|
+
value_entity_account :account_cash, :drop, :path
|
71
|
+
|
72
|
+
@@functions = %w( network share network_pro
|
73
|
+
courses course_server course_client
|
74
|
+
files_manage
|
75
|
+
internet internet_simple internet_captive
|
76
|
+
internet_free_course internet_free_staff
|
77
|
+
internet_cyber
|
78
|
+
internet_mobile internet_mobile_autocharge
|
79
|
+
inventory accounting quiz accounting_courses accounting_old
|
80
|
+
plug_admin special special_vnc remote_chat
|
81
|
+
cashbox email usage_report activities library ).sort.to_sym
|
82
|
+
@@functions_base = {:network => [:internet, :share, :internet_only, :email,
|
83
|
+
:internet_mobile, :network_pro],
|
84
|
+
:internet => [:internet_simple, :internet_captive,
|
85
|
+
:internet_free_course, :internet_free_staff,
|
86
|
+
:internet_mobile, :internet_cyber],
|
87
|
+
:courses => [:course_server, :course_client, :accounting_courses],
|
88
|
+
:accounting => [:accounting_courses, :cashbox],
|
89
|
+
:cashbox => [:accounting_courses, :internet_cyber, :activities],
|
90
|
+
:activities => [:library],
|
91
|
+
:special => [:plug_admin, :special_vnc],
|
92
|
+
:internet_mobile => [:internet_mobile_autocharge]
|
93
|
+
}
|
94
|
+
@@functions_conflict = [[:course_server, :course_client]]
|
95
|
+
end
|
96
|
+
|
97
|
+
def migration_10(c)
|
98
|
+
c.allow_free = [c.allow_free]
|
99
|
+
c.account_activities = c.account_services
|
100
|
+
end
|
101
|
+
|
102
|
+
def migration_9(c)
|
103
|
+
c.diploma_dir = get_config('Diplomas', :Entities, :Courses, :dir_diplomas)
|
104
|
+
c.template_dir = get_config('Diplomas', :Entities, :Courses, :dir_diplomas)
|
105
|
+
c.exam_dir = get_config('Exams', :Entities, :Courses, :dir_exas)
|
106
|
+
# Old installation had default directory of 'Exas'
|
107
|
+
File.exists?('Exas') && c.exam_dir != 'Exas' and FileUtils.mv('Exas', c.exam_dir)
|
108
|
+
c.presence_sheet = get_config('presence_sheet.ods',
|
109
|
+
:Entities, :Courses, :presence_sheet).to_a
|
110
|
+
c.presence_sheet_small = get_config('presence_sheet_small.ods',
|
111
|
+
:Entities, :Courses, :presence_sheet_small).to_a
|
112
|
+
c.card_student = get_config('student_card.odg', :Entities, :Persons, :student_card)
|
113
|
+
c.persons_adduser_cmd = get_config('', :Entities, :Persons, :adduser_cmd)
|
114
|
+
c.persons_addeduser_cmd = get_config('', :Entities, :Persons, :cmd_after_new)
|
115
|
+
c.dputs_logall = '/var/log/gestion/gestion.log'
|
116
|
+
c.dputs_logfile = '/var/log/gestion/events.log'
|
117
|
+
c.dputs_show_time = %w(min)
|
118
|
+
c.dputs_silent = %w(false)
|
119
|
+
c.dputs_terminal_width = 160
|
120
|
+
c.html_title = 'Gestion from Profeda'
|
121
|
+
c.autosave = %w(true)
|
122
|
+
c.autosave_timer = get_config(60, :autosave, :timer)
|
123
|
+
c.openprint_simul = %w(false)
|
124
|
+
c.openprint_search = get_config('.*', :OpenPrint, :search_remote)
|
125
|
+
c.upload_files = get_config('/tmp', :UploadFiles, :path)
|
126
|
+
c.captive_dev = ''
|
127
|
+
c.connection_cmds_up = "postqueue -f\n/usr/local/bin/dnsmasq-internet.sh"
|
128
|
+
c.connection_cmds_down = '/usr/local/bin/dnsmasq-catchall.sh'
|
129
|
+
c.connection_services_up = 'ntpd fetchmail'
|
130
|
+
c.connection_services_down = 'fetchmail'
|
131
|
+
c.connection_vpns = if (vpns = Dir.glob('/etc/openvpn/vpn-profeda*conf')).length > 0
|
132
|
+
vpns.collect { |v| File.basename v, '.conf' }.join(' ')
|
133
|
+
else
|
134
|
+
nil
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def migration_8(c)
|
139
|
+
c.show_passwords = %w(lesser)
|
140
|
+
end
|
141
|
+
|
142
|
+
def migration_7(c)
|
143
|
+
c.replace_function(:sms_control, :internet_mobile)
|
144
|
+
c.replace_function(:sms_control_autocharge, :internet_mobile_autocharge)
|
145
|
+
end
|
146
|
+
|
147
|
+
def migration_6(c)
|
148
|
+
c._use_printing = c._use_printing.to_i > 0
|
149
|
+
end
|
150
|
+
|
151
|
+
def migration_5(c)
|
152
|
+
c.account_services = Accounts.get_by_path_or_create(
|
153
|
+
get_config('Root::Income::Services', :Accounting, :service))
|
154
|
+
c.account_lending = Accounts.get_by_path_or_create(
|
155
|
+
get_config('Root::Lending', :Accounting, :lending))
|
156
|
+
c.account_cash = Accounts.get_by_path_or_create(
|
157
|
+
get_config('Root::Cash', :Accounting, :cash))
|
158
|
+
#dp c
|
159
|
+
end
|
160
|
+
|
161
|
+
def migration_4(c)
|
162
|
+
if c._functions.index(:internet_libnet)
|
163
|
+
c._functions -= [:internet_libnet]
|
164
|
+
c._functions += [:internet_captive]
|
165
|
+
end
|
166
|
+
if !c.welcome_text || c.welcome_text == ''
|
167
|
+
c.welcome_text = get_config('', :welcome_text)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def migration_3(c)
|
172
|
+
c.cost_base = 0
|
173
|
+
c.cost_shared = 0
|
174
|
+
c.allow_free = 'false'
|
175
|
+
end
|
176
|
+
|
177
|
+
def migration_2(c)
|
178
|
+
c.keep_idle_free = 5
|
179
|
+
c.keep_idle_minutes = 3
|
180
|
+
c.server_url = 'icc.profeda.org'
|
181
|
+
c.label_url = 'label.profeda.org'
|
182
|
+
end
|
183
|
+
|
184
|
+
# Migration_1 is taken by QooxView-ConfigBase!
|
185
|
+
end
|
186
|
+
|
187
|
+
class ConfigBase < Entity
|
188
|
+
def send_config
|
189
|
+
save_block_to_object :captive, Network::Captive
|
190
|
+
Network::Captive.clean_config
|
191
|
+
ConfigBase.has_function?(:internet_captive) and Network::Captive.setup
|
192
|
+
save_block_to_object :operator, Network::Operator
|
193
|
+
Network::Operator.clean_config
|
194
|
+
if ConfigBase.samba_simul.to_s == "false"
|
195
|
+
if ConfigBase.has_function?(:share)
|
196
|
+
Platform.enable_start(:samba)
|
197
|
+
else
|
198
|
+
Platform.stop_disable(:samba)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
if ConfigBase.has_function?(:internet_mobile)
|
202
|
+
start_mobile_control
|
203
|
+
save_block_to_object :mobilecontrol, $MobileControl
|
204
|
+
$MobileControl.autocharge = ConfigBase.has_function?(:internet_mobile_autocharge)
|
205
|
+
else
|
206
|
+
stop_mobile_control
|
207
|
+
end
|
208
|
+
if ConfigBase.has_function?(:accounting) && Entities.is_setup?(:Person)
|
209
|
+
Persons.search_by_permissions('secretary').each{|p|
|
210
|
+
p.update_accounts
|
211
|
+
}
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
def replace_function(old, new)
|
216
|
+
func = self.functions.to_sym
|
217
|
+
if func.index(old.to_sym)
|
218
|
+
func -= [old.to_sym]
|
219
|
+
func += [new.to_sym]
|
220
|
+
end
|
221
|
+
self.functions = func
|
222
|
+
end
|
223
|
+
|
224
|
+
def start_mobile_control
|
225
|
+
return if $MobileControl
|
226
|
+
dputs(1) { 'Starting mobile-control' }
|
227
|
+
$MobileControl = Network::MobileControl.new
|
228
|
+
|
229
|
+
@mobile_thread = Thread.new {
|
230
|
+
state = nil
|
231
|
+
loop {
|
232
|
+
rescue_all 'Error with MobileControl' do
|
233
|
+
$MobileControl.check_connection
|
234
|
+
if state != $MobileControl.state_to_s
|
235
|
+
dputs(2) { "#{Time.now.strftime('%y%m%d-%H%M')}: #{state = $MobileControl.state_to_s}" }
|
236
|
+
end
|
237
|
+
sleep 10
|
238
|
+
end
|
239
|
+
}
|
240
|
+
}
|
241
|
+
end
|
242
|
+
|
243
|
+
def stop_mobile_control
|
244
|
+
if @mobile_thread
|
245
|
+
@mobile_thread.kill
|
246
|
+
@mobile_thread.join
|
247
|
+
@mobile_thread = nil
|
248
|
+
end
|
249
|
+
$MobileControl = nil
|
250
|
+
end
|
251
|
+
|
252
|
+
def server_uri
|
253
|
+
server_url =~ /^http/ ? server_url : "http://#{server_url}"
|
254
|
+
end
|
255
|
+
|
256
|
+
def get_url(url)
|
257
|
+
if url.class == Symbol
|
258
|
+
url = ConfigBase.data_get(url)
|
259
|
+
end
|
260
|
+
url =~ /^https{0,1}:\/\// ? url : "http://#{url}"
|
261
|
+
end
|
262
|
+
|
263
|
+
def templates
|
264
|
+
Dir.glob("#{template_dir}/*.od?").
|
265
|
+
collect { |f| f.sub(/^.*\//, '') }.
|
266
|
+
sort
|
267
|
+
end
|
268
|
+
|
269
|
+
def template_path(t)
|
270
|
+
return '' unless template_dir && card_student && card_responsible
|
271
|
+
"#{template_dir}/" +
|
272
|
+
case t
|
273
|
+
when :card_student
|
274
|
+
card_student.first.to_s
|
275
|
+
when :card_responsible
|
276
|
+
card_responsible.first.to_s
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
end
|