Commit 1ac6167675cfca3ac4a14c16f9364506d3a3bfca
Exists in
theme-brasil-digital-from-staging
and in
9 other branches
Merge branch 'master' into AI3074-community_dashboard
Showing
1288 changed files
with
98103 additions
and
144085 deletions
Show diff stats
Too many changes.
To preserve performance only 100 of 1288 files displayed.
AUTHORS
@@ -1,240 +0,0 @@ | @@ -1,240 +0,0 @@ | ||
1 | -If you are not listed here, but should be, please write to the noosfero mailing | ||
2 | -list: http://listas.softwarelivre.org/cgi-bin/mailman/listinfo/noosfero-dev | ||
3 | -(this list requires subscription to post, but since you are an author of | ||
4 | -noosfero, that's not a problem). | ||
5 | - | ||
6 | -Developers | ||
7 | -========== | ||
8 | - | ||
9 | -Alan Freihof Tygel <alantygel@gmail.com> | ||
10 | -alcampelo <alcampelo@alcampelo.(none)> | ||
11 | -Alessandro Palmeira <alessandro.palmeira@gmail.com> | ||
12 | -Alessandro Palmeira + Caio C. Salgado <alessandro.palmeira@gmail.com> | ||
13 | -Alessandro Palmeira + Caio Salgado <alessandro.palmeira@gmail.com> | ||
14 | -Alessandro Palmeira + Caio Salgado <caio.csalgado@gmail.com> | ||
15 | -Alessandro Palmeira + Caio Salgado + Diego Araújo + João M. M. da Silva <diegoamc90@gmail.com> | ||
16 | -Alessandro Palmeira + Carlos Morais <alessandro.palmeira@gmail.com> | ||
17 | -Alessandro Palmeira + Daniel Alves <alessandro.palmeira@gmail.com> | ||
18 | -Alessandro Palmeira + Daniel Alves + Diego Araújo <diegoamc90@gmail.com> | ||
19 | -Alessandro Palmeira + Daniel Alves + Diego Araújo + Guilherme Rojas <danpaulalves@gmail.com> | ||
20 | -Alessandro Palmeira + Diego Araujo <alessandro.palmeira@gmail.com> | ||
21 | -Alessandro Palmeira + Diego Araújo <alessandro.palmeira@gmail.com> | ||
22 | -Alessandro Palmeira + Diego Araujo + Daniela Feitosa <alessandro.palmeira@gmail.com> | ||
23 | -Alessandro Palmeira + Diego Araujo <diegoamc90@gmail.com> | ||
24 | -Alessandro Palmeira + Diego Araújo <diegoamc90@gmail.com> | ||
25 | -Alessandro Palmeira + Diego Araujo + Eduardo Morais <alessandro.palmeira@gmail.com> | ||
26 | -Alessandro Palmeira + Diego Araújo + João M. M. da Silva <alessandro.palmeira@gmail.com> | ||
27 | -Alessandro Palmeira + Diego Araújo + João M. M. da Silva <diegoamc90@gmail.com> | ||
28 | -Alessandro Palmeira + Diego Araujo + João M. M. da Silva + Paulo Meirelles <alessandro.palmeira@gmail.com> | ||
29 | -Alessandro Palmeira + Diego Araújo + Pedro Leal <diegoamc90@gmail.com> | ||
30 | -Alessandro Palmeira + Diego Araújo + Pedro Leal + João M. M. da Silva <diegoamc90@gmail.com> | ||
31 | -Alessandro Palmeira + Diego Araujo + Rafael Manzo <alessandro.palmeira@gmail.com> | ||
32 | -Alessandro Palmeira + Eduardo Morais <alessandro.palmeira@gmail.com> | ||
33 | -Alessandro Palmeira + Guilherme Rojas <alessandro.palmeira@gmail.com> | ||
34 | -Alessandro Palmeira + Jefferson Fernandes <alessandro.palmeira@gmail.com> | ||
35 | -Alessandro Palmeira + João M. M. da Silva <alessandro.palmeira@gmail.com> | ||
36 | -Alessandro Palmeira + Joao M. M. da Silva + Diego Araujo <alessandro.palmeira@gmail.com> | ||
37 | -Alessandro Palmeira + João M. M. da Silva + Renan Teruo <alessandro.palmeira@gmail.com> | ||
38 | -Alessandro Palmeira + João M. M. Silva <alessandro.palmeira@gmail.com> | ||
39 | -Alessandro Palmeira + Paulo Meirelles <alessandro.palmeira@gmail.com> | ||
40 | -Alessandro Palmeira + Paulo Meirelles + João M. M. da Silva <alessandro.palmeira@gmail.com> | ||
41 | -Alessandro Palmeira + Rafael Manzo <alessandro.palmeira@gmail.com> | ||
42 | -Ana Losnak <analosnak@gmail.com> | ||
43 | -Antonio Terceiro + Carlos Morais <terceiro@colivre.coop.br> | ||
44 | -Antonio Terceiro + Paulo Meirelles <terceiro@colivre.coop.br> | ||
45 | -Antonio Terceiro <terceiro@colivre.coop.br> | ||
46 | -Arthur Del Esposte <arthurmde@yahoo.com.br> | ||
47 | -Aurelio A. Heckert <aurelio@colivre.coop.br> | ||
48 | -Braulio Bhavamitra <brauliobo@gmail.com> | ||
49 | -Bráulio Bhavamitra <brauliobo@gmail.com> | ||
50 | -Braulio Bhavamitra <braulio@eita.org.br> | ||
51 | -Caio <caio.csalgado@gmail.com> | ||
52 | -Caio + Diego + Pedro + João <caio.csalgado@gmail.com> | ||
53 | -Caio Formiga <caio.formiga@gmail.com> | ||
54 | -Caio, Pedro <caio.csalgado@gmail.com> | ||
55 | -Caio Salgado + Alessandro Palmeira <caio.csalgado@gmail.com> | ||
56 | -Caio Salgado <caio.csalgado@gmail.com> | ||
57 | -Caio Salgado + Carlos Morais + Diego Araújo + Pedro Leal <diegoamc90@gmail.com> | ||
58 | -Caio Salgado + Diego Araujo <caio.csalgado@gmail.com> | ||
59 | -Caio Salgado + Diego Araújo <caio.csalgado@gmail.com> | ||
60 | -Caio Salgado + Diego Araújo <diegoamc90@gmail.com> | ||
61 | -Caio Salgado + Diego Araújo + Jefferson Fernandes <caio.csalgado@gmail.com> | ||
62 | -Caio Salgado + Diego Araújo + João M. M. da Silva <caio.csalgado@gmail.com> | ||
63 | -Caio Salgado + Diego Araújo + Pedro Leal <caio.csalgado@gmail.com> | ||
64 | -Caio Salgado + Diego Araújo + Pedro Leal <diegoamc90@gmail.com> | ||
65 | -Caio Salgado + Diego Araújo + Rafael Manzo <diegoamc90@gmail.com> | ||
66 | -Caio Salgado + Jefferson Fernandes <caio.csalgado@gmail.com> | ||
67 | -Caio Salgado + Jefferson Fernandes <jeffs.fernandes@gmail.com> | ||
68 | -Caio Salgado + Rafael Manzo <caio.csalgado@gmail.com> | ||
69 | -Caio Salgado + Renan Teruo <caio.csalgado@gmail.com> | ||
70 | -Caio Salgado + Renan Teruo <caio.salgado@gmail.com> | ||
71 | -Caio Salgado + Renan Teruo + Jefferson Fernandes <jeffs.fernandes@gmail.com> | ||
72 | -Caio Salgado + Renan Teruo <renanteruoc@gmail.com> | ||
73 | -Caio SBA <caio@colivre.coop.br> | ||
74 | -Carlos Andre de Souza <carlos.andre.souza@msn.com> | ||
75 | -Carlos Morais <carlos88morais@gmail.com> | ||
76 | -Carlos Morais + Diego Araújo <diegoamc90@gmail.com> | ||
77 | -Carlos Morais + Eduardo Morais <carlos88morais@gmail.com> | ||
78 | -Carlos Morais + Paulo Meirelles <carlos88morais@gmail.com> | ||
79 | -Carlos Morais + Pedro Leal <carlos88morais@gmail.com> | ||
80 | -Daniel Alves + Diego Araújo <danpaulalves@gmail.com> | ||
81 | -Daniel Alves + Diego Araújo <diegoamc90@gmail.com> | ||
82 | -Daniel Alves + Diego Araújo + Guilherme Rojas <danpaulalves@gmail.com> | ||
83 | -Daniel Alves + Diego Araújo + Guilherme Rojas <diegoamc90@gmail.com> | ||
84 | -Daniel Alves + Diego Araújo + Guilherme Rojas <guilhermehrojas@gmail.com> | ||
85 | -Daniel Alves + Guilherme Rojas <danpaulalves@gmail.com> | ||
86 | -Daniel Alves + Rafael Manzo <rr.manzo@gmail.com> | ||
87 | -Daniela Soares Feitosa <danielafeitosa@colivre.coop.br> | ||
88 | -Daniel Bucher <daniel.bucher88@gmail.com> | ||
89 | -Daniel Cunha <daniel@colivre.coop.br> | ||
90 | -David Carlos <ddavidcarlos1392@gmail.com> | ||
91 | -diegoamc <diegoamc90@gmail.com> | ||
92 | -Diego Araújo + Alessandro Palmeira <diegoamc90@gmail.com> | ||
93 | -Diego Araújo + Alessandro Palmeira + João M. M. da Silva <diegoamc90@gmail.com> | ||
94 | -Diego Araújo + Alessandro Palmeira + Rafael Manzo <rr.manzo@gmail.com> | ||
95 | -Diego Araujo + Caio Salgado <diegoamc90@gmail.com> | ||
96 | -Diego Araújo + Daniel Alves + Rafael Manzo <rr.manzo@gmail.com> | ||
97 | -Diego Araújo <diegoamc90@gmail.com> | ||
98 | -Diego Araújo + Eduardo Morais + Paulo Meirelles <diegoamc90@gmail.com> | ||
99 | -Diego Araújo + Guilherme Rojas <diegoamc90@gmail.com> | ||
100 | -Diego Araújo + Jefferson Fernandes <diegoamc90@gmail.com> | ||
101 | -Diego Araujo + Jefferson Fernandes <jeffs.fernandes@gmail.com> | ||
102 | -Diego Araújo + João Machini <diegoamc90@gmail.com> | ||
103 | -Diego Araújo + João Machini <digoamc90@gmail.com> | ||
104 | -Diego Araújo + João M. M. da Silva + Alessandro Palmeira <jaodsilv@linux.ime.usp.br> | ||
105 | -Diego Araújo + João M. M. da Silva <diegoamc90@gmail.com> | ||
106 | -Diego Araújo + João M. M. da Silva + João Machini <diegoamc90@gmail.com> | ||
107 | -Diego Araújo + João M. M. da Silva + Pedro Leal <diegoamc90@gmail.com> | ||
108 | -Diego Araújo + Paulo Meirelles <diegoamc90@gmail.com> | ||
109 | -Diego Araújo + Pedro Leal <diegoamc90@gmail.com> | ||
110 | -Diego Araujo + Rafael Manzo <diegoamc90@gmail.com> | ||
111 | -Diego Araújo + Rafael Manzo <diegoamc90@gmail.com> | ||
112 | -Diego Araújo + Renan Teruo + Alessandro Palmeira <diegoamc90@gmail.com> | ||
113 | -Diego Araújo + Renan Teruo <diegoamc90@gmail.com> | ||
114 | -Diego Araujo + Rodrigo Souto + Rafael Manzo <rr.manzo@gmail.com> | ||
115 | -Diego + Jefferson <diegoamc90@gmail.com> | ||
116 | -Diego Martinez <diegoamc90@gmail.com> | ||
117 | -Diego Martinez <diego@diego-K55A.(none)> | ||
118 | -Diego + Renan <renanteruoc@gmail.com> | ||
119 | -Eduardo Tourinho Edington <eduardo.edington@serpro.gov.br> | ||
120 | -Fabio Teixeira <fabio1079@gmail.com> | ||
121 | -Fernanda Lopes <nanda.listas+psl@gmail.com> | ||
122 | -Francisco Marcelo A. Lima Júnior <francisco.lima-junior@serpro.gov.br> | ||
123 | -Francisco Marcelo de Araujo Lima Junior <79350259591@serpro-1457614.(none)> | ||
124 | -Francisco Marcelo de Araújo Lima Júnior <francisco.lima-junior@serpro.gov.br> | ||
125 | -Francisco Marcelo de Araújo Lima Júnior <maljunior@gmail.com> | ||
126 | -Gabriela Navarro <navarro1703@gmail.com> | ||
127 | -Grazieno Pellegrino <grazieno@gmail.com> | ||
128 | -Gust <darksshades@hotmail.com> | ||
129 | -Hugo Melo <hugo@riseup.net> | ||
130 | -Isaac Canan <isaac@intelletto.com.br> | ||
131 | -Italo Valcy <italo@dcc.ufba.br> | ||
132 | -Jefferson Fernandes + Diego Araujo + Rafael Manzo <jeffs.fernandes@gmail.com> | ||
133 | -Jefferson Fernandes + Joao M. M. da Silva <jeffs.fernandes@gmail.com> | ||
134 | -Jefferson Fernandes + Joao M. M. Silva <jeffs.fernandes@gmail.com> | ||
135 | -João da Silva <jaodsilv@linux.ime.usp.br> | ||
136 | -João Marco Maciel da Silva + Rafael Manzo + Renan Teruo <jaodsilv@linux.ime.usp.br> | ||
137 | -João M. M. da Silva + Alessandro Palmeira + Diego Araújo + Caio Salgado <jaodsilv@linux.ime.usp.br> | ||
138 | -João M. M. da Silva + Alessandro Palmeira + Diego Araújo <jaodsilv@linux.ime.usp.br> | ||
139 | -Joao M. M. da Silva + Alessandro Palmeira <jaodsilv@linux.ime.usp.br> | ||
140 | -João M. M. da Silva + Alessandro Palmeira <jaodsilv@linux.ime.usp.br> | ||
141 | -João M. M. da Silva + Alessandro Palmeira + João Machini <jaodsilv@linux.ime.usp.br> | ||
142 | -João M. M. da Silva + Caio Salgado + Alessandro Palmeira <jaodsilv@linux.ime.usp.br> | ||
143 | -João M. M. da Silva + Caio Salgado <jaodsilv@linux.ime.usp.br> | ||
144 | -João M. M. da Silva + Carlos Morais <jaodsilv@linux.ime.usp.br> | ||
145 | -João M. M. da Silva + Diego Araújo <diegoamc90@gmail.com> | ||
146 | -João M. M. da Silva + Diego Araújo <jaodsilv@linux.ime.usp.br> | ||
147 | -João M. M. da Silva + Diego Araújo + Pedro Leal <jaodsilv@linux.ime.usp.br> | ||
148 | -João M. M. da Silva <jaodsilv@linux.ime.usp.br> | ||
149 | -Joao M. M. da Silva + Jefferson Fernandes <jaodsilv@linux.ime.usp.br> | ||
150 | -João M. M. da Silva + Jefferson Fernandes <jaodsilv@linux.ime.usp.br> | ||
151 | -João M. M. da Silva + João M. Miranda <jaodsilv@linux.ime.usp.br> | ||
152 | -João M. M. da Silva + Paulo Meirelles <jaodsilv@linux.ime.usp.br> | ||
153 | -João M. M. da Silva + Pedro Leal <jaodsilv@linux.ime.usp.br> | ||
154 | -João M. M. da Silva + Rafael Manzo + Diego Araújo <jaodsilv@linux.ime.usp.br> | ||
155 | -João M. M. da Silva + Rafael Manzo <jaodsilv@linux.ime.usp.br> | ||
156 | -João M. M. da Silva + Renan Teruo <jaodsilv@linux.ime.usp.br> | ||
157 | -João M. M. Silva + Caio Salgado <jaodsilv@linux.ime.usp.br> | ||
158 | -João M. M. Silva + Diego Araújo <jaodsilv@linux.ime.usp.br> | ||
159 | -Joao M. M. Silva + Jefferson Fernandes <jaodsilv@linux.ime.usp.br> | ||
160 | -João M. M. Silva + Paulo Meirelles <jaodsilv@linux.ime.usp.br> | ||
161 | -João M. M. Silva + Rafael Manzo <jaodsilv@linux.ime.usp.br> | ||
162 | -João M. M. Silva + Renan Teruo <jaodsilv@linux.ime.usp.br> | ||
163 | -Joenio Costa <joenio@colivre.coop.br> | ||
164 | -Josef Spillner <josef.spillner@tu-dresden.de> | ||
165 | -Junior Silva <junior@bajor.localhost.localdomain> | ||
166 | -Junior Silva <juniorsilva1001@gmail.com> | ||
167 | -Junior Silva <juniorsilva7@juniorsilva-Aspire-5750Z.(none)> | ||
168 | -Junior Silva <juniorsilva@colivre.coop.br> | ||
169 | -Keilla Menezes <keilla@colivre.coop.br> | ||
170 | -Larissa Reis <larissa@colivre.coop.br> | ||
171 | -Larissa Reis <reiss.larissa@gmail.com> | ||
172 | -Leandro Nunes dos Santos <81665687568@serpro-1541727.Home> | ||
173 | -Leandro Nunes dos Santos <81665687568@serpro-1541727.(none)> | ||
174 | -Leandro Nunes dos Santos <leandronunes@gmail.com> | ||
175 | -Leandro Nunes dos Santos <leandro.santos@serpro.gov.br> | ||
176 | -LinguÁgil 2010 <linguagil.bahia@gmail.com> | ||
177 | -Lucas Melo <lucas@colivre.coop.br> | ||
178 | -Lucas Melo <lucaspradomelo@gmail.com> | ||
179 | -Luis David Aguilar Carlos <ludwig9003@gmail.com> | ||
180 | -Marcos Ramos <ms.ramos@outlook.com> | ||
181 | -Martín Olivera <molivera@solar.org.ar> | ||
182 | -Moises Machado <moises@colivre.coop.br> | ||
183 | -Naíla Alves <naila@colivre.coop.br> | ||
184 | -Nanda Lopes <nanda.listas+psl@gmail.com> | ||
185 | -Paulo Meirelles + Alessandro Palmeira + João M. M. da Silva <paulo@softwarelivre.org> | ||
186 | -Paulo Meirelles + Alessandro Palmeira <paulo@softwarelivre.org> | ||
187 | -Paulo Meirelles + Carlos Morais <paulo@softwarelivre.org> | ||
188 | -Paulo Meirelles + Diego Araújo <paulo@softwarelivre.org> | ||
189 | -Paulo Meirelles + João M. M. da Silva <paulo@softwarelivre.org> | ||
190 | -Paulo Meirelles <paulo@softwarelivre.org> | ||
191 | -Paulo Meirelles + Rafael Manzo <paulo@softwarelivre.org> | ||
192 | -Rafael Gomes <rafaelgomes@techfree.com.br> | ||
193 | -Rafael Manzo + Alessandro Palmeira <rr.manzo@gmail.com> | ||
194 | -Rafael Manzo + Daniel Alves <danpaulalves@gmail.com> | ||
195 | -Rafael Manzo + Diego Araújo <rr.manzo@gmail.com> | ||
196 | -Rafael Manzo + João M. M. Silva <rr.manzo@gmail.com> | ||
197 | -Rafael Manzo + Paulo Meirelles <rr.manzo@gmail.com> | ||
198 | -Rafael Martins <rmmartins@gmail.com> | ||
199 | -Rafael Reggiani Manzo + Caio Salgado + Jefferson Fernandes <rr.manzo@gmail.com> | ||
200 | -Rafael Reggiani Manzo + Diego Araujo <diegoamc90@gmail.com> | ||
201 | -Rafael Reggiani Manzo + Diego Araujo <rr.manzo@gmail.com> | ||
202 | -Rafael Reggiani Manzo + Diego Araújo <rr.manzo@gmail.com> | ||
203 | -Rafael Reggiani Manzo + João M. M. da Silva <rr.manzo@gmail.com> | ||
204 | -Rafael Reggiani Manzo <rr.manzo@gmail.com> | ||
205 | -Raphaël Rousseau <raph@r4f.org> | ||
206 | -Raquel Lira <raquel.lira@gmail.com> | ||
207 | -Renan Teruo + Caio Salgado <renanteruoc@gmail.com> | ||
208 | -Renan Teruoc + Diego Araujo <renanteruoc@gmail.com> | ||
209 | -Renan Teruo + Diego Araujo <renanteruoc@gmail.com> | ||
210 | -Renan Teruo + Diego Araújo <renanteruoc@gmail.com> | ||
211 | -Renan Teruo + Paulo Meirelles <renanteruoc@gmail.com> | ||
212 | -Renan Teruo + Rafael Manzo <renanteruoc@gmail.com> | ||
213 | -Rodrigo Souto + Ana Losnak + Daniel Bucher + Caio Almeida + Leandro Nunes + Daniela Feitosa + Mariel Zasso <noosfero-br@listas.softwarelivre.org> | ||
214 | -Rodrigo Souto <diguliu@gmail.com> | ||
215 | -Rodrigo Souto <rodrigo@colivre.coop.br> | ||
216 | -Ronny Kursawe <kursawe.ronny@googlemail.com> | ||
217 | -root <root@debian.sdr.serpro> | ||
218 | -Samuel R. C. Vale <srcvale@holoscopio.com> | ||
219 | -Valessio Brito <contato@valessiobrito.com.br> | ||
220 | -Valessio Brito <contato@valessiobrito.info> | ||
221 | -Valessio Brito <valessio@gmail.com> | ||
222 | -vfcosta <vfcosta@gmail.com> | ||
223 | -Victor Carvalho <victorhugodf.ac@gmail.com> | ||
224 | -Victor Costa <vfcosta@gmail.com> | ||
225 | -Victor Hugo Alves de Carvalho <victorhugodf.ac@gmail.com> | ||
226 | -Vinicius Cubas Brand <viniciuscb@gmail.com> | ||
227 | -Visita <visita@debian.(none)> | ||
228 | -Yann Lugrin <yann.lugrin@liquid-concept.ch> | ||
229 | - | ||
230 | -Ideas, specifications and incentive | ||
231 | -=================================== | ||
232 | -Daniel Tygel <dtygel@fbes.org.br> | ||
233 | -Guilherme Rocha <guilherme@gf7.com.br> | ||
234 | -Raphael Rousseau <raph@r4f.org> | ||
235 | -Théo Bondolfi <move@cooperation.net> | ||
236 | -Vicente Aguiar <vicenteaguiar@colivre.coop.br> | ||
237 | - | ||
238 | -Arts | ||
239 | -=================================== | ||
240 | -Nara Oliveira <narananet@gmail.com> |
AUTHORS.md
1 | -If you are not listed here, but should be, please write to the noosfero mailing list: http://listas.softwarelivre.org/cgi-bin/mailman/listinfo/noosfero-dev (this list requires subscription to post, but since you are an author of noosfero, that's not a problem). | 1 | +If you are not listed here, but should be, please write to the noosfero mailing |
2 | +list: http://listas.softwarelivre.org/cgi-bin/mailman/listinfo/noosfero-dev | ||
3 | +(this list requires subscription to post, but since you are an author of | ||
4 | +noosfero, that's not a problem). | ||
2 | 5 | ||
3 | Developers | 6 | Developers |
4 | ========== | 7 | ========== |
5 | 8 | ||
9 | +Ábner Silva de Oliveira <abner.oliveira@serpro.gov.br> | ||
6 | Alan Freihof Tygel <alantygel@gmail.com> | 10 | Alan Freihof Tygel <alantygel@gmail.com> |
11 | +alcampelo <alcampelo@alcampelo.(none)> | ||
7 | Alessandro Palmeira <alessandro.palmeira@gmail.com> | 12 | Alessandro Palmeira <alessandro.palmeira@gmail.com> |
8 | Alessandro Palmeira + Caio C. Salgado <alessandro.palmeira@gmail.com> | 13 | Alessandro Palmeira + Caio C. Salgado <alessandro.palmeira@gmail.com> |
9 | Alessandro Palmeira + Caio Salgado <alessandro.palmeira@gmail.com> | 14 | Alessandro Palmeira + Caio Salgado <alessandro.palmeira@gmail.com> |
@@ -35,9 +40,13 @@ Alessandro Palmeira + João M. M. Silva <alessandro.palmeira@gmail.com> | @@ -35,9 +40,13 @@ Alessandro Palmeira + João M. M. Silva <alessandro.palmeira@gmail.com> | ||
35 | Alessandro Palmeira + Paulo Meirelles <alessandro.palmeira@gmail.com> | 40 | Alessandro Palmeira + Paulo Meirelles <alessandro.palmeira@gmail.com> |
36 | Alessandro Palmeira + Paulo Meirelles + João M. M. da Silva <alessandro.palmeira@gmail.com> | 41 | Alessandro Palmeira + Paulo Meirelles + João M. M. da Silva <alessandro.palmeira@gmail.com> |
37 | Alessandro Palmeira + Rafael Manzo <alessandro.palmeira@gmail.com> | 42 | Alessandro Palmeira + Rafael Manzo <alessandro.palmeira@gmail.com> |
43 | +Ana Losnak <analosnak@gmail.com> | ||
44 | +Andre Bernardes <andrebsguedes@gmail.com> | ||
38 | Antonio Terceiro + Carlos Morais <terceiro@colivre.coop.br> | 45 | Antonio Terceiro + Carlos Morais <terceiro@colivre.coop.br> |
39 | Antonio Terceiro + Paulo Meirelles <terceiro@colivre.coop.br> | 46 | Antonio Terceiro + Paulo Meirelles <terceiro@colivre.coop.br> |
40 | Antonio Terceiro <terceiro@colivre.coop.br> | 47 | Antonio Terceiro <terceiro@colivre.coop.br> |
48 | +Arthur Del Esposte <arthurmde@gmail.com> | ||
49 | +Arthur Del Esposte <arthurmde@yahoo.com.br> | ||
41 | Aurelio A. Heckert <aurelio@colivre.coop.br> | 50 | Aurelio A. Heckert <aurelio@colivre.coop.br> |
42 | Braulio Bhavamitra <brauliobo@gmail.com> | 51 | Braulio Bhavamitra <brauliobo@gmail.com> |
43 | Bráulio Bhavamitra <brauliobo@gmail.com> | 52 | Bráulio Bhavamitra <brauliobo@gmail.com> |
@@ -65,11 +74,14 @@ Caio Salgado + Renan Teruo <caio.salgado@gmail.com> | @@ -65,11 +74,14 @@ Caio Salgado + Renan Teruo <caio.salgado@gmail.com> | ||
65 | Caio Salgado + Renan Teruo + Jefferson Fernandes <jeffs.fernandes@gmail.com> | 74 | Caio Salgado + Renan Teruo + Jefferson Fernandes <jeffs.fernandes@gmail.com> |
66 | Caio Salgado + Renan Teruo <renanteruoc@gmail.com> | 75 | Caio Salgado + Renan Teruo <renanteruoc@gmail.com> |
67 | Caio SBA <caio@colivre.coop.br> | 76 | Caio SBA <caio@colivre.coop.br> |
77 | +Caio Tiago Oliveira <caiotiago@colivre.coop.br> | ||
78 | +Carlos Andre de Souza <carlos.andre.souza@msn.com> | ||
68 | Carlos Morais <carlos88morais@gmail.com> | 79 | Carlos Morais <carlos88morais@gmail.com> |
69 | Carlos Morais + Diego Araújo <diegoamc90@gmail.com> | 80 | Carlos Morais + Diego Araújo <diegoamc90@gmail.com> |
70 | Carlos Morais + Eduardo Morais <carlos88morais@gmail.com> | 81 | Carlos Morais + Eduardo Morais <carlos88morais@gmail.com> |
71 | Carlos Morais + Paulo Meirelles <carlos88morais@gmail.com> | 82 | Carlos Morais + Paulo Meirelles <carlos88morais@gmail.com> |
72 | Carlos Morais + Pedro Leal <carlos88morais@gmail.com> | 83 | Carlos Morais + Pedro Leal <carlos88morais@gmail.com> |
84 | +Daniela Feitosa <dani@dohko.(none)> | ||
73 | Daniel Alves + Diego Araújo <danpaulalves@gmail.com> | 85 | Daniel Alves + Diego Araújo <danpaulalves@gmail.com> |
74 | Daniel Alves + Diego Araújo <diegoamc90@gmail.com> | 86 | Daniel Alves + Diego Araújo <diegoamc90@gmail.com> |
75 | Daniel Alves + Diego Araújo + Guilherme Rojas <danpaulalves@gmail.com> | 87 | Daniel Alves + Diego Araújo + Guilherme Rojas <danpaulalves@gmail.com> |
@@ -78,7 +90,9 @@ Daniel Alves + Diego Araújo + Guilherme Rojas <guilhermehrojas@gmail.com> | @@ -78,7 +90,9 @@ Daniel Alves + Diego Araújo + Guilherme Rojas <guilhermehrojas@gmail.com> | ||
78 | Daniel Alves + Guilherme Rojas <danpaulalves@gmail.com> | 90 | Daniel Alves + Guilherme Rojas <danpaulalves@gmail.com> |
79 | Daniel Alves + Rafael Manzo <rr.manzo@gmail.com> | 91 | Daniel Alves + Rafael Manzo <rr.manzo@gmail.com> |
80 | Daniela Soares Feitosa <danielafeitosa@colivre.coop.br> | 92 | Daniela Soares Feitosa <danielafeitosa@colivre.coop.br> |
93 | +Daniel Bucher <daniel.bucher88@gmail.com> | ||
81 | Daniel Cunha <daniel@colivre.coop.br> | 94 | Daniel Cunha <daniel@colivre.coop.br> |
95 | +David Carlos <ddavidcarlos1392@gmail.com> | ||
82 | diegoamc <diegoamc90@gmail.com> | 96 | diegoamc <diegoamc90@gmail.com> |
83 | Diego Araújo + Alessandro Palmeira <diegoamc90@gmail.com> | 97 | Diego Araújo + Alessandro Palmeira <diegoamc90@gmail.com> |
84 | Diego Araújo + Alessandro Palmeira + João M. M. da Silva <diegoamc90@gmail.com> | 98 | Diego Araújo + Alessandro Palmeira + João M. M. da Silva <diegoamc90@gmail.com> |
@@ -107,15 +121,26 @@ Diego + Jefferson <diegoamc90@gmail.com> | @@ -107,15 +121,26 @@ Diego + Jefferson <diegoamc90@gmail.com> | ||
107 | Diego Martinez <diegoamc90@gmail.com> | 121 | Diego Martinez <diegoamc90@gmail.com> |
108 | Diego Martinez <diego@diego-K55A.(none)> | 122 | Diego Martinez <diego@diego-K55A.(none)> |
109 | Diego + Renan <renanteruoc@gmail.com> | 123 | Diego + Renan <renanteruoc@gmail.com> |
124 | +Eduardo Tourinho Edington <eduardo.edington@serpro.gov.br> | ||
125 | +Evandro Jr <evandrojr@gmail.com> | ||
126 | +Evandro Junior <evandrojr@gmail.com> | ||
127 | +Fabio Teixeira <fabio1079@gmail.com> | ||
110 | Fernanda Lopes <nanda.listas+psl@gmail.com> | 128 | Fernanda Lopes <nanda.listas+psl@gmail.com> |
111 | Francisco Marcelo A. Lima Júnior <francisco.lima-junior@serpro.gov.br> | 129 | Francisco Marcelo A. Lima Júnior <francisco.lima-junior@serpro.gov.br> |
112 | Francisco Marcelo de Araujo Lima Junior <79350259591@serpro-1457614.(none)> | 130 | Francisco Marcelo de Araujo Lima Junior <79350259591@serpro-1457614.(none)> |
131 | +Francisco Marcelo de Araújo Lima Júnior <francisco.lima-junior@serpro.gov.br> | ||
132 | +Francisco Marcelo de Araújo Lima Júnior <maljunior@gmail.com> | ||
133 | +Gabriela Navarro <navarro1703@gmail.com> | ||
113 | Grazieno Pellegrino <grazieno@gmail.com> | 134 | Grazieno Pellegrino <grazieno@gmail.com> |
135 | +Gust <darksshades@hotmail.com> | ||
136 | +Hebert Douglas <hebertdougl@gmail.com> | ||
137 | +Hugo Melo <hugo@riseup.net> | ||
114 | Isaac Canan <isaac@intelletto.com.br> | 138 | Isaac Canan <isaac@intelletto.com.br> |
115 | Italo Valcy <italo@dcc.ufba.br> | 139 | Italo Valcy <italo@dcc.ufba.br> |
116 | Jefferson Fernandes + Diego Araujo + Rafael Manzo <jeffs.fernandes@gmail.com> | 140 | Jefferson Fernandes + Diego Araujo + Rafael Manzo <jeffs.fernandes@gmail.com> |
117 | Jefferson Fernandes + Joao M. M. da Silva <jeffs.fernandes@gmail.com> | 141 | Jefferson Fernandes + Joao M. M. da Silva <jeffs.fernandes@gmail.com> |
118 | Jefferson Fernandes + Joao M. M. Silva <jeffs.fernandes@gmail.com> | 142 | Jefferson Fernandes + Joao M. M. Silva <jeffs.fernandes@gmail.com> |
143 | +João da Silva + Eduardo Morais + Rafael Manzo <rr.manzo@gmail.com> | ||
119 | João da Silva <jaodsilv@linux.ime.usp.br> | 144 | João da Silva <jaodsilv@linux.ime.usp.br> |
120 | João Marco Maciel da Silva + Rafael Manzo + Renan Teruo <jaodsilv@linux.ime.usp.br> | 145 | João Marco Maciel da Silva + Rafael Manzo + Renan Teruo <jaodsilv@linux.ime.usp.br> |
121 | João M. M. da Silva + Alessandro Palmeira + Diego Araújo + Caio Salgado <jaodsilv@linux.ime.usp.br> | 146 | João M. M. da Silva + Alessandro Palmeira + Diego Araújo + Caio Salgado <jaodsilv@linux.ime.usp.br> |
@@ -146,17 +171,29 @@ João M. M. Silva + Rafael Manzo <jaodsilv@linux.ime.usp.br> | @@ -146,17 +171,29 @@ João M. M. Silva + Rafael Manzo <jaodsilv@linux.ime.usp.br> | ||
146 | João M. M. Silva + Renan Teruo <jaodsilv@linux.ime.usp.br> | 171 | João M. M. Silva + Renan Teruo <jaodsilv@linux.ime.usp.br> |
147 | Joenio Costa <joenio@colivre.coop.br> | 172 | Joenio Costa <joenio@colivre.coop.br> |
148 | Josef Spillner <josef.spillner@tu-dresden.de> | 173 | Josef Spillner <josef.spillner@tu-dresden.de> |
174 | +Jose Pedro <1jpsneto@gmail.com> | ||
175 | +Junior Silva <junior@bajor.localhost.localdomain> | ||
176 | +Junior Silva <junior@sedeantigo.colivre.coop.br> | ||
149 | Junior Silva <juniorsilva1001@gmail.com> | 177 | Junior Silva <juniorsilva1001@gmail.com> |
150 | Junior Silva <juniorsilva7@juniorsilva-Aspire-5750Z.(none)> | 178 | Junior Silva <juniorsilva7@juniorsilva-Aspire-5750Z.(none)> |
179 | +Junior Silva <juniorsilva@colivre.coop.br> | ||
180 | +juniorsilva <juniorsilva@QonoS.localhost.localdomain> | ||
151 | Keilla Menezes <keilla@colivre.coop.br> | 181 | Keilla Menezes <keilla@colivre.coop.br> |
152 | Larissa Reis <larissa@colivre.coop.br> | 182 | Larissa Reis <larissa@colivre.coop.br> |
153 | Larissa Reis <reiss.larissa@gmail.com> | 183 | Larissa Reis <reiss.larissa@gmail.com> |
184 | +Leandro Alves <leandrosustenido@gmail.com> | ||
185 | +Leandro Nunes dos Santos <81665687568@serpro-1541727.Home> | ||
186 | +Leandro Nunes dos Santos <81665687568@serpro-1541727.(none)> | ||
154 | Leandro Nunes dos Santos <leandronunes@gmail.com> | 187 | Leandro Nunes dos Santos <leandronunes@gmail.com> |
155 | Leandro Nunes dos Santos <leandro.santos@serpro.gov.br> | 188 | Leandro Nunes dos Santos <leandro.santos@serpro.gov.br> |
156 | LinguÁgil 2010 <linguagil.bahia@gmail.com> | 189 | LinguÁgil 2010 <linguagil.bahia@gmail.com> |
157 | Lucas Melo <lucas@colivre.coop.br> | 190 | Lucas Melo <lucas@colivre.coop.br> |
158 | Lucas Melo <lucaspradomelo@gmail.com> | 191 | Lucas Melo <lucaspradomelo@gmail.com> |
192 | +Luciano <lucianopcbr@gmail.com> | ||
193 | +Luciano Prestes Cavalcanti <lucianopcbr@gmail.com> | ||
159 | Luis David Aguilar Carlos <ludwig9003@gmail.com> | 194 | Luis David Aguilar Carlos <ludwig9003@gmail.com> |
195 | +Luiz Fernando de Freitas Matos <luiz@luizff.matos@gmail.com> | ||
196 | +Marcos Ramos <ms.ramos@outlook.com> | ||
160 | Martín Olivera <molivera@solar.org.ar> | 197 | Martín Olivera <molivera@solar.org.ar> |
161 | Moises Machado <moises@colivre.coop.br> | 198 | Moises Machado <moises@colivre.coop.br> |
162 | Naíla Alves <naila@colivre.coop.br> | 199 | Naíla Alves <naila@colivre.coop.br> |
@@ -189,14 +226,21 @@ Renan Teruo + Diego Araujo <renanteruoc@gmail.com> | @@ -189,14 +226,21 @@ Renan Teruo + Diego Araujo <renanteruoc@gmail.com> | ||
189 | Renan Teruo + Diego Araújo <renanteruoc@gmail.com> | 226 | Renan Teruo + Diego Araújo <renanteruoc@gmail.com> |
190 | Renan Teruo + Paulo Meirelles <renanteruoc@gmail.com> | 227 | Renan Teruo + Paulo Meirelles <renanteruoc@gmail.com> |
191 | Renan Teruo + Rafael Manzo <renanteruoc@gmail.com> | 228 | Renan Teruo + Rafael Manzo <renanteruoc@gmail.com> |
229 | +Rodrigo Souto + Ana Losnak + Daniel Bucher + Caio Almeida + Leandro Nunes + Daniela Feitosa + Mariel Zasso <noosfero-br@listas.softwarelivre.org> | ||
192 | Rodrigo Souto <diguliu@gmail.com> | 230 | Rodrigo Souto <diguliu@gmail.com> |
193 | Rodrigo Souto <rodrigo@colivre.coop.br> | 231 | Rodrigo Souto <rodrigo@colivre.coop.br> |
194 | Ronny Kursawe <kursawe.ronny@googlemail.com> | 232 | Ronny Kursawe <kursawe.ronny@googlemail.com> |
195 | root <root@debian.sdr.serpro> | 233 | root <root@debian.sdr.serpro> |
196 | Samuel R. C. Vale <srcvale@holoscopio.com> | 234 | Samuel R. C. Vale <srcvale@holoscopio.com> |
235 | +Tallys Martins <tallysmartins@gmail.com> | ||
236 | +tallys <tallys@tallys.(none)> | ||
237 | +Valessio Brito <contato@valessiobrito.com.br> | ||
238 | +Valessio Brito <contato@valessiobrito.info> | ||
197 | Valessio Brito <valessio@gmail.com> | 239 | Valessio Brito <valessio@gmail.com> |
198 | vfcosta <vfcosta@gmail.com> | 240 | vfcosta <vfcosta@gmail.com> |
241 | +Victor Carvalho <victorhugodf.ac@gmail.com> | ||
199 | Victor Costa <vfcosta@gmail.com> | 242 | Victor Costa <vfcosta@gmail.com> |
243 | +Victor Hugo Alves de Carvalho <victorhugodf.ac@gmail.com> | ||
200 | Vinicius Cubas Brand <viniciuscb@gmail.com> | 244 | Vinicius Cubas Brand <viniciuscb@gmail.com> |
201 | Visita <visita@debian.(none)> | 245 | Visita <visita@debian.(none)> |
202 | Yann Lugrin <yann.lugrin@liquid-concept.ch> | 246 | Yann Lugrin <yann.lugrin@liquid-concept.ch> |
Gemfile
1 | source "https://rubygems.org" | 1 | source "https://rubygems.org" |
2 | -gem 'rails' | ||
3 | -gem 'fast_gettext' | ||
4 | -gem 'acts-as-taggable-on' | ||
5 | -gem 'prototype-rails' | ||
6 | -gem 'prototype_legacy_helper', '0.0.0', :path => 'vendor/prototype_legacy_helper' | ||
7 | -gem 'rails_autolink' | ||
8 | -gem 'pg' | ||
9 | -gem 'rmagick' | ||
10 | -gem 'RedCloth' | ||
11 | -gem 'will_paginate' | ||
12 | -gem 'ruby-feedparser' | ||
13 | -gem 'daemons' | ||
14 | -gem 'thin' | ||
15 | -gem 'hpricot' | ||
16 | -gem 'nokogiri' | 2 | +gem 'rails', '~> 3.2.19' |
3 | +gem 'fast_gettext', '~> 0.6.8' | ||
4 | +gem 'acts-as-taggable-on', '~> 3.0.2' | ||
5 | +gem 'prototype-rails', '~> 3.2.1' | ||
6 | +gem 'prototype_legacy_helper', '0.0.0', :path => 'vendor/prototype_legacy_helper' | ||
7 | +gem 'rails_autolink', '~> 1.1.5' | ||
8 | +gem 'pg', '~> 0.13.2' | ||
9 | +gem 'rmagick', '~> 2.13.1' | ||
10 | +gem 'RedCloth', '~> 4.2.9' | ||
11 | +gem 'will_paginate', '~> 3.0.3' | ||
12 | +gem 'ruby-feedparser', '~> 0.7' | ||
13 | +gem 'daemons', '~> 1.1.5' | ||
14 | +gem 'thin', '~> 1.3.1' | ||
15 | +gem 'hpricot', '~> 0.8.6' | ||
16 | +gem 'nokogiri', '~> 1.5.5' | ||
17 | gem 'rake', :require => false | 17 | gem 'rake', :require => false |
18 | +gem 'rest-client', '~> 1.6.7' | ||
19 | +gem 'exception_notification', '~> 4.0.1' | ||
20 | +gem 'gettext', '~> 2.2.1', :require => false, :group => :development | ||
21 | +gem 'locale', '~> 2.0.5' | ||
18 | 22 | ||
19 | # FIXME list here all actual dependencies (i.e. the ones in debian/control), | 23 | # FIXME list here all actual dependencies (i.e. the ones in debian/control), |
20 | # with their GEM names (not the Debian package names) | 24 | # with their GEM names (not the Debian package names) |
21 | 25 | ||
22 | group :production do | 26 | group :production do |
23 | - gem 'dalli' | 27 | + gem 'dalli', '~> 2.7.0' |
24 | end | 28 | end |
25 | 29 | ||
26 | group :test do | 30 | group :test do |
27 | - gem 'rspec' | ||
28 | - gem 'rspec-rails' | 31 | + gem 'rspec', '~> 2.10.0' |
32 | + gem 'rspec-rails', '~> 2.10.1' | ||
33 | + gem 'mocha', '~> 1.1.0', :require => false | ||
29 | end | 34 | end |
30 | 35 | ||
31 | group :cucumber do | 36 | group :cucumber do |
32 | - gem 'rake' | ||
33 | - gem 'cucumber-rails', :require => false | ||
34 | - gem 'capybara' | ||
35 | - gem 'cucumber' | ||
36 | - gem 'database_cleaner' | ||
37 | - gem 'selenium-webdriver' | 37 | + gem 'cucumber-rails', '~> 1.0.6', :require => false |
38 | + gem 'capybara', '~> 2.1.0' | ||
39 | + gem 'cucumber', '~> 1.0.6' | ||
40 | + gem 'database_cleaner', '~> 1.2.0' | ||
41 | + gem 'selenium-webdriver', '~> 2.39.0' | ||
38 | end | 42 | end |
39 | 43 | ||
40 | # include plugin gemfiles | 44 | # include plugin gemfiles |
Gemfile.lock
@@ -1,180 +0,0 @@ | @@ -1,180 +0,0 @@ | ||
1 | -PATH | ||
2 | - remote: vendor/prototype_legacy_helper | ||
3 | - specs: | ||
4 | - prototype_legacy_helper (0.0.0) | ||
5 | - | ||
6 | -GEM | ||
7 | - remote: https://rubygems.org/ | ||
8 | - specs: | ||
9 | - RedCloth (4.2.9) | ||
10 | - actionmailer (3.2.6) | ||
11 | - actionpack (= 3.2.6) | ||
12 | - mail (~> 2.4.4) | ||
13 | - actionpack (3.2.6) | ||
14 | - activemodel (= 3.2.6) | ||
15 | - activesupport (= 3.2.6) | ||
16 | - builder (~> 3.0.0) | ||
17 | - erubis (~> 2.7.0) | ||
18 | - journey (~> 1.0.1) | ||
19 | - rack (~> 1.4.0) | ||
20 | - rack-cache (~> 1.2) | ||
21 | - rack-test (~> 0.6.1) | ||
22 | - sprockets (~> 2.1.3) | ||
23 | - activemodel (3.2.6) | ||
24 | - activesupport (= 3.2.6) | ||
25 | - builder (~> 3.0.0) | ||
26 | - activerecord (3.2.6) | ||
27 | - activemodel (= 3.2.6) | ||
28 | - activesupport (= 3.2.6) | ||
29 | - arel (~> 3.0.2) | ||
30 | - tzinfo (~> 0.3.29) | ||
31 | - activeresource (3.2.6) | ||
32 | - activemodel (= 3.2.6) | ||
33 | - activesupport (= 3.2.6) | ||
34 | - activesupport (3.2.6) | ||
35 | - i18n (~> 0.6) | ||
36 | - multi_json (~> 1.0) | ||
37 | - acts-as-taggable-on (3.0.2) | ||
38 | - rails (>= 3, < 5) | ||
39 | - arel (3.0.2) | ||
40 | - builder (3.0.0) | ||
41 | - capybara (2.1.0) | ||
42 | - mime-types (>= 1.16) | ||
43 | - nokogiri (>= 1.3.3) | ||
44 | - rack (>= 1.0.0) | ||
45 | - rack-test (>= 0.5.4) | ||
46 | - xpath (~> 2.0) | ||
47 | - childprocess (0.3.3) | ||
48 | - ffi (~> 1.0.6) | ||
49 | - cucumber (1.0.6) | ||
50 | - builder (>= 2.1.2) | ||
51 | - diff-lcs (>= 1.1.2) | ||
52 | - gherkin (~> 2.4.18) | ||
53 | - json (>= 1.4.6) | ||
54 | - term-ansicolor (>= 1.0.6) | ||
55 | - cucumber-rails (1.0.6) | ||
56 | - capybara (>= 1.1.1) | ||
57 | - cucumber (>= 1.0.6) | ||
58 | - nokogiri (>= 1.5.0) | ||
59 | - daemons (1.1.5) | ||
60 | - dalli (2.7.0) | ||
61 | - database_cleaner (1.2.0) | ||
62 | - diff-lcs (1.1.3) | ||
63 | - erubis (2.7.0) | ||
64 | - eventmachine (0.12.11) | ||
65 | - fast_gettext (0.6.8) | ||
66 | - ffi (1.0.11) | ||
67 | - gherkin (2.4.21) | ||
68 | - json (>= 1.4.6) | ||
69 | - hike (1.2.1) | ||
70 | - hpricot (0.8.6) | ||
71 | - i18n (0.6.0) | ||
72 | - journey (1.0.3) | ||
73 | - json (1.7.3) | ||
74 | - mail (2.4.4) | ||
75 | - i18n (>= 0.4.0) | ||
76 | - mime-types (~> 1.16) | ||
77 | - treetop (~> 1.4.8) | ||
78 | - mime-types (1.19) | ||
79 | - multi_json (1.3.6) | ||
80 | - nokogiri (1.5.5) | ||
81 | - pg (0.13.2) | ||
82 | - polyglot (0.3.3) | ||
83 | - prototype-rails (3.2.1) | ||
84 | - rails (~> 3.2) | ||
85 | - rack (1.4.1) | ||
86 | - rack-cache (1.2) | ||
87 | - rack (>= 0.4) | ||
88 | - rack-ssl (1.3.2) | ||
89 | - rack | ||
90 | - rack-test (0.6.1) | ||
91 | - rack (>= 1.0) | ||
92 | - rails (3.2.6) | ||
93 | - actionmailer (= 3.2.6) | ||
94 | - actionpack (= 3.2.6) | ||
95 | - activerecord (= 3.2.6) | ||
96 | - activeresource (= 3.2.6) | ||
97 | - activesupport (= 3.2.6) | ||
98 | - bundler (~> 1.0) | ||
99 | - railties (= 3.2.6) | ||
100 | - rails_autolink (1.1.5) | ||
101 | - rails (> 3.1) | ||
102 | - railties (3.2.6) | ||
103 | - actionpack (= 3.2.6) | ||
104 | - activesupport (= 3.2.6) | ||
105 | - rack-ssl (~> 1.3.2) | ||
106 | - rake (>= 0.8.7) | ||
107 | - rdoc (~> 3.4) | ||
108 | - thor (>= 0.14.6, < 2.0) | ||
109 | - rake (0.9.2.2) | ||
110 | - rdoc (3.9.4) | ||
111 | - rmagick (2.13.1) | ||
112 | - rspec (2.10.0) | ||
113 | - rspec-core (~> 2.10.0) | ||
114 | - rspec-expectations (~> 2.10.0) | ||
115 | - rspec-mocks (~> 2.10.0) | ||
116 | - rspec-core (2.10.1) | ||
117 | - rspec-expectations (2.10.0) | ||
118 | - diff-lcs (~> 1.1.3) | ||
119 | - rspec-mocks (2.10.1) | ||
120 | - rspec-rails (2.10.1) | ||
121 | - actionpack (>= 3.0) | ||
122 | - activesupport (>= 3.0) | ||
123 | - railties (>= 3.0) | ||
124 | - rspec (~> 2.10.0) | ||
125 | - ruby-feedparser (0.7) | ||
126 | - rubyzip (1.1.2) | ||
127 | - selenium-webdriver (2.39.0) | ||
128 | - childprocess (>= 0.2.5) | ||
129 | - multi_json (~> 1.0) | ||
130 | - rubyzip (~> 1.0) | ||
131 | - websocket (~> 1.0.4) | ||
132 | - sprockets (2.1.3) | ||
133 | - hike (~> 1.2) | ||
134 | - multi_json (~> 1.0) | ||
135 | - rack (~> 1.0) | ||
136 | - tilt (~> 1.1, != 1.3.0) | ||
137 | - term-ansicolor (1.0.7) | ||
138 | - thin (1.3.1) | ||
139 | - daemons (>= 1.0.9) | ||
140 | - eventmachine (>= 0.12.6) | ||
141 | - rack (>= 1.0.0) | ||
142 | - thor (0.15.3) | ||
143 | - tilt (1.3.3) | ||
144 | - treetop (1.4.10) | ||
145 | - polyglot | ||
146 | - polyglot (>= 0.3.1) | ||
147 | - tzinfo (0.3.33) | ||
148 | - websocket (1.0.7) | ||
149 | - will_paginate (3.0.3) | ||
150 | - xpath (2.0.0) | ||
151 | - nokogiri (~> 1.3) | ||
152 | - | ||
153 | -PLATFORMS | ||
154 | - ruby | ||
155 | - | ||
156 | -DEPENDENCIES | ||
157 | - RedCloth | ||
158 | - acts-as-taggable-on | ||
159 | - capybara | ||
160 | - cucumber | ||
161 | - cucumber-rails | ||
162 | - daemons | ||
163 | - dalli | ||
164 | - database_cleaner | ||
165 | - fast_gettext | ||
166 | - hpricot | ||
167 | - nokogiri | ||
168 | - pg | ||
169 | - prototype-rails | ||
170 | - prototype_legacy_helper (= 0.0.0)! | ||
171 | - rails | ||
172 | - rails_autolink | ||
173 | - rake | ||
174 | - rmagick | ||
175 | - rspec | ||
176 | - rspec-rails | ||
177 | - ruby-feedparser | ||
178 | - selenium-webdriver | ||
179 | - thin | ||
180 | - will_paginate |
INSTALL.chat.md
1 | -XMPP/Chat Client Setup | ||
2 | -====================== | 1 | +XMPP/Chat Setup |
2 | +=============== | ||
3 | 3 | ||
4 | -To configure XMPP/BOSH in Noosfero you need: | 4 | +The samples of config file to configure a XMPP/BOSH server with ejabberd, |
5 | +postgresql and apache2 can be found at util/chat directory. | ||
5 | 6 | ||
6 | -* REST Client - http://github.com/archiloque/rest-client | ||
7 | -* SystemTimer - http://ph7spot.com/musings/system-timer | ||
8 | -* Pidgin data files - http://www.pidgin.im/ | 7 | +This setup supposes that you are using Noosfero installed via Debian package |
8 | +in a production environment. | ||
9 | 9 | ||
10 | -If you use Debian 6.0 (squeeze): | ||
11 | - | ||
12 | - # apt-get install librestclient-ruby pidgin-data ruby1.8-dev | ||
13 | - # gem install SystemTimer | ||
14 | - | ||
15 | -The samples of config file to configure a XMPP/BOSH server with ejabberd, postgresql and apache2 can be found at util/chat directory. | ||
16 | - | ||
17 | -XMPP/Chat Server Setup | ||
18 | -====================== | 10 | +Steps |
11 | +===== | ||
19 | 12 | ||
20 | This is a step-by-step guide to get a XMPP service working, in a Debian system. | 13 | This is a step-by-step guide to get a XMPP service working, in a Debian system. |
21 | 14 | ||
22 | ## 1. Install the required packages | 15 | ## 1. Install the required packages |
23 | 16 | ||
24 | - # apt-get install ejabberd odbc-postgresql | 17 | + # apt-get install ejabberd odbc-postgresql librestclient-ruby pidgin-data ruby1.8-dev |
18 | + # gem install SystemTimer | ||
25 | 19 | ||
26 | ## 2. Ejabberd configuration | 20 | ## 2. Ejabberd configuration |
27 | 21 | ||
28 | -All the following changes must be done in config file: `/etc/ejabberd/ejabberd.cfg` | ||
29 | - | ||
30 | -### 2.1. Set the default admin user | ||
31 | - | ||
32 | - { acl, admin, { user, "john", "www.example.com" } }. | ||
33 | - { acl, admin, { user, "bart", "www.example.com" } }. | ||
34 | - | ||
35 | -### 2.2. Set the default host | ||
36 | - | ||
37 | - { hosts, [ "www.example.com" ] }. | ||
38 | - | ||
39 | -### 2.3. Http-Bind activation | ||
40 | - | ||
41 | - { 5280, ejabberd_http, [ | ||
42 | - http_bind, | ||
43 | - web_admin | ||
44 | - ] | ||
45 | - } | ||
46 | - | ||
47 | - (...) | ||
48 | - | ||
49 | - { modules, [ | ||
50 | - {mod_http_bind, []}, | ||
51 | - ... | ||
52 | - ] }. | ||
53 | - | ||
54 | -Ejabberd creates semi-anonymous rooms by default, but Noosfero's Jabber client needs non-anonymous room, then we need to change default params of creation rooms in ejabberd to create non-anonymous rooms. | ||
55 | - | ||
56 | -In non-anonymous rooms the jabber service sends the new occupant's full JID to all occupants in the room [[1]]. | 22 | + # cp /usr/share/noosfero/util/chat/ejabberd.cfg /etc/ejabberd/ |
57 | 23 | ||
58 | -Add option "`{default_room_options, [{anonymous, false}]}`" to `/etc/ejabberd/ejabberd.cfg` in mod_muc session. See below: | 24 | +Edit the /etc/ejabberd/ejabberd.cfg file and set your domain on the first 2 lines. |
59 | 25 | ||
60 | - { mod_muc, [ | ||
61 | - %%{host, "conference.@HOST@"}, | ||
62 | - {access, muc}, | ||
63 | - {access_create, muc}, | ||
64 | - {access_persistent, muc}, | ||
65 | - {access_admin, muc_admin}, | ||
66 | - {max_users, 500}, | ||
67 | - {default_room_options, [{anonymous, false}]} | ||
68 | - ]}, | ||
69 | - | ||
70 | -[1]: http://xmpp.org/extensions/xep-0045.html#enter-nonanon | ||
71 | - | ||
72 | - | ||
73 | -### 2.4. Authentication method | ||
74 | - | ||
75 | -To use Postgresql through ODBC, the following modifications must be done: | ||
76 | - | ||
77 | - * Disable the default method: | ||
78 | - `{auth_method, internal}.` | ||
79 | - | ||
80 | - * Enable autheticantion through ODBC: | ||
81 | - `{auth_method, odbc}.` | 26 | +## 3. Configuring Postgresql |
82 | 27 | ||
83 | - * Set database server name | ||
84 | - `{odbc_server, "DSN=PostgreSQLEjabberdNoosfero"}.` | 28 | +Give permission to noosfero user create new roles, login as |
29 | +postgres user and execute: | ||
85 | 30 | ||
31 | + $ psql | ||
32 | + postgres=# GRANT CREATE ON DATABASE noosfero TO noosfero; | ||
86 | 33 | ||
87 | -### 2.5. Increase the shaper traffic limit | 34 | +Change the postgresql authentication method to md5 instead of ident, |
35 | +add the following line to the file /etc/postgresql/8.4/main/pg_hba.conf: | ||
88 | 36 | ||
89 | - { shaper, normal, { maxrate, 10000000 } }. | 37 | + # Noosfero user |
38 | + local noosfero noosfero md5 | ||
90 | 39 | ||
40 | +(add this line before the following line) | ||
91 | 41 | ||
92 | -### 2.6. Disable unused modules | 42 | + # "local" is for Unix domain socket connections only |
43 | + local all all ident | ||
93 | 44 | ||
94 | -Unused modules can be disabled, for example: | 45 | +Restart postgresql server: |
95 | 46 | ||
96 | - * s2s | ||
97 | - * web_admin | ||
98 | - * mod_pubsub | ||
99 | - * mod_irc | ||
100 | - * mod_offline | ||
101 | - * mod_admin_extra | ||
102 | - * mod_register | 47 | + # service postgresql restart |
103 | 48 | ||
49 | +Login as noosfero user, and execute: | ||
104 | 50 | ||
105 | -### 2.7. Enable ODBC modules | 51 | + $ psql -U noosfero -W noosfero < /usr/share/noosfero/util/chat/postgresql/ejabberd.sql |
106 | 52 | ||
107 | - * mod_privacy -> mod_privacy_odbc | ||
108 | - * mod_private -> mod_private_odbc | ||
109 | - * mod_roster -> mod_roster_odbc | 53 | +(see database password in the /etc/noosfero/database.yml file) |
110 | 54 | ||
111 | -## 3. Configuring Postgresql | 55 | +This will create a new schema inside the noosfero database, called `ejabberd`. |
112 | 56 | ||
113 | -Login as noosfero user, and execute: | 57 | +Note that there should be at least one domain with `is_default = true` in |
58 | +`domains` table, otherwise people won't be able to see their friends online. | ||
114 | 59 | ||
115 | - $ psql noosfero < /path/to/noosfero/util/chat/postgresql/ejabberd.sql | 60 | +## 4. ODBC configuration |
116 | 61 | ||
117 | -Where `noosfero` may need to be replace by the name of the database used for Noosfero. | 62 | +Create the following files: |
118 | 63 | ||
119 | -This will create a new schema inside the noosfero database, called `ejabberd`. | 64 | + # cp /usr/share/noosfero/util/chat/odbc.ini /etc/ |
65 | + # cp /usr/share/noosfero/util/chat/odbcinst.ini /etc/ | ||
120 | 66 | ||
121 | -Note `noosfero` user should have permission to create Postgresql schemas. Also, there should be at least one domain with `is_default = true` in `domains` table, otherwise people won't be able to see their friends online. | 67 | +Edit the odbc.ini file and set the password for the database user, see |
68 | +the file /etc/noosfero/database.yml to get the password. | ||
122 | 69 | ||
123 | -## 4. ODBC configuration | 70 | +Adjust premissions: |
124 | 71 | ||
125 | -The following files must be created: | ||
126 | - | ||
127 | -`/etc/odbc.ini`: | ||
128 | - | ||
129 | - [PostgreSQLEjabberdNoosfero] | ||
130 | - Description = PostgreSQL Noosfero ejabberd database | ||
131 | - Driver = PostgreSQL Unicode | ||
132 | - Trace = No | ||
133 | - TraceFile = /tmp/psqlodbc.log | ||
134 | - Database = noosfero | ||
135 | - Servername = localhost | ||
136 | - UserName = <DBUSER> | ||
137 | - Password = <DBPASS> | ||
138 | - Port = | ||
139 | - ReadOnly = No | ||
140 | - RowVersioning = No | ||
141 | - ShowSystemTables = No | ||
142 | - ShowOidColumn = No | ||
143 | - FakeOidIndex = No | ||
144 | - ConnSettings = SET search_path TO ejabberd | ||
145 | - | ||
146 | -`/etc/odbcinst.ini`: | ||
147 | - | ||
148 | - [PostgreSQL Unicode] | ||
149 | - Description = PostgreSQL ODBC driver (Unicode version) | ||
150 | - Driver = /usr/lib/odbc/psqlodbcw.so | ||
151 | - Setup = /usr/lib/odbc/libodbcpsqlS.so | ||
152 | - Debug = 0 | ||
153 | - CommLog = 1 | ||
154 | - UsageCount = 3 | 72 | + # chmod 640 /etc/odbc.ini |
73 | + # chown ejabberd /etc/odbc.ini | ||
155 | 74 | ||
156 | ## 4.1 testing all: | 75 | ## 4.1 testing all: |
157 | 76 | ||
@@ -159,7 +78,6 @@ The following files must be created: | @@ -159,7 +78,6 @@ The following files must be created: | ||
159 | 78 | ||
160 | If the configuration was done right, the message "Connected!" will be displayed. | 79 | If the configuration was done right, the message "Connected!" will be displayed. |
161 | 80 | ||
162 | - | ||
163 | ## 5. Enabling kernel polling and SMP in `/etc/default/ejabberd` | 81 | ## 5. Enabling kernel polling and SMP in `/etc/default/ejabberd` |
164 | 82 | ||
165 | POLL=true | 83 | POLL=true |
@@ -205,32 +123,45 @@ Note: module proxy_http must be enabled: | @@ -205,32 +123,45 @@ Note: module proxy_http must be enabled: | ||
205 | 123 | ||
206 | # a2enmod proxy_http | 124 | # a2enmod proxy_http |
207 | 125 | ||
208 | -## 8. DNS configuration | 126 | +Restart services: |
209 | 127 | ||
210 | -For this point, we assume you are using BIND as your DNS server. You need to add the following entries to the DNS zone file corresponding to the domain of your noosfero site: | 128 | + # service ejabberd restart |
129 | + # service noosfero restart | ||
130 | + # service apache2 restart | ||
211 | 131 | ||
212 | - _xmpp-client._tcp SRV 5 100 5222 master | ||
213 | - conference CNAME master | ||
214 | - _xmpp-client._tcp.conference SRV 5 100 5222 master | 132 | +## 8. Test Apache Configuration |
215 | 133 | ||
216 | -If you are running a DNS server other than BIND, you will have to figure out how to create equivalente rules for your zone file. Patches to this documentation are welcome. | 134 | +Open in your browser the address: |
217 | 135 | ||
218 | -## 9. Testing this Setup | 136 | + http://<yout domain>/http-bind |
219 | 137 | ||
220 | -Adjust shell limits to proceed with some benchmarks and load tests: | 138 | +You should see a page with a message like that: |
221 | 139 | ||
222 | - # ulimit −s 256 | ||
223 | - # ulimit −n 8192 | ||
224 | - # echo 10 > /proc/sys/net/ipv4/tcp_syn_retries | 140 | + ejabberd mod_http_bind |
141 | + An implementation of XMPP over BOSH (XEP-0206) | ||
142 | + This web page is only informative. To use HTTP-Bind you need a Jabber/XMPP | ||
143 | + client that supports it. | ||
225 | 144 | ||
226 | -To measure the bandwidth between server and client: | 145 | +## 9. Test chat session |
227 | 146 | ||
228 | - * at server side: | ||
229 | - `# iperf −s` | 147 | +Open Noosfero console and execute: |
230 | 148 | ||
231 | - * at client side: | ||
232 | - `# iperf −c server_ip` | 149 | +>> environment = Environment.default |
150 | +>> user = Person['guest'] | ||
151 | +>> password = user.user.crypted_password | ||
152 | +>> login = user.jid | ||
153 | +>> RubyBOSH.initialize_session(login, password, "http://#{environment.default_hostname}/http-bind", :wait => 30, :hold => 1, :window => 5 | ||
233 | 154 | ||
234 | -For heavy load tests, clone and use this software: | 155 | +If you have luck, should see something like that: |
235 | 156 | ||
236 | - $ git clone http://git.holoscopio.com/git/metal/tester.git | 157 | +Ruby-BOSH - SEND |
158 | +<body window="5" rid="60265" xmlns="http://jabber.org/protocol/httpbind" xmlns:xmpp="urn:xmpp:xbosh" to="vagrant-debian-squeeze.vagrantup.com" wait="30" xmpp:version="1.0" hold="1"/> | ||
159 | +Ruby-BOSH - SEND | ||
160 | +<body rid="60266" xmlns="http://jabber.org/protocol/httpbind" sid="24cdfc43646a2af1059a7060b677c2e11b26f34f" xmlns:xmpp="urn:xmpp:xbosh" xmpp:version="1.0"><auth mechanism="PLAIN" xmlns="urn:ietf:params:xml:ns:xmpp-sasl">Z3Vlc3RAdmFncmFudC1kZWJpYW4tc3F1ZWV6ZS52YWdyYW50dXAuY29tAGd1ZXN0ADEzZTFhYWVlYjRhYjZlMTA0MmRkNWI1YWY0MzM4MjA1OGJiOWZmNzk=</auth></body> | ||
161 | +Ruby-BOSH - SEND | ||
162 | +<body xmpp:restart="true" rid="60267" xmlns="http://jabber.org/protocol/httpbind" sid="24cdfc43646a2af1059a7060b677c2e11b26f34f" xmlns:xmpp="urn:xmpp:xbosh" xmpp:version="1.0"/> | ||
163 | +Ruby-BOSH - SEND | ||
164 | +<body rid="60268" xmlns="http://jabber.org/protocol/httpbind" sid="24cdfc43646a2af1059a7060b677c2e11b26f34f" xmlns:xmpp="urn:xmpp:xbosh" xmpp:version="1.0"><iq type="set" xmlns="jabber:client" id="bind_29330"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"><resource>bosh_9631</resource></bind></iq></body> | ||
165 | +Ruby-BOSH - SEND | ||
166 | +<body rid="60269" xmlns="http://jabber.org/protocol/httpbind" sid="24cdfc43646a2af1059a7060b677c2e11b26f34f" xmlns:xmpp="urn:xmpp:xbosh" xmpp:version="1.0"><iq type="set" xmlns="jabber:client" id="sess_21557"><session xmlns="urn:ietf:params:xml:ns:xmpp-session"/></iq></body> | ||
167 | +=> ["guest@vagrant-debian-squeeze.vagrantup.com", "24cdfc43646a2af1059a7060b677c2e11b26f34f", 60270] |
@@ -0,0 +1,115 @@ | @@ -0,0 +1,115 @@ | ||
1 | +Setup Noosfero to use HTTPS | ||
2 | +=========================== | ||
3 | + | ||
4 | +This document assumes that you have a fully and clean Noosfero | ||
5 | +installation as explained at the `INSTALL.md` file. | ||
6 | + | ||
7 | +SSL certificate | ||
8 | ++++++++++++++++ | ||
9 | + | ||
10 | +You should get a valid SSL certificate, but if you want to test | ||
11 | +your setup before, you could generate a self-signed certificate | ||
12 | +as below: | ||
13 | + | ||
14 | + # mkdir /etc/noosfero/ssl | ||
15 | + # cd /etc/noosfero/ssl | ||
16 | + # openssl genrsa 1024 > noosfero.key | ||
17 | + # openssl req -new -x509 -nodes -sha1 -days $[10*365] -key noosfero.key > noosfero.cert | ||
18 | + # cat noosfero.key noosfero.cert > noosfero.pem | ||
19 | + | ||
20 | +There are two ways of using SSL with Noosfero: 1) If you are not using | ||
21 | +Varnish; and 2) If you are using Varnish. | ||
22 | + | ||
23 | +1) If you are are not using Varnish | ||
24 | ++++++++++++++++++++++++++++++++++++ | ||
25 | + | ||
26 | +Simply do a redirect in apache to force all connections with SSL: | ||
27 | + | ||
28 | + <VirtualHost *:8080> | ||
29 | + ServerName test.stoa.usp.br | ||
30 | + | ||
31 | + Redirect / https://example.com/ | ||
32 | + </VirtualHost> | ||
33 | + | ||
34 | +And set a vhost to receive then: | ||
35 | + | ||
36 | + <VirtualHost *:443> | ||
37 | + ServerName example.com | ||
38 | + | ||
39 | + SSLEngine On | ||
40 | + SSLCertificateFile /etc/ssl/certs/cert.pem | ||
41 | + SSLCertificateKeyFile /etc/ssl/private/cert.key | ||
42 | + | ||
43 | + Include /etc/noosfero/apache/virtualhost.conf | ||
44 | + </VirtualHost> | ||
45 | + | ||
46 | +Be aware that if you had configured varnish, the requests won't reach | ||
47 | +it with this configuration. | ||
48 | + | ||
49 | +2) If you are using Varnish | ||
50 | ++++++++++++++++++++++++++++ | ||
51 | + | ||
52 | +Varnish isn't able to communicate with the SSL protocol, so we will | ||
53 | +need some one who do this and Pound[1] can do the job. In order to | ||
54 | +install it in Debian based systems: | ||
55 | + | ||
56 | + $ sudo apt-get install pound | ||
57 | + | ||
58 | +Set Varnish to listen in other port than 80: | ||
59 | + | ||
60 | +/etc/defaults/varnish | ||
61 | +--------------------- | ||
62 | + | ||
63 | + DAEMON_OPTS="-a localhost:6081 \ | ||
64 | + -T localhost:6082 \ | ||
65 | + -f /etc/varnish/default.vcl \ | ||
66 | + -S /etc/varnish/secret \ | ||
67 | + -s file,/var/lib/varnish/$INSTANCE/varnish_storage.bin,1G" | ||
68 | + | ||
69 | +Configure Pound: | ||
70 | + | ||
71 | + # cp /usr/share/noosfero/etc/pound.cfg /etc/pound/ | ||
72 | + | ||
73 | +Edit /etc/pound.cfg and set the IP and domain of your server. | ||
74 | + | ||
75 | +Configure Pound to start at system initialization: | ||
76 | + | ||
77 | +/etc/default/pound | ||
78 | +------------------ | ||
79 | + | ||
80 | + startup=1 | ||
81 | + | ||
82 | +Set Apache to only listen to localhost: | ||
83 | + | ||
84 | +/etc/apache2/ports.conf | ||
85 | +----------------------- | ||
86 | + | ||
87 | + Listen 127.0.0.1:8080 | ||
88 | + | ||
89 | +Restart the services: | ||
90 | + | ||
91 | + $ sudo service apache2 restart | ||
92 | + $ sudo service varnish restart | ||
93 | + | ||
94 | +Start pound: | ||
95 | + | ||
96 | + $ sudo service pound start | ||
97 | + | ||
98 | +[1] http://www.apsis.ch/pound | ||
99 | + | ||
100 | +Noosfero XMPP chat | ||
101 | +++++++++++++++++++ | ||
102 | + | ||
103 | +If you want to use chat over HTTPS, then you should add the domain | ||
104 | +and IP of your server in the /etc/hosts file, example: | ||
105 | + | ||
106 | +/etc/hosts | ||
107 | +---------- | ||
108 | + | ||
109 | + 192.168.1.86 mydomain.example.com | ||
110 | + | ||
111 | +Also, it's recomended that you remove lines above from the file | ||
112 | +`/etc/apache2/sites-enabled/noosfero`: | ||
113 | + | ||
114 | + RewriteEngine On | ||
115 | + Include /usr/share/noosfero/util/chat/apache/xmpp.conf |
INSTALL.md
@@ -186,8 +186,8 @@ Apache instalation | @@ -186,8 +186,8 @@ Apache instalation | ||
186 | 186 | ||
187 | # apt-get install apache2 | 187 | # apt-get install apache2 |
188 | 188 | ||
189 | -Apache configuration | ||
190 | --------------------- | 189 | +Configuration - noosfero at / |
190 | +----------------------------- | ||
191 | 191 | ||
192 | First you have to enable the following some apache modules: | 192 | First you have to enable the following some apache modules: |
193 | 193 | ||
@@ -257,6 +257,62 @@ Now restart your apache server (as root): | @@ -257,6 +257,62 @@ Now restart your apache server (as root): | ||
257 | 257 | ||
258 | # invoke-rc.d apache2 restart | 258 | # invoke-rc.d apache2 restart |
259 | 259 | ||
260 | +Configuration - noosfero at a /subdirectory | ||
261 | +------------------------------------------- | ||
262 | + | ||
263 | +This section describes how to configure noosfero at a subdirectory, what is | ||
264 | +specially useful when you want Noosfero to share a domain name with other | ||
265 | +applications. For example you can host noosfero at yourdomain.com/social, a | ||
266 | +webmail application at yourdomain.com/webmail, and have a static HTML website | ||
267 | +at yourdomain.com/. | ||
268 | + | ||
269 | +**NOTE:** Some plugins might not work well with this setting. Before deploying | ||
270 | +this setting, make sure you test that everything you need works properly with | ||
271 | +it. | ||
272 | + | ||
273 | +The configuration is similar to the main configuration instructions, except for | ||
274 | +the following points. In the description below, replace '/subdirectory' with | ||
275 | +the actual subdirectory you want. | ||
276 | + | ||
277 | +1) add a `prefix: /subdirectory` line to your thin configuration file (thin.yml). | ||
278 | + | ||
279 | +1.1) remember to restart the noosfero application server whenever you make | ||
280 | +changes to that configuration file. | ||
281 | + | ||
282 | + # service noosfero restart | ||
283 | + | ||
284 | +2) add a line saying `export RAILS_RELATIVE_URL_ROOT=/subdirectory` to | ||
285 | +/etc/default/noosfero (you can create it with just this line if it does not | ||
286 | +exist already). | ||
287 | + | ||
288 | +3) You should add the following apache configuration to an existing virtual | ||
289 | +host (plus the `<Proxy balancer://noosfero>` section as displayed above): | ||
290 | + | ||
291 | +``` | ||
292 | +Alias /subdirectory /path/to/noosfero/public | ||
293 | +<Directory "/path/to/noosfero/public"> | ||
294 | + Options FollowSymLinks | ||
295 | + AllowOverride None | ||
296 | + Order Allow,Deny | ||
297 | + Allow from all | ||
298 | + | ||
299 | + Include /path/to/noosfero/etc/noosfero/apache/cache.conf | ||
300 | + | ||
301 | + RewriteEngine On | ||
302 | + RewriteBase /subdirectory | ||
303 | + # Rewrite index to check for static index.html | ||
304 | + RewriteRule ^$ index.html [QSA] | ||
305 | + # Rewrite to check for Rails cached page | ||
306 | + RewriteRule ^([^.]+)$ $1.html [QSA] | ||
307 | + RewriteCond %{REQUEST_FILENAME} !-f | ||
308 | + RewriteRule ^(.*)$ http://localhost:3000%{REQUEST_URI} [P,QSA,L] | ||
309 | +</Directory> | ||
310 | +``` | ||
311 | + | ||
312 | +3.1) remember to reload the apache server whenever any apache configuration | ||
313 | +file changes. | ||
314 | + | ||
315 | + # sudo service apache2 reload | ||
260 | 316 | ||
261 | Enabling exception notifications | 317 | Enabling exception notifications |
262 | ================================ | 318 | ================================ |
INSTALL.varnish.md
@@ -24,10 +24,6 @@ Install the RPAF apache module (or skip this step if not using apache): | @@ -24,10 +24,6 @@ Install the RPAF apache module (or skip this step if not using apache): | ||
24 | 24 | ||
25 | 3b) Edit `/etc/apache2/sites-enabled/*`, and change `<VirtualHost *:80>` to `<VirtualHost *:8080>` | 25 | 3b) Edit `/etc/apache2/sites-enabled/*`, and change `<VirtualHost *:80>` to `<VirtualHost *:8080>` |
26 | 26 | ||
27 | -3c) Restart apache | ||
28 | - | ||
29 | - # invoke-rc.d apache2 restart | ||
30 | - | ||
31 | 4) Varnish configuration | 27 | 4) Varnish configuration |
32 | 28 | ||
33 | 4a) Edit `/etc/default/varnish` | 29 | 4a) Edit `/etc/default/varnish` |
@@ -44,10 +40,6 @@ On manual installations, change `/etc/noosfero/*` to `{Rails.root}/etc/noosfero/ | @@ -44,10 +40,6 @@ On manual installations, change `/etc/noosfero/*` to `{Rails.root}/etc/noosfero/ | ||
44 | 40 | ||
45 | **NOTE**: it is very important that the `*.vcl` files are included in that order, i.e. *first* include `varnish-noosfero.vcl`, and *after* `noosfero-accept-language.cvl`. | 41 | **NOTE**: it is very important that the `*.vcl` files are included in that order, i.e. *first* include `varnish-noosfero.vcl`, and *after* `noosfero-accept-language.cvl`. |
46 | 42 | ||
47 | -4c) Restart Varnish | ||
48 | - | ||
49 | - # invoke-rc.d varnish restart | ||
50 | - | ||
51 | 5) Enable varnish logging: | 43 | 5) Enable varnish logging: |
52 | 44 | ||
53 | 5a) Edit `/etc/default/varnishncsa` and uncomment the line that contains: | 45 | 5a) Edit `/etc/default/varnishncsa` and uncomment the line that contains: |
@@ -56,8 +48,10 @@ On manual installations, change `/etc/noosfero/*` to `{Rails.root}/etc/noosfero/ | @@ -56,8 +48,10 @@ On manual installations, change `/etc/noosfero/*` to `{Rails.root}/etc/noosfero/ | ||
56 | 48 | ||
57 | The varnish log will be written to `/var/log/varnish/varnishncsa.log` in an apache-compatible format. You should change your statistics generation software (e.g. awstats) to use that instead of apache logs. | 49 | The varnish log will be written to `/var/log/varnish/varnishncsa.log` in an apache-compatible format. You should change your statistics generation software (e.g. awstats) to use that instead of apache logs. |
58 | 50 | ||
59 | -5b) Restart Varnish Logging service | 51 | +Thanks to Cosimo Streppone for varnish-accept-language. See http://github.com/cosimo/varnish-accept-language for more information. |
60 | 52 | ||
61 | - # invoke-rc.d varnishncsa restart | 53 | +6) Restart services |
62 | 54 | ||
63 | -Thanks to Cosimo Streppone for varnish-accept-language. See http://github.com/cosimo/varnish-accept-language for more information. | 55 | + # service apache2 restart |
56 | + # service varnish restart | ||
57 | + # service varnishncsa restart |
Rakefile
1 | #!/usr/bin/env rake | 1 | #!/usr/bin/env rake |
2 | + | ||
2 | # Add your own tasks in files placed in lib/tasks ending in .rake, | 3 | # Add your own tasks in files placed in lib/tasks ending in .rake, |
3 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. | 4 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. |
4 | 5 | ||
5 | require File.expand_path('../config/application', __FILE__) | 6 | require File.expand_path('../config/application', __FILE__) |
6 | 7 | ||
7 | Noosfero::Application.load_tasks | 8 | Noosfero::Application.load_tasks |
9 | + | ||
10 | +[ | ||
11 | + "baseplugins/*/{tasks,lib/tasks,rails/tasks}/**/*.rake", | ||
12 | + "config/plugins/*/{tasks,lib/tasks,rails/tasks}/**/*.rake", | ||
13 | + "config/plugins/*/vendor/plugins/*/{tasks,lib/tasks,rails/tasks}/**/*.rake", | ||
14 | +].map do |pattern| | ||
15 | + Dir.glob(pattern).sort | ||
16 | +end.flatten.each do |taskfile| | ||
17 | + load taskfile | ||
18 | +end |
Vagrantfile
@@ -3,7 +3,7 @@ | @@ -3,7 +3,7 @@ | ||
3 | 3 | ||
4 | VAGRANTFILE_API_VERSION = "2" | 4 | VAGRANTFILE_API_VERSION = "2" |
5 | Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| | 5 | Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| |
6 | - config.vm.box = "debian-wheezy" | 6 | + config.vm.box = ENV.fetch('VAGRANT_BOX', "debian-wheezy") |
7 | config.vm.network :forwarded_port, host: 3000, guest: 3000 | 7 | config.vm.network :forwarded_port, host: 3000, guest: 3000 |
8 | config.vm.provision :shell do |shell| | 8 | config.vm.provision :shell do |shell| |
9 | shell.inline = 'su vagrant -c /vagrant/script/vagrant' | 9 | shell.inline = 'su vagrant -c /vagrant/script/vagrant' |
app/controllers/admin/admin_panel_controller.rb
@@ -7,6 +7,7 @@ class AdminPanelController < AdminController | @@ -7,6 +7,7 @@ class AdminPanelController < AdminController | ||
7 | end | 7 | end |
8 | 8 | ||
9 | def site_info | 9 | def site_info |
10 | + @no_design_blocks = true | ||
10 | if request.post? | 11 | if request.post? |
11 | if params[:environment][:languages] | 12 | if params[:environment][:languages] |
12 | params[:environment][:languages] = params[:environment][:languages].map {|lang, value| lang if value=='true'}.compact | 13 | params[:environment][:languages] = params[:environment][:languages].map {|lang, value| lang if value=='true'}.compact |
app/controllers/admin/categories_controller.rb
@@ -45,9 +45,11 @@ class CategoriesController < AdminController | @@ -45,9 +45,11 @@ class CategoriesController < AdminController | ||
45 | if request.post? | 45 | if request.post? |
46 | @category.update_attributes!(params[:category]) | 46 | @category.update_attributes!(params[:category]) |
47 | @saved = true | 47 | @saved = true |
48 | + session[:notice] = _("Category %s saved." % @category.name) | ||
48 | redirect_to :action => 'index' | 49 | redirect_to :action => 'index' |
49 | end | 50 | end |
50 | rescue Exception => e | 51 | rescue Exception => e |
52 | + session[:notice] = _('Could not save category.') | ||
51 | render :action => 'edit' | 53 | render :action => 'edit' |
52 | end | 54 | end |
53 | end | 55 | end |
app/controllers/admin/environment_design_controller.rb
@@ -3,9 +3,7 @@ class EnvironmentDesignController < BoxOrganizerController | @@ -3,9 +3,7 @@ class EnvironmentDesignController < BoxOrganizerController | ||
3 | protect 'edit_environment_design', :environment | 3 | protect 'edit_environment_design', :environment |
4 | 4 | ||
5 | def available_blocks | 5 | def available_blocks |
6 | - # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from | ||
7 | - # the Noosfero core soon, see ActionItem3045 | ||
8 | - @available_blocks ||= [ ArticleBlock, LoginBlock, EnvironmentStatisticsBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, PeopleBlock, SellersSearchBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock, FeaturedProductsBlock, CategoriesBlock, RawHTMLBlock, TagsBlock ] | 6 | + @available_blocks ||= [ ArticleBlock, LoginBlock, RecentDocumentsBlock, EnterprisesBlock, CommunitiesBlock, SellersSearchBlock, LinkListBlock, FeedReaderBlock, SlideshowBlock, HighlightsBlock, FeaturedProductsBlock, CategoriesBlock, RawHTMLBlock, TagsBlock ] |
9 | @available_blocks += plugins.dispatch(:extra_blocks, :type => Environment) | 7 | @available_blocks += plugins.dispatch(:extra_blocks, :type => Environment) |
10 | end | 8 | end |
11 | 9 |
app/controllers/admin/features_controller.rb
@@ -51,4 +51,10 @@ class FeaturesController < AdminController | @@ -51,4 +51,10 @@ class FeaturesController < AdminController | ||
51 | redirect_to :action => 'manage_fields' | 51 | redirect_to :action => 'manage_fields' |
52 | end | 52 | end |
53 | 53 | ||
54 | + def search_members | ||
55 | + arg = params[:q].downcase | ||
56 | + result = environment.people.find(:all, :conditions => ['LOWER(name) LIKE ? OR identifier LIKE ?', "%#{arg}%", "%#{arg}%"]) | ||
57 | + render :text => prepare_to_token_input(result).to_json | ||
58 | + end | ||
59 | + | ||
54 | end | 60 | end |
app/controllers/application_controller.rb
@@ -7,6 +7,12 @@ class ApplicationController < ActionController::Base | @@ -7,6 +7,12 @@ class ApplicationController < ActionController::Base | ||
7 | before_filter :detect_stuff_by_domain | 7 | before_filter :detect_stuff_by_domain |
8 | before_filter :init_noosfero_plugins | 8 | before_filter :init_noosfero_plugins |
9 | before_filter :allow_cross_domain_access | 9 | before_filter :allow_cross_domain_access |
10 | + before_filter :login_required, :if => :private_environment? | ||
11 | + before_filter :verify_members_whitelist, :if => [:private_environment?, :user] | ||
12 | + | ||
13 | + def verify_members_whitelist | ||
14 | + render_access_denied unless user.is_admin? || environment.in_whitelist?(user) | ||
15 | + end | ||
10 | 16 | ||
11 | after_filter :set_csrf_cookie | 17 | after_filter :set_csrf_cookie |
12 | 18 | ||
@@ -34,7 +40,7 @@ class ApplicationController < ActionController::Base | @@ -34,7 +40,7 @@ class ApplicationController < ActionController::Base | ||
34 | 40 | ||
35 | theme_layout = theme_option(:layout) | 41 | theme_layout = theme_option(:layout) |
36 | if theme_layout | 42 | if theme_layout |
37 | - theme_view_file('layouts/'+theme_layout) || theme_layout | 43 | + (theme_view_file('layouts/'+theme_layout) || theme_layout).to_s |
38 | else | 44 | else |
39 | 'application' | 45 | 'application' |
40 | end | 46 | end |
@@ -187,4 +193,8 @@ class ApplicationController < ActionController::Base | @@ -187,4 +193,8 @@ class ApplicationController < ActionController::Base | ||
187 | {:results => scope.paginate(paginate_options)} | 193 | {:results => scope.paginate(paginate_options)} |
188 | end | 194 | end |
189 | 195 | ||
196 | + def private_environment? | ||
197 | + @environment.enabled?(:restrict_to_members) | ||
198 | + end | ||
199 | + | ||
190 | end | 200 | end |
app/controllers/my_profile/cms_controller.rb
@@ -4,6 +4,12 @@ class CmsController < MyProfileController | @@ -4,6 +4,12 @@ class CmsController < MyProfileController | ||
4 | 4 | ||
5 | include ArticleHelper | 5 | include ArticleHelper |
6 | 6 | ||
7 | + def search_tags | ||
8 | + arg = params[:term].downcase | ||
9 | + result = ActsAsTaggableOn::Tag.find(:all, :conditions => ['LOWER(name) LIKE ?', "%#{arg}%"]) | ||
10 | + render :text => prepare_to_token_input_by_label(result).to_json, :content_type => 'application/json' | ||
11 | + end | ||
12 | + | ||
7 | def self.protect_if(*args) | 13 | def self.protect_if(*args) |
8 | before_filter(*args) do |c| | 14 | before_filter(*args) do |c| |
9 | user, profile = c.send(:user), c.send(:profile) | 15 | user, profile = c.send(:user), c.send(:profile) |
@@ -143,7 +149,9 @@ class CmsController < MyProfileController | @@ -143,7 +149,9 @@ class CmsController < MyProfileController | ||
143 | end | 149 | end |
144 | 150 | ||
145 | @article.profile = profile | 151 | @article.profile = profile |
152 | + @article.author = user | ||
146 | @article.last_changed_by = user | 153 | @article.last_changed_by = user |
154 | + @article.created_by = user | ||
147 | 155 | ||
148 | translations if @article.translatable? | 156 | translations if @article.translatable? |
149 | 157 | ||
@@ -187,7 +195,18 @@ class CmsController < MyProfileController | @@ -187,7 +195,18 @@ class CmsController < MyProfileController | ||
187 | end | 195 | end |
188 | if request.post? && params[:uploaded_files] | 196 | if request.post? && params[:uploaded_files] |
189 | params[:uploaded_files].each do |file| | 197 | params[:uploaded_files].each do |file| |
190 | - @uploaded_files << UploadedFile.create({:uploaded_data => file, :profile => profile, :parent => @parent, :last_changed_by => user}, :without_protection => true) unless file == '' | 198 | + unless file == '' |
199 | + @uploaded_files << UploadedFile.create( | ||
200 | + { | ||
201 | + :uploaded_data => file, | ||
202 | + :profile => profile, | ||
203 | + :parent => @parent, | ||
204 | + :last_changed_by => user, | ||
205 | + :author => user, | ||
206 | + }, | ||
207 | + :without_protection => true | ||
208 | + ) | ||
209 | + end | ||
191 | end | 210 | end |
192 | @errors = @uploaded_files.select { |f| f.errors.any? } | 211 | @errors = @uploaded_files.select { |f| f.errors.any? } |
193 | if @errors.any? | 212 | if @errors.any? |
@@ -208,7 +227,7 @@ class CmsController < MyProfileController | @@ -208,7 +227,7 @@ class CmsController < MyProfileController | ||
208 | @article = profile.articles.find(params[:id]) | 227 | @article = profile.articles.find(params[:id]) |
209 | if request.post? | 228 | if request.post? |
210 | @article.destroy | 229 | @article.destroy |
211 | - session[:notice] = _("\"#{@article.name}\" was removed.") | 230 | + session[:notice] = _("\"%s\" was removed." % @article.name) |
212 | referer = Rails.application.routes.recognize_path URI.parse(request.referer).path rescue nil | 231 | referer = Rails.application.routes.recognize_path URI.parse(request.referer).path rescue nil |
213 | if referer and referer[:controller] == 'cms' and referer[:action] != 'edit' | 232 | if referer and referer[:controller] == 'cms' and referer[:action] != 'edit' |
214 | redirect_to referer | 233 | redirect_to referer |
@@ -231,7 +250,7 @@ class CmsController < MyProfileController | @@ -231,7 +250,7 @@ class CmsController < MyProfileController | ||
231 | @current_category = Category.find(params[:category_id]) | 250 | @current_category = Category.find(params[:category_id]) |
232 | @categories = @current_category.children | 251 | @categories = @current_category.children |
233 | end | 252 | end |
234 | - render :template => 'shared/update_categories', :locals => { :category => @current_category } | 253 | + render :template => 'shared/update_categories', :locals => { :category => @current_category, :object_name => 'article' } |
235 | end | 254 | end |
236 | 255 | ||
237 | def publish | 256 | def publish |
@@ -247,12 +266,15 @@ class CmsController < MyProfileController | @@ -247,12 +266,15 @@ class CmsController < MyProfileController | ||
247 | end.compact unless params[:marked_groups].nil? | 266 | end.compact unless params[:marked_groups].nil? |
248 | if request.post? | 267 | if request.post? |
249 | @failed = {} | 268 | @failed = {} |
269 | + if @marked_groups.empty? | ||
270 | + return session[:notice] = _("Select some group to publish your article") | ||
271 | + end | ||
250 | @marked_groups.each do |item| | 272 | @marked_groups.each do |item| |
251 | task = ApproveArticle.create!(:article => @article, :name => item[:name], :target => item[:group], :requestor => profile) | 273 | task = ApproveArticle.create!(:article => @article, :name => item[:name], :target => item[:group], :requestor => profile) |
252 | begin | 274 | begin |
253 | task.finish unless item[:group].moderated_articles? | 275 | task.finish unless item[:group].moderated_articles? |
254 | rescue Exception => ex | 276 | rescue Exception => ex |
255 | - @failed[ex.message] ? @failed[ex.message] << item[:group].name : @failed[ex.message] = [item[:group].name] | 277 | + @failed[ex.message] ? @failed[ex.message] << item[:group].name : @failed[ex.message] = [item[:group].name] |
256 | end | 278 | end |
257 | end | 279 | end |
258 | if @failed.blank? | 280 | if @failed.blank? |
@@ -11,7 +11,7 @@ class FriendsController < MyProfileController | @@ -11,7 +11,7 @@ class FriendsController < MyProfileController | ||
11 | def remove | 11 | def remove |
12 | @friend = profile.friends.find(params[:id]) | 12 | @friend = profile.friends.find(params[:id]) |
13 | if request.post? && params[:confirmation] | 13 | if request.post? && params[:confirmation] |
14 | - profile.remove_friend(@friend) | 14 | + Friendship.remove_friendship(profile, @friend) |
15 | redirect_to :action => 'index' | 15 | redirect_to :action => 'index' |
16 | end | 16 | end |
17 | end | 17 | end |
@@ -20,7 +20,7 @@ class FriendsController < MyProfileController | @@ -20,7 +20,7 @@ class FriendsController < MyProfileController | ||
20 | 20 | ||
21 | class << self | 21 | class << self |
22 | def per_page | 22 | def per_page |
23 | - 10 | 23 | + 12 |
24 | end | 24 | end |
25 | end | 25 | end |
26 | def per_page | 26 | def per_page |
app/controllers/my_profile/memberships_controller.rb
@@ -7,9 +7,9 @@ class MembershipsController < MyProfileController | @@ -7,9 +7,9 @@ class MembershipsController < MyProfileController | ||
7 | ra = profile.role_assignments.find_by_role_id(role.id) | 7 | ra = profile.role_assignments.find_by_role_id(role.id) |
8 | ra.present? && ra.resource_type == 'Profile' | 8 | ra.present? && ra.resource_type == 'Profile' |
9 | end | 9 | end |
10 | - @filter = params[:filter_type].blank? ? nil : params[:filter_type] | 10 | + @filter = params[:filter_type].to_i |
11 | begin | 11 | begin |
12 | - @memberships = @filter.nil? ? profile.memberships : profile.memberships_by_role(environment.roles.find(@filter)) | 12 | + @memberships = @filter.zero? ? profile.memberships : profile.memberships_by_role(environment.roles.find(@filter)) |
13 | rescue ActiveRecord::RecordNotFound | 13 | rescue ActiveRecord::RecordNotFound |
14 | @memberships = [] | 14 | @memberships = [] |
15 | end | 15 | end |
@@ -21,6 +21,9 @@ class MembershipsController < MyProfileController | @@ -21,6 +21,9 @@ class MembershipsController < MyProfileController | ||
21 | @back_to = params[:back_to] || url_for(:action => 'index') | 21 | @back_to = params[:back_to] || url_for(:action => 'index') |
22 | if request.post? && @community.valid? | 22 | if request.post? && @community.valid? |
23 | @community = Community.create_after_moderation(user, params[:community].merge({:environment => environment})) | 23 | @community = Community.create_after_moderation(user, params[:community].merge({:environment => environment})) |
24 | + if @community.new_record? | ||
25 | + session[:notice] = _('Your new community creation request will be evaluated by an administrator. You will be notified.') | ||
26 | + end | ||
24 | redirect_to @back_to | 27 | redirect_to @back_to |
25 | return | 28 | return |
26 | end | 29 | end |
app/controllers/my_profile/profile_design_controller.rb
@@ -9,14 +9,8 @@ class ProfileDesignController < BoxOrganizerController | @@ -9,14 +9,8 @@ class ProfileDesignController < BoxOrganizerController | ||
9 | 9 | ||
10 | blocks += plugins.dispatch(:extra_blocks) | 10 | blocks += plugins.dispatch(:extra_blocks) |
11 | 11 | ||
12 | - # blocks exclusive for organizations | ||
13 | - if profile.has_members? | ||
14 | - blocks << MembersBlock | ||
15 | - end | ||
16 | - | ||
17 | # blocks exclusive to people | 12 | # blocks exclusive to people |
18 | if profile.person? | 13 | if profile.person? |
19 | - blocks << FriendsBlock | ||
20 | blocks << FavoriteEnterprisesBlock | 14 | blocks << FavoriteEnterprisesBlock |
21 | blocks << CommunitiesBlock | 15 | blocks << CommunitiesBlock |
22 | blocks << EnterprisesBlock | 16 | blocks << EnterprisesBlock |
app/controllers/my_profile/profile_editor_controller.rb
@@ -54,7 +54,7 @@ class ProfileEditorController < MyProfileController | @@ -54,7 +54,7 @@ class ProfileEditorController < MyProfileController | ||
54 | @current_category = Category.find(params[:category_id]) | 54 | @current_category = Category.find(params[:category_id]) |
55 | @categories = @current_category.children | 55 | @categories = @current_category.children |
56 | end | 56 | end |
57 | - render :template => 'shared/update_categories', :locals => { :category => @current_category } | 57 | + render :template => 'shared/update_categories', :locals => { :category => @current_category, :object_name => 'profile_data' } |
58 | end | 58 | end |
59 | 59 | ||
60 | def header_footer | 60 | def header_footer |
app/controllers/my_profile/tasks_controller.rb
@@ -4,6 +4,7 @@ class TasksController < MyProfileController | @@ -4,6 +4,7 @@ class TasksController < MyProfileController | ||
4 | 4 | ||
5 | def index | 5 | def index |
6 | @filter = params[:filter_type].blank? ? nil : params[:filter_type] | 6 | @filter = params[:filter_type].blank? ? nil : params[:filter_type] |
7 | + @task_types = Task.pending_types_for(profile) | ||
7 | @tasks = Task.to(profile).without_spam.pending.of(@filter).order_by('created_at', 'asc').paginate(:per_page => Task.per_page, :page => params[:page]) | 8 | @tasks = Task.to(profile).without_spam.pending.of(@filter).order_by('created_at', 'asc').paginate(:per_page => Task.per_page, :page => params[:page]) |
8 | @failed = params ? params[:failed] : {} | 9 | @failed = params ? params[:failed] : {} |
9 | end | 10 | end |
app/controllers/public/account_controller.rb
@@ -2,7 +2,7 @@ class AccountController < ApplicationController | @@ -2,7 +2,7 @@ class AccountController < ApplicationController | ||
2 | 2 | ||
3 | no_design_blocks | 3 | no_design_blocks |
4 | 4 | ||
5 | - before_filter :login_required, :only => [:activation_question, :accept_terms, :activate_enterprise] | 5 | + before_filter :login_required, :only => [:activation_question, :accept_terms, :activate_enterprise, :change_password] |
6 | before_filter :redirect_if_logged_in, :only => [:login, :signup] | 6 | before_filter :redirect_if_logged_in, :only => [:login, :signup] |
7 | before_filter :protect_from_bots, :only => :signup | 7 | before_filter :protect_from_bots, :only => :signup |
8 | 8 | ||
@@ -15,9 +15,23 @@ class AccountController < ApplicationController | @@ -15,9 +15,23 @@ class AccountController < ApplicationController | ||
15 | 15 | ||
16 | def activate | 16 | def activate |
17 | @user = User.find_by_activation_code(params[:activation_code]) if params[:activation_code] | 17 | @user = User.find_by_activation_code(params[:activation_code]) if params[:activation_code] |
18 | - if @user and @user.activate | ||
19 | - @message = _("Your account has been activated, now you can log in!") | ||
20 | - render :action => 'login', :userlogin => @user.login | 18 | + if @user |
19 | + unless @user.environment.enabled?('admin_must_approve_new_users') | ||
20 | + if @user.activate | ||
21 | + @message = _("Your account has been activated, now you can log in!") | ||
22 | + check_redirection | ||
23 | + session[:join] = params[:join] unless params[:join].blank? | ||
24 | + render :action => 'login', :userlogin => @user.login | ||
25 | + end | ||
26 | + else | ||
27 | + if @user.create_moderate_task | ||
28 | + session[:notice] = _('Thanks for registering. The administrators were notified.') | ||
29 | + @register_pending = true | ||
30 | + @user.activation_code = nil | ||
31 | + @user.save! | ||
32 | + redirect_to :controller => :home | ||
33 | + end | ||
34 | + end | ||
21 | else | 35 | else |
22 | session[:notice] = _("It looks like you're trying to activate an account. Perhaps have already activated this account?") | 36 | session[:notice] = _("It looks like you're trying to activate an account. Perhaps have already activated this account?") |
23 | redirect_to :controller => :home | 37 | redirect_to :controller => :home |
@@ -35,6 +49,7 @@ class AccountController < ApplicationController | @@ -35,6 +49,7 @@ class AccountController < ApplicationController | ||
35 | self.current_user ||= User.authenticate(params[:user][:login], params[:user][:password], environment) if params[:user] | 49 | self.current_user ||= User.authenticate(params[:user][:login], params[:user][:password], environment) if params[:user] |
36 | 50 | ||
37 | if logged_in? | 51 | if logged_in? |
52 | + check_join_in_community(self.current_user) | ||
38 | if params[:remember_me] == "1" | 53 | if params[:remember_me] == "1" |
39 | self.current_user.remember_me | 54 | self.current_user.remember_me |
40 | cookies[:auth_token] = { :value => self.current_user.remember_token , :expires => self.current_user.remember_token_expires_at } | 55 | cookies[:auth_token] = { :value => self.current_user.remember_token , :expires => self.current_user.remember_token_expires_at } |
@@ -82,6 +97,7 @@ class AccountController < ApplicationController | @@ -82,6 +97,7 @@ class AccountController < ApplicationController | ||
82 | @user.return_to = session[:return_to] | 97 | @user.return_to = session[:return_to] |
83 | @person = Person.new(params[:profile_data]) | 98 | @person = Person.new(params[:profile_data]) |
84 | @person.environment = @user.environment | 99 | @person.environment = @user.environment |
100 | + | ||
85 | if request.post? | 101 | if request.post? |
86 | if may_be_a_bot | 102 | if may_be_a_bot |
87 | set_signup_start_time_for_now | 103 | set_signup_start_time_for_now |
@@ -91,6 +107,7 @@ class AccountController < ApplicationController | @@ -91,6 +107,7 @@ class AccountController < ApplicationController | ||
91 | if session[:may_be_a_bot] | 107 | if session[:may_be_a_bot] |
92 | return false unless verify_recaptcha :model=>@user, :message=>_('Captcha (the human test)') | 108 | return false unless verify_recaptcha :model=>@user, :message=>_('Captcha (the human test)') |
93 | end | 109 | end |
110 | + @user.community_to_join = session[:join] | ||
94 | @user.signup! | 111 | @user.signup! |
95 | owner_role = Role.find_by_name('owner') | 112 | owner_role = Role.find_by_name('owner') |
96 | @user.person.affiliate(@user.person, [owner_role]) if owner_role | 113 | @user.person.affiliate(@user.person, [owner_role]) if owner_role |
@@ -99,10 +116,20 @@ class AccountController < ApplicationController | @@ -99,10 +116,20 @@ class AccountController < ApplicationController | ||
99 | invitation.update_attributes!({:friend => @user.person}) | 116 | invitation.update_attributes!({:friend => @user.person}) |
100 | invitation.finish | 117 | invitation.finish |
101 | end | 118 | end |
119 | + | ||
120 | + unless params[:file].nil? | ||
121 | + image = Image::new :uploaded_data=> params[:file][:image] | ||
122 | + | ||
123 | + @user.person.image = image | ||
124 | + @user.person.save | ||
125 | + end | ||
126 | + | ||
102 | if @user.activated? | 127 | if @user.activated? |
103 | self.current_user = @user | 128 | self.current_user = @user |
129 | + check_join_in_community(@user) | ||
104 | go_to_signup_initial_page | 130 | go_to_signup_initial_page |
105 | else | 131 | else |
132 | + session[:notice] = _('Thanks for registering!') | ||
106 | @register_pending = true | 133 | @register_pending = true |
107 | end | 134 | end |
108 | end | 135 | end |
@@ -388,12 +415,6 @@ class AccountController < ApplicationController | @@ -388,12 +415,6 @@ class AccountController < ApplicationController | ||
388 | end | 415 | end |
389 | 416 | ||
390 | def go_to_initial_page | 417 | def go_to_initial_page |
391 | - if params[:redirection] | ||
392 | - session[:return_to] = @user.return_to | ||
393 | - @user.return_to = nil | ||
394 | - @user.save | ||
395 | - end | ||
396 | - | ||
397 | if params[:return_to] | 418 | if params[:return_to] |
398 | redirect_to params[:return_to] | 419 | redirect_to params[:return_to] |
399 | elsif environment.enabled?('allow_change_of_redirection_after_login') | 420 | elsif environment.enabled?('allow_change_of_redirection_after_login') |
@@ -444,4 +465,19 @@ class AccountController < ApplicationController | @@ -444,4 +465,19 @@ class AccountController < ApplicationController | ||
444 | redirect_back_or_default(default) | 465 | redirect_back_or_default(default) |
445 | end | 466 | end |
446 | end | 467 | end |
468 | + | ||
469 | + def check_redirection | ||
470 | + unless params[:redirection].blank? | ||
471 | + session[:return_to] = @user.return_to | ||
472 | + @user.update_attributes(:return_to => nil) | ||
473 | + end | ||
474 | + end | ||
475 | + | ||
476 | + def check_join_in_community(user) | ||
477 | + profile_to_join = session[:join] | ||
478 | + unless profile_to_join.blank? | ||
479 | + environment.profiles.find_by_identifier(profile_to_join).add_member(user.person) | ||
480 | + session.delete(:join) | ||
481 | + end | ||
482 | + end | ||
447 | end | 483 | end |
app/controllers/public/catalog_controller.rb
@@ -11,7 +11,7 @@ class CatalogController < PublicController | @@ -11,7 +11,7 @@ class CatalogController < PublicController | ||
11 | protected | 11 | protected |
12 | 12 | ||
13 | def check_enterprise_and_environment | 13 | def check_enterprise_and_environment |
14 | - unless profile.kind_of?(Enterprise) && @profile.environment.enabled?('products_for_enterprises') | 14 | + unless profile.enterprise? && @profile.environment.enabled?('products_for_enterprises') |
15 | redirect_to :controller => 'profile', :profile => profile.identifier, :action => 'index' | 15 | redirect_to :controller => 'profile', :profile => profile.identifier, :action => 'index' |
16 | end | 16 | end |
17 | end | 17 | end |
app/controllers/public/chat_controller.rb
@@ -19,9 +19,13 @@ class ChatController < PublicController | @@ -19,9 +19,13 @@ class ChatController < PublicController | ||
19 | def avatar | 19 | def avatar |
20 | profile = environment.profiles.find_by_identifier(params[:id]) | 20 | profile = environment.profiles.find_by_identifier(params[:id]) |
21 | filename, mimetype = profile_icon(profile, :minor, true) | 21 | filename, mimetype = profile_icon(profile, :minor, true) |
22 | - data = File.read(File.join(Rails.root, 'public', filename)) | ||
23 | - render :text => data, :layout => false, :content_type => mimetype | ||
24 | - expires_in 24.hours | 22 | + if filename =~ /^https?:/ |
23 | + redirect_to filename | ||
24 | + else | ||
25 | + data = File.read(File.join(Rails.root, 'public', filename)) | ||
26 | + render :text => data, :layout => false, :content_type => mimetype | ||
27 | + expires_in 24.hours | ||
28 | + end | ||
25 | end | 29 | end |
26 | 30 | ||
27 | def index | 31 | def index |
app/controllers/public/content_viewer_controller.rb
@@ -8,49 +8,32 @@ class ContentViewerController < ApplicationController | @@ -8,49 +8,32 @@ class ContentViewerController < ApplicationController | ||
8 | helper TagsHelper | 8 | helper TagsHelper |
9 | 9 | ||
10 | def view_page | 10 | def view_page |
11 | - path = params[:page] | ||
12 | - path = path.join('/') if path.kind_of?(Array) | ||
13 | - path = "#{path}.#{params[:format]}" if params[:format] | 11 | + path = get_path(params[:page], params[:format]) |
12 | + | ||
14 | @version = params[:version].to_i | 13 | @version = params[:version].to_i |
15 | 14 | ||
16 | if path.blank? | 15 | if path.blank? |
17 | - @page = profile.home_page | ||
18 | - if @page.nil? | ||
19 | - redirect_to :controller => 'profile', :action => 'index', :profile => profile.identifier | ||
20 | - return | ||
21 | - end | 16 | + @page = profile.home_page |
17 | + return if redirected_to_profile_index | ||
22 | else | 18 | else |
23 | @page = profile.articles.find_by_path(path) | 19 | @page = profile.articles.find_by_path(path) |
24 | - unless @page | ||
25 | - page_from_old_path = profile.articles.find_by_old_path(path) | ||
26 | - if page_from_old_path | ||
27 | - redirect_to profile.url.merge(:page => page_from_old_path.explode_path) | ||
28 | - return | ||
29 | - end | ||
30 | - end | 20 | + return if redirected_page_from_old_path(path) |
31 | end | 21 | end |
32 | 22 | ||
33 | return unless allow_access_to_page(path) | 23 | return unless allow_access_to_page(path) |
34 | 24 | ||
35 | if @version > 0 | 25 | if @version > 0 |
36 | return render_access_denied unless @page.display_versions? | 26 | return render_access_denied unless @page.display_versions? |
37 | - @versioned_article = @page.versions.find_by_version(@version) | ||
38 | - if @versioned_article && @page.versions.latest.version != @versioned_article.version | ||
39 | - render :template => 'content_viewer/versioned_article.html.erb' | ||
40 | - return | ||
41 | - end | 27 | + return if rendered_versioned_article |
42 | end | 28 | end |
43 | 29 | ||
44 | redirect_to_translation and return if @page.profile.redirect_l10n | 30 | redirect_to_translation and return if @page.profile.redirect_l10n |
45 | 31 | ||
46 | - if request.post? | ||
47 | - if @page.forum? && @page.has_terms_of_use && params[:terms_accepted] == "true" | ||
48 | - @page.add_agreed_user(user) | ||
49 | - end | ||
50 | - elsif !@page.parent.nil? && @page.parent.forum? | ||
51 | - unless @page.parent.agrees_with_terms?(user) | ||
52 | - redirect_to @page.parent.url | ||
53 | - end | 32 | + if request.post? && @page.forum? |
33 | + process_forum_terms_of_use(user, params[:terms_accepted]) | ||
34 | + elsif is_a_forum_topic?(@page) && !@page.parent.agrees_with_terms?(user) | ||
35 | + redirect_to @page.parent.url | ||
36 | + return | ||
54 | end | 37 | end |
55 | 38 | ||
56 | # At this point the page will be showed | 39 | # At this point the page will be showed |
@@ -58,64 +41,22 @@ class ContentViewerController < ApplicationController | @@ -58,64 +41,22 @@ class ContentViewerController < ApplicationController | ||
58 | 41 | ||
59 | @page = FilePresenter.for @page | 42 | @page = FilePresenter.for @page |
60 | 43 | ||
61 | - if @page.download? params[:view] | ||
62 | - headers['Content-Type'] = @page.mime_type | ||
63 | - headers.merge! @page.download_headers | ||
64 | - data = @page.data | ||
65 | - | ||
66 | - # TODO test the condition | ||
67 | - if data.nil? | ||
68 | - raise "No data for file" | ||
69 | - end | ||
70 | - | ||
71 | - render :text => data, :layout => false | ||
72 | - return | ||
73 | - end | 44 | + return if rendered_file_download(params[:view]) |
74 | 45 | ||
75 | @form_div = params[:form] | 46 | @form_div = params[:form] |
76 | 47 | ||
77 | #FIXME see a better way to do this. It's not need to pass this variable anymore | 48 | #FIXME see a better way to do this. It's not need to pass this variable anymore |
78 | @comment = Comment.new | 49 | @comment = Comment.new |
79 | 50 | ||
80 | - if @page.has_posts? | ||
81 | - posts = if params[:year] and params[:month] | ||
82 | - filter_date = DateTime.parse("#{params[:year]}-#{params[:month]}-01") | ||
83 | - @page.posts.by_range(filter_date..filter_date.at_end_of_month) | ||
84 | - else | ||
85 | - @page.posts | ||
86 | - end | ||
87 | - | ||
88 | - #FIXME Need to run this before the pagination because this version of | ||
89 | - # will_paginate returns a will_paginate collection instead of a | ||
90 | - # relation. | ||
91 | - blog_with_translation = @page.blog? && @page.display_posts_in_current_language? | ||
92 | - posts = posts.native_translations if blog_with_translation | ||
93 | - | ||
94 | - @posts = posts.paginate({ :page => params[:npage], :per_page => @page.posts_per_page }.merge(Article.display_filter(user, profile))).to_a | ||
95 | - | ||
96 | - if blog_with_translation | ||
97 | - @posts.replace @posts.map{ |p| p.get_translation_to(FastGettext.locale) }.compact | ||
98 | - end | ||
99 | - end | 51 | + process_page_posts(params) |
100 | 52 | ||
101 | if @page.folder? && @page.gallery? | 53 | if @page.folder? && @page.gallery? |
102 | - @images = @page.images.select{ |a| a.display_to? user } | ||
103 | - @images = @images.paginate(:per_page => per_page, :page => params[:npage]) unless params[:slideshow] | 54 | + @images = get_images(@page, params[:npage], params[:slideshow]) |
104 | end | 55 | end |
105 | 56 | ||
106 | - @unfollow_form = params[:unfollow] && params[:unfollow] == 'true' | ||
107 | - if params[:unfollow] && params[:unfollow] == 'commit' && request.post? | ||
108 | - @page.followers -= [params[:email]] | ||
109 | - if @page.save | ||
110 | - session[:notice] = _("Notification of new comments to '%s' was successfully canceled") % params[:email] | ||
111 | - end | ||
112 | - end | 57 | + process_page_followers(params) |
113 | 58 | ||
114 | - @comments = @page.comments.without_spam | ||
115 | - @comments = @plugins.filter(:unavailable_comments, @comments) | ||
116 | - @comments_count = @comments.count | ||
117 | - @comments = @comments.without_reply.paginate(:per_page => per_page, :page => params[:comment_page] ) | ||
118 | - @comment_order = params[:comment_order].nil? ? 'oldest' : params[:comment_order] | 59 | + process_comments(params) |
119 | 60 | ||
120 | if request.xhr? and params[:comment_order] | 61 | if request.xhr? and params[:comment_order] |
121 | if @comment_order == 'newest' | 62 | if @comment_order == 'newest' |
@@ -133,7 +74,7 @@ class ContentViewerController < ApplicationController | @@ -133,7 +74,7 @@ class ContentViewerController < ApplicationController | ||
133 | end | 74 | end |
134 | 75 | ||
135 | def versions_diff | 76 | def versions_diff |
136 | - path = params[:page].join('/') | 77 | + path = params[:page] |
137 | @page = profile.articles.find_by_path(path) | 78 | @page = profile.articles.find_by_path(path) |
138 | @v1, @v2 = @page.versions.find_by_version(params[:v1]), @page.versions.find_by_version(params[:v2]) | 79 | @v1, @v2 = @page.versions.find_by_version(params[:v1]), @page.versions.find_by_version(params[:v2]) |
139 | end | 80 | end |
@@ -185,7 +126,7 @@ class ContentViewerController < ApplicationController | @@ -185,7 +126,7 @@ class ContentViewerController < ApplicationController | ||
185 | elsif !@page.display_to?(user) | 126 | elsif !@page.display_to?(user) |
186 | if !profile.public? | 127 | if !profile.public? |
187 | private_profile_partial_parameters | 128 | private_profile_partial_parameters |
188 | - render :template => 'profile/_private_profile', :status => 403 | 129 | + render :template => 'profile/_private_profile', :status => 403, :formats => [:html] |
189 | allowed = false | 130 | allowed = false |
190 | else #if !profile.visible? | 131 | else #if !profile.visible? |
191 | render_access_denied | 132 | render_access_denied |
@@ -203,4 +144,127 @@ class ContentViewerController < ApplicationController | @@ -203,4 +144,127 @@ class ContentViewerController < ApplicationController | ||
203 | user_agent.match(/crawler/) || | 144 | user_agent.match(/crawler/) || |
204 | user_agent.match(/\(.*https?:\/\/.*\)/) | 145 | user_agent.match(/\(.*https?:\/\/.*\)/) |
205 | end | 146 | end |
147 | + | ||
148 | + def get_path(page, format = nil) | ||
149 | + path = page | ||
150 | + path = path.join('/') if path.kind_of?(Array) | ||
151 | + path = "#{path}.#{format}" if format | ||
152 | + | ||
153 | + return path | ||
154 | + end | ||
155 | + | ||
156 | + def redirected_to_profile_index | ||
157 | + if @page.nil? | ||
158 | + redirect_to :controller => 'profile', :action => 'index', :profile => profile.identifier | ||
159 | + return true | ||
160 | + end | ||
161 | + | ||
162 | + return false | ||
163 | + end | ||
164 | + | ||
165 | + def redirected_page_from_old_path(path) | ||
166 | + unless @page | ||
167 | + page_from_old_path = profile.articles.find_by_old_path(path) | ||
168 | + if page_from_old_path | ||
169 | + redirect_to profile.url.merge(:page => page_from_old_path.explode_path) | ||
170 | + return true | ||
171 | + end | ||
172 | + end | ||
173 | + | ||
174 | + return false | ||
175 | + end | ||
176 | + | ||
177 | + def process_forum_terms_of_use(user, terms_accepted = nil) | ||
178 | + if @page.forum? && @page.has_terms_of_use && terms_accepted == "true" | ||
179 | + @page.add_agreed_user(user) | ||
180 | + end | ||
181 | + end | ||
182 | + | ||
183 | + def is_a_forum_topic? (page) | ||
184 | + return (!@page.parent.nil? && @page.parent.forum?) | ||
185 | + end | ||
186 | + | ||
187 | + def rendered_versioned_article | ||
188 | + @versioned_article = @page.versions.find_by_version(@version) | ||
189 | + if @versioned_article && @page.versions.latest.version != @versioned_article.version | ||
190 | + render :template => 'content_viewer/versioned_article.html.erb' | ||
191 | + return true | ||
192 | + end | ||
193 | + | ||
194 | + return false | ||
195 | + end | ||
196 | + | ||
197 | + def rendered_file_download(view = nil) | ||
198 | + if @page.download? view | ||
199 | + headers['Content-Type'] = @page.mime_type | ||
200 | + headers.merge! @page.download_headers | ||
201 | + data = @page.data | ||
202 | + | ||
203 | + # TODO test the condition | ||
204 | + if data.nil? | ||
205 | + raise "No data for file" | ||
206 | + end | ||
207 | + | ||
208 | + render :text => data, :layout => false | ||
209 | + return true | ||
210 | + end | ||
211 | + | ||
212 | + return false | ||
213 | + end | ||
214 | + | ||
215 | + def process_page_posts(params) | ||
216 | + if @page.has_posts? | ||
217 | + posts = get_posts(params[:year], params[:month]) | ||
218 | + | ||
219 | + #FIXME Need to run this before the pagination because this version of | ||
220 | + # will_paginate returns a will_paginate collection instead of a | ||
221 | + # relation. | ||
222 | + posts = posts.native_translations if blog_with_translation?(@page) | ||
223 | + | ||
224 | + @posts = posts.paginate({ :page => params[:npage], :per_page => @page.posts_per_page }.merge(Article.display_filter(user, profile))).to_a | ||
225 | + | ||
226 | + if blog_with_translation?(@page) | ||
227 | + @posts.replace @posts.map{ |p| p.get_translation_to(FastGettext.locale) }.compact | ||
228 | + end | ||
229 | + end | ||
230 | + end | ||
231 | + | ||
232 | + def get_posts(year = nil, month = nil) | ||
233 | + if year && month | ||
234 | + filter_date = DateTime.parse("#{year}-#{month}-01") | ||
235 | + return @page.posts.by_range(filter_date..filter_date.at_end_of_month) | ||
236 | + else | ||
237 | + return @page.posts | ||
238 | + end | ||
239 | + end | ||
240 | + | ||
241 | + def blog_with_translation?(page) | ||
242 | + return (page.blog? && page.display_posts_in_current_language?) | ||
243 | + end | ||
244 | + | ||
245 | + def get_images(page, npage, slideshow) | ||
246 | + images = page.images.select{ |a| a.display_to? user } | ||
247 | + images = images.paginate(:per_page => per_page, :page => npage) unless slideshow | ||
248 | + | ||
249 | + return images | ||
250 | + end | ||
251 | + | ||
252 | + def process_page_followers(params) | ||
253 | + @unfollow_form = params[:unfollow] == 'true' | ||
254 | + if params[:unfollow] == 'commit' && request.post? | ||
255 | + @page.followers -= [params[:email]] | ||
256 | + if @page.save | ||
257 | + session[:notice] = _("Notification of new comments to '%s' was successfully canceled") % params[:email] | ||
258 | + end | ||
259 | + end | ||
260 | + end | ||
261 | + | ||
262 | + def process_comments(params) | ||
263 | + @comments = @page.comments.without_spam | ||
264 | + @comments = @plugins.filter(:unavailable_comments, @comments) | ||
265 | + @comments_count = @comments.count | ||
266 | + @comments = @comments.without_reply.paginate(:per_page => per_page, :page => params[:comment_page] ) | ||
267 | + @comment_order = params[:comment_order].nil? ? 'oldest' : params[:comment_order] | ||
268 | + end | ||
269 | + | ||
206 | end | 270 | end |
app/controllers/public/profile_controller.rb
@@ -3,7 +3,7 @@ class ProfileController < PublicController | @@ -3,7 +3,7 @@ class ProfileController < PublicController | ||
3 | needs_profile | 3 | needs_profile |
4 | before_filter :check_access_to_profile, :except => [:join, :join_not_logged, :index, :add] | 4 | before_filter :check_access_to_profile, :except => [:join, :join_not_logged, :index, :add] |
5 | before_filter :store_location, :only => [:join, :join_not_logged, :report_abuse, :send_mail] | 5 | before_filter :store_location, :only => [:join, :join_not_logged, :report_abuse, :send_mail] |
6 | - before_filter :login_required, :only => [:add, :join, :join_not_logged, :leave, :unblock, :leave_scrap, :remove_scrap, :remove_activity, :view_more_activities, :view_more_network_activities, :report_abuse, :register_report, :leave_comment_on_activity, :send_mail] | 6 | + before_filter :login_required, :only => [:add, :join, :leave, :unblock, :leave_scrap, :remove_scrap, :remove_activity, :view_more_activities, :view_more_network_activities, :report_abuse, :register_report, :leave_comment_on_activity, :send_mail] |
7 | 7 | ||
8 | helper TagsHelper | 8 | helper TagsHelper |
9 | 9 | ||
@@ -18,6 +18,7 @@ class ProfileController < PublicController | @@ -18,6 +18,7 @@ class ProfileController < PublicController | ||
18 | @tags = profile.article_tags | 18 | @tags = profile.article_tags |
19 | unless profile.display_info_to?(user) | 19 | unless profile.display_info_to?(user) |
20 | profile.visible? ? private_profile : invisible_profile | 20 | profile.visible? ? private_profile : invisible_profile |
21 | + render :action => 'index', :status => 403 | ||
21 | end | 22 | end |
22 | end | 23 | end |
23 | 24 | ||
@@ -51,7 +52,7 @@ class ProfileController < PublicController | @@ -51,7 +52,7 @@ class ProfileController < PublicController | ||
51 | 52 | ||
52 | def communities | 53 | def communities |
53 | if is_cache_expired?(profile.communities_cache_key(params)) | 54 | if is_cache_expired?(profile.communities_cache_key(params)) |
54 | - @communities = profile.communities.includes(relations_to_include).paginate(:per_page => per_page, :page => params[:npage]) | 55 | + @communities = profile.communities.includes(relations_to_include).paginate(:per_page => per_page, :page => params[:npage], :total_entries => profile.communities.count) |
55 | end | 56 | end |
56 | end | 57 | end |
57 | 58 | ||
@@ -97,21 +98,12 @@ class ProfileController < PublicController | @@ -97,21 +98,12 @@ class ProfileController < PublicController | ||
97 | end | 98 | end |
98 | 99 | ||
99 | def join_not_logged | 100 | def join_not_logged |
100 | - if request.post? | ||
101 | - profile.add_member(user) | ||
102 | - session[:notice] = _('%s administrator still needs to accept you as member.') % profile.name if profile.closed? | ||
103 | - redirect_to_previous_location | 101 | + session[:join] = profile.identifier |
102 | + | ||
103 | + if user | ||
104 | + redirect_to :controller => 'profile', :action => 'join' | ||
104 | else | 105 | else |
105 | - if user.memberships.include?(profile) | ||
106 | - session[:notice] = _('You are already a member of %s.') % profile.name | ||
107 | - redirect_to profile.url | ||
108 | - return | ||
109 | - end | ||
110 | - if request.xhr? | ||
111 | - render :layout => false | ||
112 | - else | ||
113 | - redirect_to profile.url | ||
114 | - end | 106 | + redirect_to :controller => '/account', :action => 'login' |
115 | end | 107 | end |
116 | end | 108 | end |
117 | 109 | ||
@@ -211,7 +203,8 @@ class ProfileController < PublicController | @@ -211,7 +203,8 @@ class ProfileController < PublicController | ||
211 | end | 203 | end |
212 | 204 | ||
213 | def more_comments | 205 | def more_comments |
214 | - activity = ActionTracker::Record.find(:first, :conditions => {:id => params[:activity], :user_id => @profile}) | 206 | + profile_filter = @profile.person? ? {:user_id => @profile} : {:target_id => @profile} |
207 | + activity = ActionTracker::Record.find(:first, :conditions => {:id => params[:activity]}.merge(profile_filter)) | ||
215 | comments_count = activity.comments.count | 208 | comments_count = activity.comments.count |
216 | comment_page = (params[:comment_page] || 1).to_i | 209 | comment_page = (params[:comment_page] || 1).to_i |
217 | comments_per_page = 5 | 210 | comments_per_page = 5 |
@@ -323,7 +316,7 @@ class ProfileController < PublicController | @@ -323,7 +316,7 @@ class ProfileController < PublicController | ||
323 | abuse_report = AbuseReport.new(params[:abuse_report]) | 316 | abuse_report = AbuseReport.new(params[:abuse_report]) |
324 | if !params[:content_type].blank? | 317 | if !params[:content_type].blank? |
325 | article = params[:content_type].constantize.find(params[:content_id]) | 318 | article = params[:content_type].constantize.find(params[:content_id]) |
326 | - abuse_report.content = instance_eval(&article.reported_version) | 319 | + abuse_report.content = article_reported_version(article) |
327 | end | 320 | end |
328 | 321 | ||
329 | user.register_report(abuse_report, profile) | 322 | user.register_report(abuse_report, profile) |
app/helpers/account_helper.rb
@@ -15,12 +15,17 @@ module AccountHelper | @@ -15,12 +15,17 @@ module AccountHelper | ||
15 | 15 | ||
16 | def suggestion_based_on_username(requested_username='') | 16 | def suggestion_based_on_username(requested_username='') |
17 | return "" if requested_username.empty? | 17 | return "" if requested_username.empty? |
18 | + | ||
19 | + requested_username = requested_username.downcase.tr("^#{Profile::IDENTIFIER_FORMAT}", '') | ||
18 | usernames = [] | 20 | usernames = [] |
21 | + tries = 0 | ||
19 | 3.times do | 22 | 3.times do |
20 | begin | 23 | begin |
21 | valid_name = requested_username + rand(1000).to_s | 24 | valid_name = requested_username + rand(1000).to_s |
22 | - end while (usernames.include?(valid_name) || !Person.is_available?(valid_name, environment)) | ||
23 | - usernames << valid_name | 25 | + tries += 1 |
26 | + invalid = usernames.include?(valid_name) || !Person.is_available?(valid_name, environment) | ||
27 | + end while tries <= 10 && invalid | ||
28 | + usernames << valid_name unless invalid | ||
24 | end | 29 | end |
25 | usernames | 30 | usernames |
26 | end | 31 | end |
app/helpers/application_helper.rb
@@ -304,7 +304,7 @@ module ApplicationHelper | @@ -304,7 +304,7 @@ module ApplicationHelper | ||
304 | def partial_for_class(klass, prefix=nil, suffix=nil) | 304 | def partial_for_class(klass, prefix=nil, suffix=nil) |
305 | raise ArgumentError, 'No partial for object. Is there a partial for any class in the inheritance hierarchy?' if klass.nil? | 305 | raise ArgumentError, 'No partial for object. Is there a partial for any class in the inheritance hierarchy?' if klass.nil? |
306 | name = klass.name.underscore | 306 | name = klass.name.underscore |
307 | - controller.view_paths.reverse_each do |view_path| | 307 | + controller.view_paths.each do |view_path| |
308 | partial = partial_for_class_in_view_path(klass, view_path, prefix, suffix) | 308 | partial = partial_for_class_in_view_path(klass, view_path, prefix, suffix) |
309 | return partial if partial | 309 | return partial if partial |
310 | end | 310 | end |
@@ -312,13 +312,13 @@ module ApplicationHelper | @@ -312,13 +312,13 @@ module ApplicationHelper | ||
312 | raise ArgumentError, 'No partial for object. Is there a partial for any class in the inheritance hierarchy?' | 312 | raise ArgumentError, 'No partial for object. Is there a partial for any class in the inheritance hierarchy?' |
313 | end | 313 | end |
314 | 314 | ||
315 | - def view_for_profile_actions(klass) | ||
316 | - raise ArgumentError, 'No profile actions view for this class.' if klass.nil? | ||
317 | - | ||
318 | - name = klass.name.underscore | ||
319 | - return "blocks/profile_info_actions/" + name + '.html.erb' if File.exists?(Rails.root.join('app', 'views', 'blocks', 'profile_info_actions', name + '.html.erb')) | ||
320 | - | ||
321 | - view_for_profile_actions(klass.superclass) | 315 | + def render_profile_actions klass |
316 | + name = klass.to_s.underscore | ||
317 | + begin | ||
318 | + render "blocks/profile_info_actions/#{name}" | ||
319 | + rescue ActionView::MissingTemplate | ||
320 | + render_profile_actions klass.superclass | ||
321 | + end | ||
322 | end | 322 | end |
323 | 323 | ||
324 | def user | 324 | def user |
@@ -482,7 +482,12 @@ module ApplicationHelper | @@ -482,7 +482,12 @@ module ApplicationHelper | ||
482 | '/images/icons-app/enterprise-'+ size.to_s() +'.png' | 482 | '/images/icons-app/enterprise-'+ size.to_s() +'.png' |
483 | end | 483 | end |
484 | else | 484 | else |
485 | - '/images/icons-app/person-'+ size.to_s() +'.png' | 485 | + pixels = Image.attachment_options[:thumbnails][size].split('x').first |
486 | + gravatar_profile_image_url( | ||
487 | + profile.email, | ||
488 | + :size => pixels, | ||
489 | + :d => gravatar_default | ||
490 | + ) | ||
486 | end | 491 | end |
487 | filename = default_or_themed_icon(icon) | 492 | filename = default_or_themed_icon(icon) |
488 | end | 493 | end |
@@ -602,7 +607,7 @@ module ApplicationHelper | @@ -602,7 +607,7 @@ module ApplicationHelper | ||
602 | end | 607 | end |
603 | 608 | ||
604 | def gravatar_default | 609 | def gravatar_default |
605 | - (respond_to?(:theme_option) && theme_option.present? && theme_option['gravatar']) || NOOSFERO_CONF['gravatar'] | 610 | + (respond_to?(:theme_option) && theme_option.present? && theme_option['gravatar']) || NOOSFERO_CONF['gravatar'] || 'mm' |
606 | end | 611 | end |
607 | 612 | ||
608 | attr_reader :environment | 613 | attr_reader :environment |
@@ -671,7 +676,7 @@ module ApplicationHelper | @@ -671,7 +676,7 @@ module ApplicationHelper | ||
671 | 676 | ||
672 | def theme_javascript_ng | 677 | def theme_javascript_ng |
673 | script = File.join(theme_path, 'theme.js') | 678 | script = File.join(theme_path, 'theme.js') |
674 | - if File.exists?(Rails.root.join('public', script)) | 679 | + if File.exists?(File.join(Rails.root, 'public', script)) |
675 | javascript_include_tag script | 680 | javascript_include_tag script |
676 | else | 681 | else |
677 | nil | 682 | nil |
@@ -1002,17 +1007,26 @@ module ApplicationHelper | @@ -1002,17 +1007,26 @@ module ApplicationHelper | ||
1002 | def display_category_menu(block, categories, root = true) | 1007 | def display_category_menu(block, categories, root = true) |
1003 | categories = categories.sort{|x,y| x.name <=> y.name} | 1008 | categories = categories.sort{|x,y| x.name <=> y.name} |
1004 | return "" if categories.blank? | 1009 | return "" if categories.blank? |
1005 | - content_tag(:ul, | 1010 | + content_tag(:ul) do |
1006 | categories.map do |category| | 1011 | categories.map do |category| |
1007 | category_path = category.kind_of?(ProductCategory) ? {:controller => 'search', :action => 'assets', :asset => 'products', :product_category => category.id} : { :controller => 'search', :action => 'category_index', :category_path => category.explode_path } | 1012 | category_path = category.kind_of?(ProductCategory) ? {:controller => 'search', :action => 'assets', :asset => 'products', :product_category => category.id} : { :controller => 'search', :action => 'category_index', :category_path => category.explode_path } |
1008 | - category.display_in_menu? ? | ||
1009 | - content_tag(:li, | ||
1010 | - ( !category.is_leaf_displayable_in_menu? ? content_tag(:a, collapsed_item_icon, :href => "#", :id => "block_#{block.id}_category_#{category.id}", :class => 'category-link-expand ' + (root ? 'category-root' : 'category-no-root'), :onclick => "expandCategory(#{block.id}, #{category.id}); return false", :style => 'display: none') : leaf_item_icon) + | ||
1011 | - link_to(content_tag(:span, category.name, :class => 'category-name'), category_path, :class => ("category-leaf" if category.is_leaf_displayable_in_menu?)) + | ||
1012 | - content_tag(:div, display_category_menu(block, category.children, false), :id => "block_#{block.id}_category_content_#{category.id}", :class => 'child-category') | ||
1013 | - ) : '' | ||
1014 | - end | ||
1015 | - ) + | 1013 | + if category.display_in_menu? |
1014 | + content_tag(:li) do | ||
1015 | + if !category.is_leaf_displayable_in_menu? | ||
1016 | + content_tag(:a, collapsed_item_icon, :href => "#", :id => "block_#{block.id}_category_#{category.id}", :class => "category-link-expand " + (root ? "category-root" : "category-no-root"), :onclick => "expandCategory(#{block.id}, #{category.id}); return false", :style => "display: none") | ||
1017 | + else | ||
1018 | + leaf_item_icon | ||
1019 | + end + | ||
1020 | + link_to(content_tag(:span, category.name, :class => "category-name"), category_path, :class => ("category-leaf" if category.is_leaf_displayable_in_menu?)) + | ||
1021 | + content_tag(:div, :id => "block_#{block.id}_category_content_#{category.id}", :class => 'child-category') do | ||
1022 | + display_category_menu(block, category.children, false) | ||
1023 | + end | ||
1024 | + end | ||
1025 | + else | ||
1026 | + "" | ||
1027 | + end | ||
1028 | + end.join.html_safe | ||
1029 | + end + | ||
1016 | content_tag(:p) + | 1030 | content_tag(:p) + |
1017 | (root ? javascript_tag(" | 1031 | (root ? javascript_tag(" |
1018 | jQuery('.child-category').hide(); | 1032 | jQuery('.child-category').hide(); |
@@ -1034,7 +1048,7 @@ module ApplicationHelper | @@ -1034,7 +1048,7 @@ module ApplicationHelper | ||
1034 | end | 1048 | end |
1035 | 1049 | ||
1036 | link_to(content_tag(:span, _('Contents'), :class => 'icon-menu-articles'), {:controller => "search", :action => 'contents', :category_path => nil}, :id => 'submenu-contents') + | 1050 | link_to(content_tag(:span, _('Contents'), :class => 'icon-menu-articles'), {:controller => "search", :action => 'contents', :category_path => nil}, :id => 'submenu-contents') + |
1037 | - link_to(content_tag(:span, _('Contents menu')), '#', :onclick => "toggleSubmenu(this,'',#{j links.to_json}); return false", :class => 'menu-submenu-trigger up', :id => 'submenu-contents-trigger') | 1051 | + link_to(content_tag(:span, _('Contents menu')), '#', :onclick => "toggleSubmenu(this,'',#{CGI::escapeHTML(links.to_json)}); return false", :class => 'menu-submenu-trigger up', :id => 'submenu-contents-trigger') |
1038 | end | 1052 | end |
1039 | alias :browse_contents_menu :search_contents_menu | 1053 | alias :browse_contents_menu :search_contents_menu |
1040 | 1054 | ||
@@ -1050,7 +1064,7 @@ module ApplicationHelper | @@ -1050,7 +1064,7 @@ module ApplicationHelper | ||
1050 | end | 1064 | end |
1051 | 1065 | ||
1052 | link_to(content_tag(:span, _('People'), :class => 'icon-menu-people'), {:controller => "search", :action => 'people', :category_path => ''}, :id => 'submenu-people') + | 1066 | link_to(content_tag(:span, _('People'), :class => 'icon-menu-people'), {:controller => "search", :action => 'people', :category_path => ''}, :id => 'submenu-people') + |
1053 | - link_to(content_tag(:span, _('People menu')), '#', :onclick => "toggleSubmenu(this,'',#{j links.to_json}); return false", :class => 'menu-submenu-trigger up', :id => 'submenu-people-trigger') | 1067 | + link_to(content_tag(:span, _('People menu')), '#', :onclick => "toggleSubmenu(this,'',#{CGI::escapeHTML(links.to_json)}); return false", :class => 'menu-submenu-trigger up', :id => 'submenu-people-trigger') |
1054 | end | 1068 | end |
1055 | alias :browse_people_menu :search_people_menu | 1069 | alias :browse_people_menu :search_people_menu |
1056 | 1070 | ||
@@ -1066,7 +1080,7 @@ module ApplicationHelper | @@ -1066,7 +1080,7 @@ module ApplicationHelper | ||
1066 | end | 1080 | end |
1067 | 1081 | ||
1068 | link_to(content_tag(:span, _('Communities'), :class => 'icon-menu-community'), {:controller => "search", :action => 'communities'}, :id => 'submenu-communities') + | 1082 | link_to(content_tag(:span, _('Communities'), :class => 'icon-menu-community'), {:controller => "search", :action => 'communities'}, :id => 'submenu-communities') + |
1069 | - link_to(content_tag(:span, _('Communities menu')), '#', :onclick => "toggleSubmenu(this,'',#{j links.to_json}); return false", :class => 'menu-submenu-trigger up', :id => 'submenu-communities-trigger') | 1083 | + link_to(content_tag(:span, _('Communities menu')), '#', :onclick => "toggleSubmenu(this,'',#{CGI::escapeHTML(links.to_json)}); return false", :class => 'menu-submenu-trigger up', :id => 'submenu-communities-trigger') |
1070 | end | 1084 | end |
1071 | alias :browse_communities_menu :search_communities_menu | 1085 | alias :browse_communities_menu :search_communities_menu |
1072 | 1086 | ||
@@ -1086,47 +1100,51 @@ module ApplicationHelper | @@ -1086,47 +1100,51 @@ module ApplicationHelper | ||
1086 | result | 1100 | result |
1087 | end | 1101 | end |
1088 | 1102 | ||
1089 | - def manage_link(list, kind) | 1103 | + def manage_link(list, kind, title) |
1090 | if list.present? | 1104 | if list.present? |
1091 | link_to_all = nil | 1105 | link_to_all = nil |
1092 | if list.count > 5 | 1106 | if list.count > 5 |
1093 | list = list.first(5) | 1107 | list = list.first(5) |
1094 | - link_to_all = link_to(content_tag('strong', _('See all')), :controller => 'memberships', :profile => current_user.login) | 1108 | + link_to_all = link_to(content_tag('strong', _('See all')), :controller => 'memberships', :profile => user.identifier) |
1095 | end | 1109 | end |
1096 | link = list.map do |element| | 1110 | link = list.map do |element| |
1097 | - link_to(content_tag('strong', [_('<span>Manage</span> %s') % element.short_name(25)]), @environment.top_url + "/myprofile/#{element.identifier}", :class => "icon-menu-"+element.class.identification.underscore, :title => [_('Manage %s') % element.short_name]) | 1111 | + link_to(content_tag('strong', _('<span>Manage</span> %s') % element.short_name(25)), element.admin_url, :class => "icon-menu-"+element.class.identification.underscore, :title => _('Manage %s') % element.short_name) |
1098 | end | 1112 | end |
1099 | if link_to_all | 1113 | if link_to_all |
1100 | link << link_to_all | 1114 | link << link_to_all |
1101 | end | 1115 | end |
1102 | - render :partial => "shared/manage_link", :locals => {:link => link, :kind => kind.to_s} | 1116 | + render :partial => "shared/manage_link", :locals => {:link => link, :kind => kind.to_s, :title => title} |
1103 | end | 1117 | end |
1104 | end | 1118 | end |
1105 | 1119 | ||
1106 | def manage_enterprises | 1120 | def manage_enterprises |
1107 | - return unless user && user.environment.enabled?(:display_my_enterprises_on_user_menu) | ||
1108 | - manage_link(user.enterprises, :enterprises) | 1121 | + return '' unless user && user.environment.enabled?(:display_my_enterprises_on_user_menu) |
1122 | + manage_link(user.enterprises, :enterprises, _('My enterprises')).to_s | ||
1109 | end | 1123 | end |
1110 | 1124 | ||
1111 | def manage_communities | 1125 | def manage_communities |
1112 | - return unless user && user.environment.enabled?(:display_my_communities_on_user_menu) | 1126 | + return '' unless user && user.environment.enabled?(:display_my_communities_on_user_menu) |
1113 | administered_communities = user.communities.more_popular.select {|c| c.admins.include? user} | 1127 | administered_communities = user.communities.more_popular.select {|c| c.admins.include? user} |
1114 | - manage_link(administered_communities, :communities) | 1128 | + manage_link(administered_communities, :communities, _('My communities')).to_s |
1129 | + end | ||
1130 | + | ||
1131 | + def admin_link | ||
1132 | + user.is_admin?(environment) ? link_to('<i class="icon-menu-admin"></i><strong>' + _('Administration') + '</strong>', environment.admin_url, :title => _("Configure the environment"), :class => 'admin-link') : '' | ||
1115 | end | 1133 | end |
1116 | 1134 | ||
1117 | def usermenu_logged_in | 1135 | def usermenu_logged_in |
1118 | pending_tasks_count = '' | 1136 | pending_tasks_count = '' |
1119 | count = user ? Task.to(user).pending.count : -1 | 1137 | count = user ? Task.to(user).pending.count : -1 |
1120 | if count > 0 | 1138 | if count > 0 |
1121 | - pending_tasks_count = link_to(count.to_s, @environment.top_url + '/myprofile/{login}/tasks', :id => 'pending-tasks-count', :title => _("Manage your pending tasks")) | 1139 | + pending_tasks_count = link_to(count.to_s, user.tasks_url, :id => 'pending-tasks-count', :title => _("Manage your pending tasks")) |
1122 | end | 1140 | end |
1123 | 1141 | ||
1124 | - (_("<span class='welcome'>Welcome,</span> %s") % link_to('<i style="background-image:url({avatar})"></i><strong>{login}</strong>', @environment.top_url + '/{login}', :id => "homepage-link", :title => _('Go to your homepage'))) + | 1142 | + (_("<span class='welcome'>Welcome,</span> %s") % link_to("<i style='background-image:url(#{user.profile_custom_icon(gravatar_default)})'></i><strong>#{user.identifier}</strong>", user.public_profile_url, :id => "homepage-link", :title => _('Go to your homepage'))) + |
1125 | render_environment_features(:usermenu) + | 1143 | render_environment_features(:usermenu) + |
1126 | - link_to('<i class="icon-menu-admin"></i><strong>' + _('Administration') + '</strong>', @environment.top_url + '/admin', :title => _("Configure the environment"), :class => 'admin-link', :style => 'display: none') + | ||
1127 | - manage_enterprises.to_s + | ||
1128 | - manage_communities.to_s + | ||
1129 | - link_to('<i class="icon-menu-ctrl-panel"></i><strong>' + _('Control panel') + '</strong>', @environment.top_url + '/myprofile/{login}', :class => 'ctrl-panel', :title => _("Configure your personal account and content")) + | 1144 | + admin_link + |
1145 | + manage_enterprises + | ||
1146 | + manage_communities + | ||
1147 | + link_to('<i class="icon-menu-ctrl-panel"></i><strong>' + _('Control panel') + '</strong>', user.admin_url, :class => 'ctrl-panel', :title => _("Configure your personal account and content")) + | ||
1130 | pending_tasks_count + | 1148 | pending_tasks_count + |
1131 | link_to('<i class="icon-menu-logout"></i><strong>' + _('Logout') + '</strong>', { :controller => 'account', :action => 'logout'} , :id => "logout", :title => _("Leave the system")) | 1149 | link_to('<i class="icon-menu-logout"></i><strong>' + _('Logout') + '</strong>', { :controller => 'account', :action => 'logout'} , :id => "logout", :title => _("Leave the system")) |
1132 | end | 1150 | end |
@@ -1210,22 +1228,9 @@ module ApplicationHelper | @@ -1210,22 +1228,9 @@ module ApplicationHelper | ||
1210 | end | 1228 | end |
1211 | 1229 | ||
1212 | def add_zoom_to_images | 1230 | def add_zoom_to_images |
1213 | - stylesheet_link_tag('fancybox') + | ||
1214 | - javascript_include_tag('jquery.fancybox-1.3.4.pack') + | ||
1215 | - javascript_tag("jQuery(function($) { | ||
1216 | - $(window).load( function() { | ||
1217 | - $('#article .article-body img').each( function(index) { | ||
1218 | - var original = original_image_dimensions($(this).attr('src')); | ||
1219 | - if ($(this).width() < original['width'] || $(this).height() < original['height']) { | ||
1220 | - $(this).wrap('<div class=\"zoomable-image\" />'); | ||
1221 | - $(this).parent('.zoomable-image').attr('style', $(this).attr('style')); | ||
1222 | - $(this).attr('style', ''); | ||
1223 | - $(this).after(\'<a href=\"' + $(this).attr('src') + '\" class=\"zoomify-image\"><span class=\"zoomify-text\">%s</span></a>'); | ||
1224 | - } | ||
1225 | - }); | ||
1226 | - $('.zoomify-image').fancybox(); | ||
1227 | - }); | ||
1228 | - });" % _('Zoom in')) | 1231 | + stylesheet_link_tag('jquery.fancybox') + |
1232 | + javascript_include_tag('jquery.fancybox.pack') + | ||
1233 | + javascript_tag("apply_zoom_to_images(#{_('Zoom in').to_json})") | ||
1229 | end | 1234 | end |
1230 | 1235 | ||
1231 | def render_dialog_error_messages(instance_name) | 1236 | def render_dialog_error_messages(instance_name) |
@@ -1281,9 +1286,9 @@ module ApplicationHelper | @@ -1281,9 +1286,9 @@ module ApplicationHelper | ||
1281 | 1286 | ||
1282 | def delete_article_message(article) | 1287 | def delete_article_message(article) |
1283 | if article.folder? | 1288 | if article.folder? |
1284 | - _("Are you sure that you want to remove the folder \"#{article.name}\"? Note that all the items inside it will also be removed!") | 1289 | + _("Are you sure that you want to remove the folder \"%s\"? Note that all the items inside it will also be removed!") % article.name |
1285 | else | 1290 | else |
1286 | - _("Are you sure that you want to remove the item \"#{article.name}\"?") | 1291 | + _("Are you sure that you want to remove the item \"%s\"?") % article.name |
1287 | end | 1292 | end |
1288 | end | 1293 | end |
1289 | 1294 | ||
@@ -1360,7 +1365,7 @@ module ApplicationHelper | @@ -1360,7 +1365,7 @@ module ApplicationHelper | ||
1360 | @message = _("The content here is available to %s's friends only.") % profile.short_name | 1365 | @message = _("The content here is available to %s's friends only.") % profile.short_name |
1361 | else | 1366 | else |
1362 | @action = :join | 1367 | @action = :join |
1363 | - @message = _('The contents in this community is available to members only.') | 1368 | + @message = _('The contents in this profile is available to members only.') |
1364 | end | 1369 | end |
1365 | @no_design_blocks = true | 1370 | @no_design_blocks = true |
1366 | end | 1371 | end |
@@ -1402,4 +1407,14 @@ module ApplicationHelper | @@ -1402,4 +1407,14 @@ module ApplicationHelper | ||
1402 | content_tag('ul', article.versions.map {|v| link_to("r#{v.version}", @page.url.merge(:version => v.version))}) | 1407 | content_tag('ul', article.versions.map {|v| link_to("r#{v.version}", @page.url.merge(:version => v.version))}) |
1403 | end | 1408 | end |
1404 | 1409 | ||
1410 | + def labelled_colorpicker_field(human_name, object_name, method, options = {}) | ||
1411 | + options[:id] ||= 'text-field-' + FormsHelper.next_id_number | ||
1412 | + content_tag('label', human_name, :for => options[:id], :class => 'formlabel') + | ||
1413 | + colorpicker_field(object_name, method, options.merge(:class => 'colorpicker_field')) | ||
1414 | + end | ||
1415 | + | ||
1416 | + def colorpicker_field(object_name, method, options = {}) | ||
1417 | + text_field(object_name, method, options.merge(:class => 'colorpicker_field')) | ||
1418 | + end | ||
1419 | + | ||
1405 | end | 1420 | end |
app/helpers/article_helper.rb
@@ -3,6 +3,12 @@ module ArticleHelper | @@ -3,6 +3,12 @@ module ArticleHelper | ||
3 | include PrototypeHelper | 3 | include PrototypeHelper |
4 | include TokenHelper | 4 | include TokenHelper |
5 | 5 | ||
6 | + def article_reported_version(article) | ||
7 | + search_path = Rails.root.join('app', 'views', 'shared', 'reported_versions') | ||
8 | + partial_path = File.join('shared', 'reported_versions', 'profile', partial_for_class_in_view_path(article.class, search_path)) | ||
9 | + render_to_string(:partial => partial_path, :locals => {:article => article}) | ||
10 | + end | ||
11 | + | ||
6 | def custom_options_for_article(article, tokenized_children) | 12 | def custom_options_for_article(article, tokenized_children) |
7 | @article = article | 13 | @article = article |
8 | 14 | ||
@@ -83,6 +89,10 @@ module ArticleHelper | @@ -83,6 +89,10 @@ module ArticleHelper | ||
83 | array.map { |object| {:id => object.id, :name => object.name} } | 89 | array.map { |object| {:id => object.id, :name => object.name} } |
84 | end | 90 | end |
85 | 91 | ||
92 | + def prepare_to_token_input_by_label(array) | ||
93 | + array.map { |object| {:label => object.name, :value => object.name} } | ||
94 | + end | ||
95 | + | ||
86 | def cms_label_for_new_children | 96 | def cms_label_for_new_children |
87 | _('New article') | 97 | _('New article') |
88 | end | 98 | end |
app/helpers/block_helper.rb
@@ -6,19 +6,20 @@ module BlockHelper | @@ -6,19 +6,20 @@ module BlockHelper | ||
6 | content_tag 'h3', content_tag('span', h(title)), :class => tag_class | 6 | content_tag 'h3', content_tag('span', h(title)), :class => tag_class |
7 | end | 7 | end |
8 | 8 | ||
9 | - def highlights_block_config_image_fields(block, image={}) | 9 | + def highlights_block_config_image_fields(block, image={}, row_number=nil) |
10 | " | 10 | " |
11 | - <tr class=\"image-data-line\"> | 11 | + <tr class=\"image-data-line\" data-row-number='#{row_number}'> |
12 | <td> | 12 | <td> |
13 | #{select_tag 'block[images][][image_id]', content_tag(:option) + option_groups_from_collection_for_select(block.folder_choices, :images, :name, :id, :name, image[:image_id].to_i).html_safe} | 13 | #{select_tag 'block[images][][image_id]', content_tag(:option) + option_groups_from_collection_for_select(block.folder_choices, :images, :name, :id, :name, image[:image_id].to_i).html_safe} |
14 | </td> | 14 | </td> |
15 | <td>#{text_field_tag 'block[images][][address]', image[:address], :class => 'highlight-address', :size => 20}</td> | 15 | <td>#{text_field_tag 'block[images][][address]', image[:address], :class => 'highlight-address', :size => 20}</td> |
16 | <td>#{text_field_tag 'block[images][][position]', image[:position], :class => 'highlight-position', :size => 1}</td> | 16 | <td>#{text_field_tag 'block[images][][position]', image[:position], :class => 'highlight-position', :size => 1}</td> |
17 | - </tr><tr class=\"image-title\"> | 17 | + </tr><tr class=\"image-title\" data-row-number='#{row_number}'> |
18 | <td colspan=\"3\"><label>#{ | 18 | <td colspan=\"3\"><label>#{ |
19 | content_tag('span', _('Title')) + | 19 | content_tag('span', _('Title')) + |
20 | text_field_tag('block[images][][title]', image[:title], :class => 'highlight-title', :size => 45) | 20 | text_field_tag('block[images][][title]', image[:title], :class => 'highlight-title', :size => 45) |
21 | }</label></td> | 21 | }</label></td> |
22 | + <td>#{link_to '', '#', :class=>'button icon-button icon-delete delete-highlight', :confirm=>_('Are you sure you want to remove this highlight')}</td> | ||
22 | </tr> | 23 | </tr> |
23 | " | 24 | " |
24 | end | 25 | end |
app/helpers/blog_helper.rb
@@ -17,13 +17,13 @@ module BlogHelper | @@ -17,13 +17,13 @@ module BlogHelper | ||
17 | _('Configure blog') | 17 | _('Configure blog') |
18 | end | 18 | end |
19 | 19 | ||
20 | - def list_posts(articles, format = 'full') | 20 | + def list_posts(articles, format = 'full', paginate = true) |
21 | pagination = will_paginate(articles, { | 21 | pagination = will_paginate(articles, { |
22 | :param_name => 'npage', | 22 | :param_name => 'npage', |
23 | :previous_label => _('« Newer posts'), | 23 | :previous_label => _('« Newer posts'), |
24 | :next_label => _('Older posts »'), | 24 | :next_label => _('Older posts »'), |
25 | :params => {:action=>"view_page", :page=>articles.first.parent.path.split('/'), :controller=>"content_viewer"} | 25 | :params => {:action=>"view_page", :page=>articles.first.parent.path.split('/'), :controller=>"content_viewer"} |
26 | - }) if articles.present? | 26 | + }) if articles.present? && paginate |
27 | content = [] | 27 | content = [] |
28 | artic_len = articles.length | 28 | artic_len = articles.length |
29 | articles.each_with_index{ |art,i| | 29 | articles.each_with_index{ |art,i| |
@@ -45,9 +45,9 @@ module BlogHelper | @@ -45,9 +45,9 @@ module BlogHelper | ||
45 | 45 | ||
46 | def display_post(article, format = 'full') | 46 | def display_post(article, format = 'full') |
47 | no_comments = (format == 'full') ? false : true | 47 | no_comments = (format == 'full') ? false : true |
48 | + title = article_title(article, :no_comments => no_comments) | ||
48 | html = send("display_#{format}_format", FilePresenter.for(article)).html_safe | 49 | html = send("display_#{format}_format", FilePresenter.for(article)).html_safe |
49 | - | ||
50 | - article_title(article, :no_comments => no_comments) + html | 50 | + title + html |
51 | end | 51 | end |
52 | 52 | ||
53 | def display_full_format(article) | 53 | def display_full_format(article) |
app/helpers/categories_helper.rb
1 | module CategoriesHelper | 1 | module CategoriesHelper |
2 | 2 | ||
3 | - | ||
4 | - COLORS = [ | ||
5 | - [ N_('Do not display at the menu'), nil ], | ||
6 | - [ N_('Orange'), 1], | ||
7 | - [ N_('Green'), 2], | ||
8 | - [ N_('Purple'), 3], | ||
9 | - [ N_('Red'), 4], | ||
10 | - [ N_('Dark Green'), 5], | ||
11 | - [ N_('Blue Oil'), 6], | ||
12 | - [ N_('Blue'), 7], | ||
13 | - [ N_('Brown'), 8], | ||
14 | - [ N_('Light Green'), 9], | ||
15 | - [ N_('Light Blue'), 10], | ||
16 | - [ N_('Dark Blue'), 11], | ||
17 | - [ N_('Blue Pool'), 12], | ||
18 | - [ N_('Beige'), 13], | ||
19 | - [ N_('Yellow'), 14], | ||
20 | - [ N_('Light Brown'), 15] | ||
21 | - ] | ||
22 | - | ||
23 | TYPES = [ | 3 | TYPES = [ |
24 | [ _('General Category'), Category.to_s ], | 4 | [ _('General Category'), Category.to_s ], |
25 | [ _('Product Category'), ProductCategory.to_s ], | 5 | [ _('Product Category'), ProductCategory.to_s ], |
26 | [ _('Region'), Region.to_s ], | 6 | [ _('Region'), Region.to_s ], |
27 | ] | 7 | ] |
28 | 8 | ||
29 | - def select_color_for_category | ||
30 | - if @category.top_level? | ||
31 | - labelled_form_field(_('Display at the menu?'), select('category', 'display_color', CategoriesHelper::COLORS.map {|item| [gettext(item[0]), item[1]] })) | ||
32 | - else | ||
33 | - "" | ||
34 | - end | ||
35 | - end | ||
36 | - | ||
37 | - def display_color_for_category(category) | ||
38 | - color = category.display_color | ||
39 | - if color.nil? | ||
40 | - "" | ||
41 | - else | ||
42 | - "[" + gettext(CategoriesHelper::COLORS.find {|item| item[1] == color}.first) + "]" | ||
43 | - end | ||
44 | - end | ||
45 | - | ||
46 | def select_category_type(field) | 9 | def select_category_type(field) |
47 | value = params[field] | 10 | value = params[field] |
48 | labelled_form_field(_('Type of category'), select_tag('type', options_for_select(TYPES, value))) | 11 | labelled_form_field(_('Type of category'), select_tag('type', options_for_select(TYPES, value))) |
49 | end | 12 | end |
50 | 13 | ||
14 | + def category_color_style(category) | ||
15 | + return '' if category.nil? or category.display_color.blank? | ||
16 | + 'background-color: #'+category.display_color+';' | ||
17 | + end | ||
18 | + | ||
51 | #FIXME make this test | 19 | #FIXME make this test |
52 | def selected_category_link(cat) | 20 | def selected_category_link(cat) |
53 | js_remove = "jQuery('#selected-category-#{cat.id}').remove();" | 21 | js_remove = "jQuery('#selected-category-#{cat.id}').remove();" |
app/helpers/content_viewer_helper.rb
@@ -10,7 +10,7 @@ module ContentViewerHelper | @@ -10,7 +10,7 @@ module ContentViewerHelper | ||
10 | end | 10 | end |
11 | 11 | ||
12 | def number_of_comments(article) | 12 | def number_of_comments(article) |
13 | - display_number_of_comments(article.comments.without_spam.count) | 13 | + display_number_of_comments(article.comments_count - article.spam_comments_count) |
14 | end | 14 | end |
15 | 15 | ||
16 | def article_title(article, args = {}) | 16 | def article_title(article, args = {}) |
@@ -26,7 +26,7 @@ module ContentViewerHelper | @@ -26,7 +26,7 @@ module ContentViewerHelper | ||
26 | end | 26 | end |
27 | title << content_tag('span', | 27 | title << content_tag('span', |
28 | content_tag('span', show_date(article.published_at), :class => 'date') + | 28 | content_tag('span', show_date(article.published_at), :class => 'date') + |
29 | - content_tag('span', _(", by %s") % link_to(article.author_name, article.author_url), :class => 'author') + | 29 | + content_tag('span', _(", by %s") % (article.author ? link_to(article.author_name, article.author_url) : article.author_name), :class => 'author') + |
30 | content_tag('span', comments, :class => 'comments'), | 30 | content_tag('span', comments, :class => 'comments'), |
31 | :class => 'created-at' | 31 | :class => 'created-at' |
32 | ) | 32 | ) |
app/helpers/folder_helper.rb
@@ -5,15 +5,17 @@ module FolderHelper | @@ -5,15 +5,17 @@ module FolderHelper | ||
5 | include ShortFilename | 5 | include ShortFilename |
6 | include ArticleHelper | 6 | include ArticleHelper |
7 | 7 | ||
8 | - def list_articles(articles, recursive = false) | ||
9 | - if !articles.blank? | ||
10 | - articles = articles.paginate( | 8 | + def list_contents(configure={}) |
9 | + configure[:recursive] ||= false | ||
10 | + configure[:list_type] ||= :folder | ||
11 | + if !configure[:contents].blank? | ||
12 | + configure[:contents] = configure[:contents].paginate( | ||
11 | :order => "updated_at DESC", | 13 | :order => "updated_at DESC", |
12 | :per_page => 10, | 14 | :per_page => 10, |
13 | :page => params[:npage] | 15 | :page => params[:npage] |
14 | ) | 16 | ) |
15 | 17 | ||
16 | - render :file => 'shared/articles_list', :locals => {:articles => articles, :recursive => recursive} | 18 | + render :file => 'shared/content_list', :locals => configure |
17 | else | 19 | else |
18 | content_tag('em', _('(empty folder)')) | 20 | content_tag('em', _('(empty folder)')) |
19 | end | 21 | end |
@@ -23,21 +25,33 @@ module FolderHelper | @@ -23,21 +25,33 @@ module FolderHelper | ||
23 | articles.select {|article| article.display_to?(user)} | 25 | articles.select {|article| article.display_to?(user)} |
24 | end | 26 | end |
25 | 27 | ||
26 | - def display_article_in_listing(article, recursive = false, level = 0) | ||
27 | - article = FilePresenter.for article | ||
28 | - article_link = if article.image? | ||
29 | - link_to(' ' * (level * 4) + image_tag(icon_for_article(article)) + short_filename(article.name), article.url.merge(:view => true)) | 28 | + def display_content_in_listing(configure={}) |
29 | + recursive = configure[:recursive] || false | ||
30 | + list_type = configure[:list_type] || :folder | ||
31 | + level = configure[:level] || 0 | ||
32 | + content = FilePresenter.for configure[:content] | ||
33 | + content_link = if content.image? | ||
34 | + link_to(' ' * (level * 4) + | ||
35 | + image_tag(icon_for_article(content)) + short_filename(content.name), | ||
36 | + content.url.merge(:view => true) | ||
37 | + ) | ||
30 | else | 38 | else |
31 | - link_to(' ' * (level * 4) + short_filename(article.name), article.url.merge(:view => true), :class => icon_for_article(article)) | 39 | + link_to(' ' * (level * 4) + |
40 | + short_filename(content.name), | ||
41 | + content.url.merge(:view => true), :class => icon_for_article(content) | ||
42 | + ) | ||
32 | end | 43 | end |
33 | result = content_tag( | 44 | result = content_tag( |
34 | 'tr', | 45 | 'tr', |
35 | - content_tag('td', article_link )+ | ||
36 | - content_tag('td', show_date(article.updated_at), :class => 'last-update'), | ||
37 | - :class => 'sitemap-item' | 46 | + content_tag('td', content_link ) + |
47 | + content_tag('td', show_date(content.updated_at), :class => 'last-update'), | ||
48 | + :class => "#{list_type}-item" | ||
38 | ) | 49 | ) |
39 | if recursive | 50 | if recursive |
40 | - result + article.children.map {|item| display_article_in_listing(item, recursive, level + 1) }.join('') | 51 | + result + content.children.map {|item| |
52 | + display_content_in_listing :content=>item, :recursive=>recursive, | ||
53 | + :list_type=>list_type, :level=>level+1 | ||
54 | + }.join("\n") | ||
41 | else | 55 | else |
42 | result | 56 | result |
43 | end | 57 | end |
app/helpers/layout_helper.rb
@@ -27,6 +27,7 @@ module LayoutHelper | @@ -27,6 +27,7 @@ module LayoutHelper | ||
27 | 'thickbox', | 27 | 'thickbox', |
28 | 'lightbox', | 28 | 'lightbox', |
29 | 'colorbox', | 29 | 'colorbox', |
30 | + 'inputosaurus', | ||
30 | pngfix_stylesheet_path, | 31 | pngfix_stylesheet_path, |
31 | ] + tokeninput_stylesheets | 32 | ] + tokeninput_stylesheets |
32 | plugins_stylesheets = @plugins.select(&:stylesheet?).map { |plugin| plugin.class.public_path('style.css') } | 33 | plugins_stylesheets = @plugins.select(&:stylesheet?).map { |plugin| plugin.class.public_path('style.css') } |
app/helpers/profile_helper.rb
1 | module ProfileHelper | 1 | module ProfileHelper |
2 | 2 | ||
3 | - def display_field(title, profile, field, force = false) | 3 | + COMMON_CATEGORIES = ActiveSupport::OrderedHash.new |
4 | + COMMON_CATEGORIES[:content] = [:blogs, :image_galleries, :events, :article_tags] | ||
5 | + COMMON_CATEGORIES[:interests] = [:interests] | ||
6 | + COMMON_CATEGORIES[:general] = nil | ||
7 | + | ||
8 | + PERSON_CATEGORIES = ActiveSupport::OrderedHash.new | ||
9 | + PERSON_CATEGORIES[:basic_information] = [:nickname, :sex, :birth_date, :location, :privacy_setting, :created_at] | ||
10 | + PERSON_CATEGORIES[:contact] = [:contact_phone, :cell_phone, :comercial_phone, :contact_information, :email, :personal_website, :jabber_id] | ||
11 | + PERSON_CATEGORIES[:location] = [:address, :address_reference, :zip_code, :city, :state, :district, :country, :nationality] | ||
12 | + PERSON_CATEGORIES[:work] = [:organization, :organization_website, :professional_activity] | ||
13 | + PERSON_CATEGORIES[:study] = [:schooling, :formation, :area_of_study] | ||
14 | + PERSON_CATEGORIES[:network] = [:friends, :communities, :enterprises] | ||
15 | + PERSON_CATEGORIES.merge!(COMMON_CATEGORIES) | ||
16 | + | ||
17 | + ORGANIZATION_CATEGORIES = ActiveSupport::OrderedHash.new | ||
18 | + ORGANIZATION_CATEGORIES[:basic_information] = [:display_name, :created_at, :foundation_year, :type, :language, :members_count, :location, :address_reference, :historic_and_current_context, :admins] | ||
19 | + ORGANIZATION_CATEGORIES[:contact] = [:contact_person, :contact_phone, :contact_email, :organization_website, :jabber_id] | ||
20 | + ORGANIZATION_CATEGORIES[:economic] = [:business_name, :acronym, :economic_activity, :legal_form, :products, :activities_short_description, :management_information] | ||
21 | + ORGANIZATION_CATEGORIES.merge!(COMMON_CATEGORIES) | ||
22 | + | ||
23 | + CATEGORY_MAP = ActiveSupport::OrderedHash.new | ||
24 | + CATEGORY_MAP[:person] = PERSON_CATEGORIES | ||
25 | + CATEGORY_MAP[:organization] = ORGANIZATION_CATEGORIES | ||
26 | + | ||
27 | + FORCE = { | ||
28 | + :person => [:privacy_setting], | ||
29 | + :organization => [:privacy_setting, :location], | ||
30 | + } | ||
31 | + | ||
32 | + MULTIPLE = { | ||
33 | + :person => [:blogs, :image_galleries, :interests], | ||
34 | + :organization => [:blogs, :image_galleries, :interests], | ||
35 | + } | ||
36 | + | ||
37 | + CUSTOM_LABELS = { | ||
38 | + :zip_code => _('ZIP code'), | ||
39 | + :email => _('e-Mail'), | ||
40 | + :jabber_id => _('Jabber'), | ||
41 | + :birth_date => _('Date of birth'), | ||
42 | + :created_at => _('Profile created at'), | ||
43 | + :members_count => _('Members'), | ||
44 | + :privacy_setting => _('Privacy setting'), | ||
45 | + :article_tags => _('Tags') | ||
46 | + } | ||
47 | + | ||
48 | + EXCEPTION = { | ||
49 | + :person => [:image, :preferred_domain, :description, :tag_list], | ||
50 | + :organization => [:image, :preferred_domain, :description, :tag_list, :address, :zip_code, :city, :state, :country, :district] | ||
51 | + } | ||
52 | + | ||
53 | + def general_fields | ||
54 | + categorized_fields = CATEGORY_MAP[kind].values.flatten | ||
55 | + profile.class.fields.map(&:to_sym) - categorized_fields - EXCEPTION[kind] | ||
56 | + end | ||
57 | + | ||
58 | + def kind | ||
59 | + if profile.kind_of?(Person) | ||
60 | + :person | ||
61 | + else | ||
62 | + :organization | ||
63 | + end | ||
64 | + end | ||
65 | + | ||
66 | + def title(field, entry = nil) | ||
67 | + return self.send("#{field}_custom_title", entry) if MULTIPLE[kind].include?(field) && entry.present? | ||
68 | + CUSTOM_LABELS[field.to_sym] || _(field.to_s.humanize) | ||
69 | + end | ||
70 | + | ||
71 | + def display_field(field) | ||
72 | + force = FORCE[kind].include?(field) | ||
73 | + multiple = MULTIPLE[kind].include?(field) | ||
4 | unless force || profile.may_display_field_to?(field, user) | 74 | unless force || profile.may_display_field_to?(field, user) |
5 | return '' | 75 | return '' |
6 | end | 76 | end |
7 | - value = profile.send(field) | ||
8 | - if !value.blank? | ||
9 | - if block_given? | ||
10 | - value = yield(value) | ||
11 | - end | ||
12 | - content_tag('tr', content_tag('td', title, :class => 'field-name') + content_tag('td', value)) | 77 | + value = begin profile.send(field) rescue nil end |
78 | + return '' if value.blank? | ||
79 | + if value.kind_of?(Hash) | ||
80 | + content = self.send("treat_#{field}", value) | ||
81 | + content_tag('tr', content_tag('td', title(field), :class => 'field-name') + content_tag('td', content)) | ||
13 | else | 82 | else |
14 | - '' | 83 | + entries = multiple ? value : [] << value |
84 | + entries.map do |entry| | ||
85 | + content = self.send("treat_#{field}", entry) | ||
86 | + unless content.blank? | ||
87 | + content_tag('tr', content_tag('td', title(field, entry), :class => 'field-name') + content_tag('td', content)) | ||
88 | + end | ||
89 | + end.join("\n") | ||
15 | end | 90 | end |
16 | end | 91 | end |
17 | 92 | ||
18 | - def display_contact(profile) | ||
19 | - fields = [] | ||
20 | - fields << display_field(_('Address:'), profile, :address).html_safe | ||
21 | - fields << display_field(_('ZIP code:'), profile, :zip_code).html_safe | ||
22 | - fields << display_field(_('Contact phone:'), profile, :contact_phone).html_safe | ||
23 | - fields << display_field(_('e-Mail:'), profile, :email) { |email| link_to_email(email) }.html_safe | ||
24 | - fields << display_field(_('Personal website:'), profile, :personal_website).html_safe | ||
25 | - fields << display_field(_('Jabber:'), profile, :jabber_id).html_safe | ||
26 | - if fields.reject!(&:blank?).empty? | ||
27 | - '' | ||
28 | - else | ||
29 | - content_tag('tr', content_tag('th', _('Contact'), { :colspan => 2 })) + fields.join.html_safe | 93 | + def treat_email(email) |
94 | + link_to_email(email) | ||
95 | + end | ||
96 | + | ||
97 | + def treat_organization_website(url) | ||
98 | + link_to(url, url) | ||
99 | + end | ||
100 | + | ||
101 | + def treat_sex(gender) | ||
102 | + { 'male' => _('Male'), 'female' => _('Female') }[gender] | ||
103 | + end | ||
104 | + | ||
105 | + def treat_date(date) | ||
106 | + show_date(date.to_date) | ||
107 | + end | ||
108 | + alias :treat_birth_date :treat_date | ||
109 | + alias :treat_created_at :treat_date | ||
110 | + | ||
111 | + def treat_friends(friends) | ||
112 | + link_to friends.count, :controller => 'profile', :action => 'friends' | ||
113 | + end | ||
114 | + | ||
115 | + def treat_communities(communities) | ||
116 | + link_to communities.count, :controller => "profile", :action => 'communities' | ||
117 | + end | ||
118 | + | ||
119 | + def treat_enterprises(enterprises) | ||
120 | + if environment.disabled?('disable_asset_enterprises') | ||
121 | + link_to enterprises.count, :controller => "profile", :action => 'enterprises' | ||
122 | + end | ||
123 | + end | ||
124 | + | ||
125 | + def treat_members_count(count) | ||
126 | + link_to count, :controller => 'profile', :action => 'members' | ||
127 | + end | ||
128 | + | ||
129 | + def treat_products(products) | ||
130 | + if profile.kind_of?(Enterprise) && profile.environment.enabled?('products_for_enterprises') | ||
131 | + link_to _('Products/Services'), :controller => 'catalog', :action => 'index' | ||
30 | end | 132 | end |
31 | end | 133 | end |
32 | 134 | ||
33 | - def display_work_info(profile) | ||
34 | - organization = display_field(_('Organization:'), profile, :organization) | ||
35 | - organization_site = display_field(_('Organization website:'), profile, :organization_website) { |url| link_to(url, url) } | ||
36 | - if organization.blank? && organization_site.blank? | ||
37 | - '' | 135 | + def treat_admins(admins) |
136 | + profile.admins.map { |admin| link_to(admin.short_name, admin.url)}.join(', ') | ||
137 | + end | ||
138 | + | ||
139 | + def treat_blogs(blog) | ||
140 | + link_to(n_('One post', '%{num} posts', blog.posts.published.count) % { :num => blog.posts.published.count }, blog.url) | ||
141 | + end | ||
142 | + | ||
143 | + def treat_image_galleries(gallery) | ||
144 | + link_to(n_('One picture', '%{num} pictures', gallery.images.published.count) % { :num => gallery.images.published.count }, gallery.url) | ||
145 | + end | ||
146 | + | ||
147 | + def treat_events(events) | ||
148 | + link_to events.published.count, :controller => 'events', :action => 'events' | ||
149 | + end | ||
150 | + | ||
151 | + def treat_article_tags(tags) | ||
152 | + tag_cloud @tags, :id, { :action => 'tags' }, :max_size => 18, :min_size => 10 | ||
153 | + end | ||
154 | + | ||
155 | + def treat_interests(interest) | ||
156 | + link_to interest.name, :controller => 'search', :action => 'category_index', :category_path => interest.explode_path | ||
157 | + end | ||
158 | + | ||
159 | + def article_custom_title(article) | ||
160 | + article.name | ||
161 | + end | ||
162 | + alias :blogs_custom_title :article_custom_title | ||
163 | + alias :image_galleries_custom_title :article_custom_title | ||
164 | + | ||
165 | + def interests_custom_title(interest) | ||
166 | + '' | ||
167 | + end | ||
168 | + | ||
169 | + def method_missing(method, *args, &block) | ||
170 | + if method.to_s =~ /^treat_(.+)$/ | ||
171 | + args[0] | ||
172 | + elsif method.to_s =~ /^display_(.+)$/ && CATEGORY_MAP[kind].has_key?($1.to_sym) | ||
173 | + category = $1.to_sym | ||
174 | + fields = category == :general ? general_fields : CATEGORY_MAP[kind][category] | ||
175 | + contents = [] | ||
176 | + | ||
177 | + fields.each do |field| | ||
178 | + contents << display_field(field).html_safe | ||
179 | + end | ||
180 | + | ||
181 | + contents = contents.delete_if(&:blank?) | ||
182 | + | ||
183 | + unless contents.empty? | ||
184 | + content_tag('tr', content_tag('th', title(category), { :colspan => 2 })) + contents.join.html_safe | ||
185 | + else | ||
186 | + '' | ||
187 | + end | ||
38 | else | 188 | else |
39 | - content_tag('tr', content_tag('th', _('Work'), { :colspan => 2 })) + organization + organization_site | 189 | + super |
40 | end | 190 | end |
41 | end | 191 | end |
42 | 192 |
app/helpers/sweeper_helper.rb
@@ -18,9 +18,7 @@ module SweeperHelper | @@ -18,9 +18,7 @@ module SweeperHelper | ||
18 | expire_timeout_fragment(profile.manage_friends_cache_key(:npage => i.to_s)) | 18 | expire_timeout_fragment(profile.manage_friends_cache_key(:npage => i.to_s)) |
19 | end | 19 | end |
20 | 20 | ||
21 | - # friends blocks | ||
22 | - blocks = profile.blocks.select{|b| b.kind_of?(FriendsBlock)} | ||
23 | - BlockSweeper.expire_blocks(blocks) | 21 | + expire_blocks_cache(profile, [:profile]) |
24 | end | 22 | end |
25 | 23 | ||
26 | def expire_communities(profile) | 24 | def expire_communities(profile) |
@@ -0,0 +1,51 @@ | @@ -0,0 +1,51 @@ | ||
1 | +module TinymceHelper | ||
2 | + include MacrosHelper | ||
3 | + | ||
4 | + def tinymce_js | ||
5 | + output = '' | ||
6 | + output += javascript_include_tag 'tinymce/js/tinymce/tinymce.min.js' | ||
7 | + output += javascript_include_tag 'tinymce/js/tinymce/jquery.tinymce.min.js' | ||
8 | + output += javascript_include_tag 'tinymce.js' | ||
9 | + output += include_macro_js_files.to_s | ||
10 | + output | ||
11 | + end | ||
12 | + | ||
13 | + def tinymce_init_js options = {} | ||
14 | + options.merge! :document_base_url => environment.top_url, | ||
15 | + :content_css => "/stylesheets/tinymce.css,#{macro_css_files}", | ||
16 | + :plugins => %w[compat3x advlist autolink lists link image charmap print preview hr anchor pagebreak | ||
17 | + searchreplace wordcount visualblocks visualchars code fullscreen | ||
18 | + insertdatetime media nonbreaking save table contextmenu directionality | ||
19 | + emoticons template paste textcolor colorpicker textpattern], | ||
20 | + :language => tinymce_language | ||
21 | + | ||
22 | + options[:toolbar1] = "insertfile undo redo | copy paste | bold italic underline | styleselect fontsizeselect | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image" | ||
23 | + if options[:mode] == 'simple' | ||
24 | + options[:menubar] = false | ||
25 | + else | ||
26 | + options[:menubar] = 'edit insert view tools' | ||
27 | + options[:toolbar2] = 'print preview code media | table' | ||
28 | + | ||
29 | + options[:toolbar2] += ' | macros' | ||
30 | + macros_with_buttons.each do |macro| | ||
31 | + options[:toolbar2] += " #{macro.identifier}" | ||
32 | + end | ||
33 | + end | ||
34 | + | ||
35 | + options[:macros_setup] = macros_with_buttons.map do |macro| | ||
36 | + <<-EOS | ||
37 | + ed.addButton('#{macro.identifier}', { | ||
38 | + title: #{macro_title(macro).to_json}, | ||
39 | + onclick: #{generate_macro_config_dialog macro}, | ||
40 | + image : '#{macro.configuration[:icon_path]}' | ||
41 | + }); | ||
42 | + EOS | ||
43 | + end | ||
44 | + | ||
45 | + #cleanup non tinymce options | ||
46 | + options = options.except :mode | ||
47 | + | ||
48 | + "noosfero.tinymce.init(#{options.to_json})" | ||
49 | + end | ||
50 | + | ||
51 | +end |
app/helpers/token_helper.rb
@@ -18,6 +18,7 @@ module TokenHelper | @@ -18,6 +18,7 @@ module TokenHelper | ||
18 | options[:on_add] ||= 'null' | 18 | options[:on_add] ||= 'null' |
19 | options[:on_delete] ||= 'null' | 19 | options[:on_delete] ||= 'null' |
20 | options[:on_ready] ||= 'null' | 20 | options[:on_ready] ||= 'null' |
21 | + options[:query_param] ||= 'q' | ||
21 | 22 | ||
22 | result = text_field_tag(name, nil, text_field_options.merge(html_options.merge({:id => element_id}))) | 23 | result = text_field_tag(name, nil, text_field_options.merge(html_options.merge({:id => element_id}))) |
23 | result += javascript_tag("jQuery('##{element_id}') | 24 | result += javascript_tag("jQuery('##{element_id}') |
@@ -30,7 +31,7 @@ module TokenHelper | @@ -30,7 +31,7 @@ module TokenHelper | ||
30 | searchDelay: #{options[:search_delay].to_json}, | 31 | searchDelay: #{options[:search_delay].to_json}, |
31 | preventDuplicates: #{options[:prevent_duplicates].to_json}, | 32 | preventDuplicates: #{options[:prevent_duplicates].to_json}, |
32 | backspaceDeleteItem: #{options[:backspace_delete_item].to_json}, | 33 | backspaceDeleteItem: #{options[:backspace_delete_item].to_json}, |
33 | - queryParam: #{name.to_json}, | 34 | + queryParam: #{options[:query_param].to_json}, |
34 | tokenLimit: #{options[:token_limit].to_json}, | 35 | tokenLimit: #{options[:token_limit].to_json}, |
35 | onResult: #{options[:on_result]}, | 36 | onResult: #{options[:on_result]}, |
36 | onAdd: #{options[:on_add]}, | 37 | onAdd: #{options[:on_add]}, |
@@ -48,4 +49,4 @@ module TokenHelper | @@ -48,4 +49,4 @@ module TokenHelper | ||
48 | result | 49 | result |
49 | end | 50 | end |
50 | 51 | ||
51 | -end | ||
52 | \ No newline at end of file | 52 | \ No newline at end of file |
53 | +end |
app/mailers/user_mailer.rb
@@ -15,10 +15,12 @@ class UserMailer < ActionMailer::Base | @@ -15,10 +15,12 @@ class UserMailer < ActionMailer::Base | ||
15 | end | 15 | end |
16 | 16 | ||
17 | def activation_code(user) | 17 | def activation_code(user) |
18 | - @recipient = user.name, | 18 | + @recipient = user.name |
19 | @activation_code = user.activation_code | 19 | @activation_code = user.activation_code |
20 | @environment = user.environment.name | 20 | @environment = user.environment.name |
21 | @url = user.environment.top_url | 21 | @url = user.environment.top_url |
22 | + @redirection = (true if user.return_to) | ||
23 | + @join = (user.community_to_join if user.community_to_join) | ||
22 | 24 | ||
23 | mail( | 25 | mail( |
24 | from: "#{user.environment.name} <#{user.environment.contact_email}>", | 26 | from: "#{user.environment.name} <#{user.environment.contact_email}>", |
app/models/approve_article.rb
@@ -48,7 +48,7 @@ class ApproveArticle < Task | @@ -48,7 +48,7 @@ class ApproveArticle < Task | ||
48 | end | 48 | end |
49 | 49 | ||
50 | def perform | 50 | def perform |
51 | - article.copy!(:name => name, :abstract => abstract, :body => body, :profile => target, :reference_article => article, :parent => article_parent, :highlighted => highlighted, :source => article.source, :last_changed_by_id => article.author_id) | 51 | + article.copy!(:name => name, :abstract => abstract, :body => body, :profile => target, :reference_article => article, :parent => article_parent, :highlighted => highlighted, :source => article.source, :last_changed_by_id => article.last_changed_by_id, :created_by_id => article.created_by_id) |
52 | end | 52 | end |
53 | 53 | ||
54 | def title | 54 | def title |
app/models/article.rb
@@ -2,7 +2,7 @@ require 'hpricot' | @@ -2,7 +2,7 @@ require 'hpricot' | ||
2 | 2 | ||
3 | class Article < ActiveRecord::Base | 3 | class Article < ActiveRecord::Base |
4 | 4 | ||
5 | - attr_accessible :name, :body, :abstract, :profile, :tag_list, :parent, :allow_members_to_edit, :translation_of_id, :language, :license_id, :parent_id, :display_posts_in_current_language, :category_ids, :posts_per_page, :moderate_comments, :accept_comments, :feed, :published, :source, :highlighted, :notify_comments, :display_hits, :slug, :external_feed_builder, :display_versions | 5 | + attr_accessible :name, :body, :abstract, :profile, :tag_list, :parent, :allow_members_to_edit, :translation_of_id, :language, :license_id, :parent_id, :display_posts_in_current_language, :category_ids, :posts_per_page, :moderate_comments, :accept_comments, :feed, :published, :source, :highlighted, :notify_comments, :display_hits, :slug, :external_feed_builder, :display_versions, :external_link, :image_builder |
6 | 6 | ||
7 | acts_as_having_image | 7 | acts_as_having_image |
8 | 8 | ||
@@ -41,8 +41,8 @@ class Article < ActiveRecord::Base | @@ -41,8 +41,8 @@ class Article < ActiveRecord::Base | ||
41 | before_save :sanitize_tag_list | 41 | before_save :sanitize_tag_list |
42 | 42 | ||
43 | before_create do |article| | 43 | before_create do |article| |
44 | - if article.last_changed_by_id | ||
45 | - article.author_name = Person.find(article.last_changed_by_id).name | 44 | + if article.author |
45 | + article.author_name = article.author.name | ||
46 | end | 46 | end |
47 | end | 47 | end |
48 | 48 | ||
@@ -54,7 +54,9 @@ class Article < ActiveRecord::Base | @@ -54,7 +54,9 @@ class Article < ActiveRecord::Base | ||
54 | 54 | ||
55 | validates_uniqueness_of :slug, :scope => ['profile_id', 'parent_id'], :message => N_('The title (article name) is already being used by another article, please use another title.'), :if => lambda { |article| !article.slug.blank? } | 55 | validates_uniqueness_of :slug, :scope => ['profile_id', 'parent_id'], :message => N_('The title (article name) is already being used by another article, please use another title.'), :if => lambda { |article| !article.slug.blank? } |
56 | 56 | ||
57 | + belongs_to :author, :class_name => 'Person' | ||
57 | belongs_to :last_changed_by, :class_name => 'Person', :foreign_key => 'last_changed_by_id' | 58 | belongs_to :last_changed_by, :class_name => 'Person', :foreign_key => 'last_changed_by_id' |
59 | + belongs_to :created_by, :class_name => 'Person', :foreign_key => 'created_by_id' | ||
58 | 60 | ||
59 | has_many :comments, :class_name => 'Comment', :foreign_key => 'source_id', :dependent => :destroy, :order => 'created_at asc' | 61 | has_many :comments, :class_name => 'Comment', :foreign_key => 'source_id', :dependent => :destroy, :order => 'created_at asc' |
60 | 62 | ||
@@ -89,6 +91,11 @@ class Article < ActiveRecord::Base | @@ -89,6 +91,11 @@ class Article < ActiveRecord::Base | ||
89 | article.parent = article.profile.blog | 91 | article.parent = article.profile.blog |
90 | end | 92 | end |
91 | end | 93 | end |
94 | + | ||
95 | + if article.created_by | ||
96 | + article.author_name = article.created_by.name | ||
97 | + end | ||
98 | + | ||
92 | end | 99 | end |
93 | 100 | ||
94 | after_destroy :destroy_activity | 101 | after_destroy :destroy_activity |
@@ -150,14 +157,17 @@ class Article < ActiveRecord::Base | @@ -150,14 +157,17 @@ class Article < ActiveRecord::Base | ||
150 | self.profile | 157 | self.profile |
151 | end | 158 | end |
152 | 159 | ||
153 | - def self.human_attribute_name(attrib, options = {}) | 160 | + def self.human_attribute_name_with_customization(attrib, options={}) |
154 | case attrib.to_sym | 161 | case attrib.to_sym |
155 | when :name | 162 | when :name |
156 | _('Title') | 163 | _('Title') |
157 | else | 164 | else |
158 | - _(self.superclass.human_attribute_name(attrib)) | 165 | + _(self.human_attribute_name_without_customization(attrib)) |
159 | end | 166 | end |
160 | end | 167 | end |
168 | + class << self | ||
169 | + alias_method_chain :human_attribute_name, :customization | ||
170 | + end | ||
161 | 171 | ||
162 | def css_class_list | 172 | def css_class_list |
163 | [self.class.name.to_css_class] | 173 | [self.class.name.to_css_class] |
@@ -205,6 +215,10 @@ class Article < ActiveRecord::Base | @@ -205,6 +215,10 @@ class Article < ActiveRecord::Base | ||
205 | acts_as_versioned | 215 | acts_as_versioned |
206 | self.non_versioned_columns << 'setting' | 216 | self.non_versioned_columns << 'setting' |
207 | 217 | ||
218 | + def version_condition_met? | ||
219 | + (['name', 'body', 'abstract', 'filename', 'start_date', 'end_date', 'image_id', 'license_id'] & changed).length > 0 | ||
220 | + end | ||
221 | + | ||
208 | def comment_data | 222 | def comment_data |
209 | comments.map {|item| [item.title, item.body].join(' ') }.join(' ') | 223 | comments.map {|item| [item.title, item.body].join(' ') }.join(' ') |
210 | end | 224 | end |
@@ -271,13 +285,6 @@ class Article < ActiveRecord::Base | @@ -271,13 +285,6 @@ class Article < ActiveRecord::Base | ||
271 | end | 285 | end |
272 | end | 286 | end |
273 | 287 | ||
274 | - def reported_version(options = {}) | ||
275 | - article = self | ||
276 | - search_path = Rails.root.join('app', 'views', 'shared', 'reported_versions') | ||
277 | - partial_path = File.join('shared', 'reported_versions', partial_for_class_in_view_path(article.class, search_path)) | ||
278 | - lambda { render_to_string(:partial => partial_path, :locals => {:article => article}) } | ||
279 | - end | ||
280 | - | ||
281 | # returns the data of the article. Must be overriden in each subclass to | 288 | # returns the data of the article. Must be overriden in each subclass to |
282 | # provide the correct content for the article. | 289 | # provide the correct content for the article. |
283 | def data | 290 | def data |
@@ -452,10 +459,10 @@ class Article < ActiveRecord::Base | @@ -452,10 +459,10 @@ class Article < ActiveRecord::Base | ||
452 | ['TextArticle', 'TextileArticle', 'TinyMceArticle'] | 459 | ['TextArticle', 'TextileArticle', 'TinyMceArticle'] |
453 | end | 460 | end |
454 | 461 | ||
455 | - scope :published, :conditions => { :published => true } | ||
456 | - scope :folders, lambda {|profile|{:conditions => { :type => profile.folder_types} }} | ||
457 | - scope :no_folders, lambda {|profile|{:conditions => ['type NOT IN (?)', profile.folder_types]}} | ||
458 | - scope :galleries, :conditions => { :type => 'Gallery' } | 462 | + scope :published, :conditions => ['articles.published = ?', true] |
463 | + scope :folders, lambda {|profile|{:conditions => ['articles.type IN (?)', profile.folder_types] }} | ||
464 | + scope :no_folders, lambda {|profile|{:conditions => ['articles.type NOT IN (?)', profile.folder_types]}} | ||
465 | + scope :galleries, :conditions => [ "articles.type IN ('Gallery')" ] | ||
459 | scope :images, :conditions => { :is_image => true } | 466 | scope :images, :conditions => { :is_image => true } |
460 | scope :text_articles, :conditions => [ 'articles.type IN (?)', text_article_types ] | 467 | scope :text_articles, :conditions => [ 'articles.type IN (?)', text_article_types ] |
461 | scope :with_types, lambda { |types| { :conditions => [ 'articles.type IN (?)', types ] } } | 468 | scope :with_types, lambda { |types| { :conditions => [ 'articles.type IN (?)', types ] } } |
@@ -465,7 +472,7 @@ class Article < ActiveRecord::Base | @@ -465,7 +472,7 @@ class Article < ActiveRecord::Base | ||
465 | scope :more_recent, :order => "created_at DESC" | 472 | scope :more_recent, :order => "created_at DESC" |
466 | 473 | ||
467 | def self.display_filter(user, profile) | 474 | def self.display_filter(user, profile) |
468 | - return {:conditions => ['published = ?', true]} if !user | 475 | + return {:conditions => ['articles.published = ?', true]} if !user |
469 | {:conditions => [" articles.published = ? OR | 476 | {:conditions => [" articles.published = ? OR |
470 | articles.last_changed_by_id = ? OR | 477 | articles.last_changed_by_id = ? OR |
471 | articles.profile_id = ? OR | 478 | articles.profile_id = ? OR |
@@ -492,6 +499,7 @@ class Article < ActiveRecord::Base | @@ -492,6 +499,7 @@ class Article < ActiveRecord::Base | ||
492 | end | 499 | end |
493 | 500 | ||
494 | def allow_post_content?(user = nil) | 501 | def allow_post_content?(user = nil) |
502 | + return true if allow_edit_topic?(user) | ||
495 | user && (user.has_permission?('post_content', profile) || allow_publish_content?(user) && (user == author)) | 503 | user && (user.has_permission?('post_content', profile) || allow_publish_content?(user) && (user == author)) |
496 | end | 504 | end |
497 | 505 | ||
@@ -511,9 +519,14 @@ class Article < ActiveRecord::Base | @@ -511,9 +519,14 @@ class Article < ActiveRecord::Base | ||
511 | end | 519 | end |
512 | 520 | ||
513 | def allow_edit?(user) | 521 | def allow_edit?(user) |
522 | + return true if allow_edit_topic?(user) | ||
514 | allow_post_content?(user) || user && allow_members_to_edit && user.is_member_of?(profile) | 523 | allow_post_content?(user) || user && allow_members_to_edit && user.is_member_of?(profile) |
515 | end | 524 | end |
516 | 525 | ||
526 | + def allow_edit_topic?(user) | ||
527 | + self.belongs_to_forum? && (user == author) && user.present? && user.is_member_of?(profile) | ||
528 | + end | ||
529 | + | ||
517 | def moderate_comments? | 530 | def moderate_comments? |
518 | moderate_comments == true | 531 | moderate_comments == true |
519 | end | 532 | end |
@@ -628,39 +641,36 @@ class Article < ActiveRecord::Base | @@ -628,39 +641,36 @@ class Article < ActiveRecord::Base | ||
628 | can_display_versions? && display_versions | 641 | can_display_versions? && display_versions |
629 | end | 642 | end |
630 | 643 | ||
631 | - def author(version_number = nil) | ||
632 | - if version_number | ||
633 | - version = versions.find_by_version(version_number) | ||
634 | - author_id = version.last_changed_by_id if version | ||
635 | - Person.exists?(author_id) ? Person.find(author_id) : nil | ||
636 | - else | ||
637 | - if versions.empty? | ||
638 | - last_changed_by | ||
639 | - else | ||
640 | - author_id = versions.first.last_changed_by_id | ||
641 | - Person.exists?(author_id) ? Person.find(author_id) : nil | ||
642 | - end | ||
643 | - end | 644 | + def get_version(version_number = nil) |
645 | + version_number ? versions.find(:first, :order => 'version', :offset => version_number - 1) : versions.earliest | ||
646 | + end | ||
647 | + | ||
648 | + def author_by_version(version_number = nil) | ||
649 | + version_number ? profile.environment.people.find_by_id(get_version(version_number).author_id) : author | ||
644 | end | 650 | end |
645 | 651 | ||
646 | def author_name(version_number = nil) | 652 | def author_name(version_number = nil) |
647 | - person = author(version_number) | ||
648 | - person ? person.name : (setting[:author_name] || _('Unknown')) | 653 | + person = author_by_version(version_number) |
654 | + if version_number | ||
655 | + person ? person.name : _('Unknown') | ||
656 | + else | ||
657 | + person ? person.name : (setting[:author_name] || _('Unknown')) | ||
658 | + end | ||
649 | end | 659 | end |
650 | 660 | ||
651 | def author_url(version_number = nil) | 661 | def author_url(version_number = nil) |
652 | - person = author(version_number) | 662 | + person = author_by_version(version_number) |
653 | person ? person.url : nil | 663 | person ? person.url : nil |
654 | end | 664 | end |
655 | 665 | ||
656 | def author_id(version_number = nil) | 666 | def author_id(version_number = nil) |
657 | - person = author(version_number) | 667 | + person = author_by_version(version_number) |
658 | person ? person.id : nil | 668 | person ? person.id : nil |
659 | end | 669 | end |
660 | 670 | ||
661 | def version_license(version_number = nil) | 671 | def version_license(version_number = nil) |
662 | return license if version_number.nil? | 672 | return license if version_number.nil? |
663 | - profile.environment.licenses.find_by_id(versions.find_by_version(version_number).license_id) | 673 | + profile.environment.licenses.find_by_id(get_version(version_number).license_id) |
664 | end | 674 | end |
665 | 675 | ||
666 | alias :active_record_cache_key :cache_key | 676 | alias :active_record_cache_key :cache_key |
app/models/block.rb
@@ -22,6 +22,10 @@ class Block < ActiveRecord::Base | @@ -22,6 +22,10 @@ class Block < ActiveRecord::Base | ||
22 | false | 22 | false |
23 | end | 23 | end |
24 | 24 | ||
25 | + def get_limit | ||
26 | + [0,limit].max | ||
27 | + end | ||
28 | + | ||
25 | def embed_code | 29 | def embed_code |
26 | me = self | 30 | me = self |
27 | proc do | 31 | proc do |
@@ -188,7 +192,7 @@ class Block < ActiveRecord::Base | @@ -188,7 +192,7 @@ class Block < ActiveRecord::Base | ||
188 | 192 | ||
189 | # Override in your subclasses. | 193 | # Override in your subclasses. |
190 | # Define which events and context should cause the block cache to expire | 194 | # Define which events and context should cause the block cache to expire |
191 | - # Possible events are: :article, :profile, :friendship, :category | 195 | + # Possible events are: :article, :profile, :friendship, :category, :role_assignment |
192 | # Possible contexts are: :profile, :environment | 196 | # Possible contexts are: :profile, :environment |
193 | def self.expire_on | 197 | def self.expire_on |
194 | { | 198 | { |
@@ -230,4 +234,9 @@ class Block < ActiveRecord::Base | @@ -230,4 +234,9 @@ class Block < ActiveRecord::Base | ||
230 | duplicated_block | 234 | duplicated_block |
231 | end | 235 | end |
232 | 236 | ||
237 | + def copy_from(block) | ||
238 | + self.settings = block.settings | ||
239 | + self.position = block.position | ||
240 | + end | ||
241 | + | ||
233 | end | 242 | end |
app/models/box.rb
@@ -28,20 +28,14 @@ class Box < ActiveRecord::Base | @@ -28,20 +28,14 @@ class Box < ActiveRecord::Base | ||
28 | CategoriesBlock, | 28 | CategoriesBlock, |
29 | CommunitiesBlock, | 29 | CommunitiesBlock, |
30 | EnterprisesBlock, | 30 | EnterprisesBlock, |
31 | - # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from | ||
32 | - # the Noosfero core soon, see ActionItem3045 | ||
33 | - EnvironmentStatisticsBlock, | ||
34 | FansBlock, | 31 | FansBlock, |
35 | FavoriteEnterprisesBlock, | 32 | FavoriteEnterprisesBlock, |
36 | FeedReaderBlock, | 33 | FeedReaderBlock, |
37 | - FriendsBlock, | ||
38 | HighlightsBlock, | 34 | HighlightsBlock, |
39 | LinkListBlock, | 35 | LinkListBlock, |
40 | LoginBlock, | 36 | LoginBlock, |
41 | MainBlock, | 37 | MainBlock, |
42 | - MembersBlock, | ||
43 | MyNetworkBlock, | 38 | MyNetworkBlock, |
44 | - PeopleBlock, | ||
45 | ProfileImageBlock, | 39 | ProfileImageBlock, |
46 | RawHTMLBlock, | 40 | RawHTMLBlock, |
47 | RecentDocumentsBlock, | 41 | RecentDocumentsBlock, |
@@ -56,21 +50,15 @@ class Box < ActiveRecord::Base | @@ -56,21 +50,15 @@ class Box < ActiveRecord::Base | ||
56 | CommunitiesBlock, | 50 | CommunitiesBlock, |
57 | DisabledEnterpriseMessageBlock, | 51 | DisabledEnterpriseMessageBlock, |
58 | EnterprisesBlock, | 52 | EnterprisesBlock, |
59 | - # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from | ||
60 | - # the Noosfero core soon, see ActionItem3045 | ||
61 | - EnvironmentStatisticsBlock, | ||
62 | FansBlock, | 53 | FansBlock, |
63 | FavoriteEnterprisesBlock, | 54 | FavoriteEnterprisesBlock, |
64 | FeaturedProductsBlock, | 55 | FeaturedProductsBlock, |
65 | FeedReaderBlock, | 56 | FeedReaderBlock, |
66 | - FriendsBlock, | ||
67 | HighlightsBlock, | 57 | HighlightsBlock, |
68 | LinkListBlock, | 58 | LinkListBlock, |
69 | LocationBlock, | 59 | LocationBlock, |
70 | LoginBlock, | 60 | LoginBlock, |
71 | - MembersBlock, | ||
72 | MyNetworkBlock, | 61 | MyNetworkBlock, |
73 | - PeopleBlock, | ||
74 | ProductsBlock, | 62 | ProductsBlock, |
75 | ProductCategoriesBlock, | 63 | ProductCategoriesBlock, |
76 | ProfileImageBlock, | 64 | ProfileImageBlock, |
app/models/categories_block.rb
@@ -8,6 +8,8 @@ class CategoriesBlock < Block | @@ -8,6 +8,8 @@ class CategoriesBlock < Block | ||
8 | 8 | ||
9 | settings_items :category_types, :type => Array, :default => [] | 9 | settings_items :category_types, :type => Array, :default => [] |
10 | 10 | ||
11 | + attr_accessible :category_types | ||
12 | + | ||
11 | def self.description | 13 | def self.description |
12 | _("Categories Menu") | 14 | _("Categories Menu") |
13 | end | 15 | end |
app/models/category.rb
@@ -14,9 +14,6 @@ class Category < ActiveRecord::Base | @@ -14,9 +14,6 @@ class Category < ActiveRecord::Base | ||
14 | validates_uniqueness_of :slug,:scope => [ :environment_id, :parent_id ], :message => N_('{fn} is already being used by another category.').fix_i18n | 14 | validates_uniqueness_of :slug,:scope => [ :environment_id, :parent_id ], :message => N_('{fn} is already being used by another category.').fix_i18n |
15 | belongs_to :environment | 15 | belongs_to :environment |
16 | 16 | ||
17 | - validates_inclusion_of :display_color, :in => 1..15, :allow_nil => true | ||
18 | - validates_uniqueness_of :display_color, :scope => :environment_id, :if => (lambda { |cat| ! cat.display_color.nil? }), :message => N_('{fn} was already assigned to another category.').fix_i18n | ||
19 | - | ||
20 | # Finds all top level categories for a given environment. | 17 | # Finds all top level categories for a given environment. |
21 | scope :top_level_for, lambda { |environment| | 18 | scope :top_level_for, lambda { |environment| |
22 | {:conditions => ['parent_id is null and environment_id = ?', environment.id ]} | 19 | {:conditions => ['parent_id is null and environment_id = ?', environment.id ]} |
@@ -42,6 +39,13 @@ class Category < ActiveRecord::Base | @@ -42,6 +39,13 @@ class Category < ActiveRecord::Base | ||
42 | 39 | ||
43 | acts_as_having_image | 40 | acts_as_having_image |
44 | 41 | ||
42 | + before_save :normalize_display_color | ||
43 | + | ||
44 | + def normalize_display_color | ||
45 | + display_color.gsub!('#', '') if display_color | ||
46 | + display_color = nil if display_color.blank? | ||
47 | + end | ||
48 | + | ||
45 | scope :from_types, lambda { |types| | 49 | scope :from_types, lambda { |types| |
46 | types.select{ |t| t.blank? }.empty? ? | 50 | types.select{ |t| t.blank? }.empty? ? |
47 | { :conditions => { :type => types } } : | 51 | { :conditions => { :type => types } } : |
@@ -101,4 +105,12 @@ class Category < ActiveRecord::Base | @@ -101,4 +105,12 @@ class Category < ActiveRecord::Base | ||
101 | self.children.find(:all, :conditions => {:display_in_menu => true}).empty? | 105 | self.children.find(:all, :conditions => {:display_in_menu => true}).empty? |
102 | end | 106 | end |
103 | 107 | ||
108 | + def with_color | ||
109 | + if display_color.blank? | ||
110 | + parent.nil? ? nil : parent.with_color | ||
111 | + else | ||
112 | + self | ||
113 | + end | ||
114 | + end | ||
115 | + | ||
104 | end | 116 | end |
app/models/change_password.rb
@@ -2,16 +2,19 @@ class ChangePassword < Task | @@ -2,16 +2,19 @@ class ChangePassword < Task | ||
2 | 2 | ||
3 | attr_accessor :password, :password_confirmation | 3 | attr_accessor :password, :password_confirmation |
4 | 4 | ||
5 | - def self.human_attribute_name(attrib, options = {}) | 5 | + def self.human_attribute_name_with_customization(attrib, options={}) |
6 | case attrib.to_sym | 6 | case attrib.to_sym |
7 | when :password | 7 | when :password |
8 | _('Password') | 8 | _('Password') |
9 | when :password_confirmation | 9 | when :password_confirmation |
10 | _('Password Confirmation') | 10 | _('Password Confirmation') |
11 | else | 11 | else |
12 | - _(self.superclass.human_attribute_name(attrib)) | 12 | + _(self.human_attribute_name_without_customization(attrib)) |
13 | end | 13 | end |
14 | end | 14 | end |
15 | + class << self | ||
16 | + alias_method_chain :human_attribute_name, :customization | ||
17 | + end | ||
15 | 18 | ||
16 | validates_presence_of :requestor | 19 | validates_presence_of :requestor |
17 | 20 |
app/models/comment.rb
@@ -111,14 +111,17 @@ class Comment < ActiveRecord::Base | @@ -111,14 +111,17 @@ class Comment < ActiveRecord::Base | ||
111 | include Noosfero::Plugin::HotSpot | 111 | include Noosfero::Plugin::HotSpot |
112 | 112 | ||
113 | include Spammable | 113 | include Spammable |
114 | + include CacheCounterHelper | ||
114 | 115 | ||
115 | def after_spam! | 116 | def after_spam! |
116 | SpammerLogger.log(ip_address, self) | 117 | SpammerLogger.log(ip_address, self) |
117 | Delayed::Job.enqueue(CommentHandler.new(self.id, :marked_as_spam)) | 118 | Delayed::Job.enqueue(CommentHandler.new(self.id, :marked_as_spam)) |
119 | + update_cache_counter(:spam_comments_count, source, 1) if source.kind_of?(Article) | ||
118 | end | 120 | end |
119 | 121 | ||
120 | def after_ham! | 122 | def after_ham! |
121 | Delayed::Job.enqueue(CommentHandler.new(self.id, :marked_as_ham)) | 123 | Delayed::Job.enqueue(CommentHandler.new(self.id, :marked_as_ham)) |
124 | + update_cache_counter(:spam_comments_count, source, -1) if source.kind_of?(Article) | ||
122 | end | 125 | end |
123 | 126 | ||
124 | def verify_and_notify | 127 | def verify_and_notify |
app/models/community.rb
1 | class Community < Organization | 1 | class Community < Organization |
2 | 2 | ||
3 | - attr_accessible :accessor_id, :accessor_type, :role_id, :resource_id, :resource_type | 3 | + attr_accessible :accessor_id, :accessor_type, :role_id, :resource_id, :resource_type, :address_reference, :district, :tag_list, :language |
4 | after_destroy :check_invite_member_for_destroy | 4 | after_destroy :check_invite_member_for_destroy |
5 | 5 | ||
6 | def self.type_name | 6 | def self.type_name |
@@ -50,16 +50,6 @@ class Community < Organization | @@ -50,16 +50,6 @@ class Community < Organization | ||
50 | super + FIELDS | 50 | super + FIELDS |
51 | end | 51 | end |
52 | 52 | ||
53 | - validate :presence_of_required_fieds | ||
54 | - | ||
55 | - def presence_of_required_fieds | ||
56 | - self.required_fields.each do |field| | ||
57 | - if self.send(field).blank? | ||
58 | - self.errors.add_on_blank(field) | ||
59 | - end | ||
60 | - end | ||
61 | - end | ||
62 | - | ||
63 | def active_fields | 53 | def active_fields |
64 | environment ? environment.active_community_fields : [] | 54 | environment ? environment.active_community_fields : [] |
65 | end | 55 | end |
@@ -85,10 +75,6 @@ class Community < Organization | @@ -85,10 +75,6 @@ class Community < Organization | ||
85 | recent_documents(limit, ["articles.type != ? AND articles.highlighted = ?", 'Folder', highlight]) | 75 | recent_documents(limit, ["articles.type != ? AND articles.highlighted = ?", 'Folder', highlight]) |
86 | end | 76 | end |
87 | 77 | ||
88 | - def blocks_to_expire_cache | ||
89 | - [MembersBlock] | ||
90 | - end | ||
91 | - | ||
92 | def each_member(offset=0) | 78 | def each_member(offset=0) |
93 | while member = self.members.first(:order => :id, :offset => offset) | 79 | while member = self.members.first(:order => :id, :offset => offset) |
94 | yield member | 80 | yield member |
app/models/domain.rb
@@ -2,7 +2,7 @@ require 'noosfero/multi_tenancy' | @@ -2,7 +2,7 @@ require 'noosfero/multi_tenancy' | ||
2 | 2 | ||
3 | class Domain < ActiveRecord::Base | 3 | class Domain < ActiveRecord::Base |
4 | 4 | ||
5 | - attr_accessible :name, :owner | 5 | + attr_accessible :name, :owner, :is_default |
6 | 6 | ||
7 | # relationships | 7 | # relationships |
8 | ############### | 8 | ############### |
app/models/enterprise.rb
@@ -2,6 +2,8 @@ | @@ -2,6 +2,8 @@ | ||
2 | # only enterprises can offer products and services. | 2 | # only enterprises can offer products and services. |
3 | class Enterprise < Organization | 3 | class Enterprise < Organization |
4 | 4 | ||
5 | + attr_accessible :business_name, :address_reference, :district, :tag_list, :organization_website, :historic_and_current_context, :activities_short_description, :products_per_catalog_page | ||
6 | + | ||
5 | SEARCH_DISPLAYS += %w[map full] | 7 | SEARCH_DISPLAYS += %w[map full] |
6 | 8 | ||
7 | def self.type_name | 9 | def self.type_name |
@@ -23,7 +25,10 @@ class Enterprise < Organization | @@ -23,7 +25,10 @@ class Enterprise < Organization | ||
23 | N_('Organization website'); N_('Historic and current context'); N_('Activities short description'); N_('City'); N_('State'); N_('Country'); N_('ZIP code') | 25 | N_('Organization website'); N_('Historic and current context'); N_('Activities short description'); N_('City'); N_('State'); N_('Country'); N_('ZIP code') |
24 | 26 | ||
25 | settings_items :organization_website, :historic_and_current_context, :activities_short_description | 27 | settings_items :organization_website, :historic_and_current_context, :activities_short_description |
28 | + | ||
26 | settings_items :products_per_catalog_page, :type => :integer, :default => 6 | 29 | settings_items :products_per_catalog_page, :type => :integer, :default => 6 |
30 | + alias_method :products_per_catalog_page_before_type_cast, :products_per_catalog_page | ||
31 | + validates_numericality_of :products_per_catalog_page, :allow_nil => true, :greater_than => 0 | ||
27 | 32 | ||
28 | extend SetProfileRegionFromCityState::ClassMethods | 33 | extend SetProfileRegionFromCityState::ClassMethods |
29 | set_profile_region_from_city_state | 34 | set_profile_region_from_city_state |
@@ -54,16 +59,6 @@ class Enterprise < Organization | @@ -54,16 +59,6 @@ class Enterprise < Organization | ||
54 | super + FIELDS | 59 | super + FIELDS |
55 | end | 60 | end |
56 | 61 | ||
57 | - validate :presence_of_required_fieds | ||
58 | - | ||
59 | - def presence_of_required_fieds | ||
60 | - self.required_fields.each do |field| | ||
61 | - if self.send(field).blank? | ||
62 | - self.errors.add_on_blank(field) | ||
63 | - end | ||
64 | - end | ||
65 | - end | ||
66 | - | ||
67 | def active_fields | 62 | def active_fields |
68 | environment ? environment.active_enterprise_fields : [] | 63 | environment ? environment.active_enterprise_fields : [] |
69 | end | 64 | end |
app/models/environment.rb
@@ -3,7 +3,7 @@ | @@ -3,7 +3,7 @@ | ||
3 | # domains. | 3 | # domains. |
4 | class Environment < ActiveRecord::Base | 4 | class Environment < ActiveRecord::Base |
5 | 5 | ||
6 | - attr_accessible :name, :is_default, :signup_welcome_text_subject, :signup_welcome_text_body, :terms_of_use, :message_for_disabled_enterprise, :news_amount_by_folder, :default_language, :languages, :description, :organization_approval_method, :enabled_plugins, :enabled_features, :redirection_after_login, :redirection_after_signup, :contact_email, :theme, :reports_lower_bound | 6 | + attr_accessible :name, :is_default, :signup_welcome_text_subject, :signup_welcome_text_body, :terms_of_use, :message_for_disabled_enterprise, :news_amount_by_folder, :default_language, :languages, :description, :organization_approval_method, :enabled_plugins, :enabled_features, :redirection_after_login, :redirection_after_signup, :contact_email, :theme, :reports_lower_bound, :noreply_email, :signup_welcome_screen_body, :members_whitelist_enabled, :members_whitelist |
7 | 7 | ||
8 | has_many :users | 8 | has_many :users |
9 | 9 | ||
@@ -124,6 +124,7 @@ class Environment < ActiveRecord::Base | @@ -124,6 +124,7 @@ class Environment < ActiveRecord::Base | ||
124 | 'organizations_are_moderated_by_default' => _("Organizations have moderated publication by default"), | 124 | 'organizations_are_moderated_by_default' => _("Organizations have moderated publication by default"), |
125 | 'enable_organization_url_change' => _("Allow organizations to change their URL"), | 125 | 'enable_organization_url_change' => _("Allow organizations to change their URL"), |
126 | 'admin_must_approve_new_communities' => _("Admin must approve creation of communities"), | 126 | 'admin_must_approve_new_communities' => _("Admin must approve creation of communities"), |
127 | + 'admin_must_approve_new_users' => _("Admin must approve registration of new users"), | ||
127 | 'show_balloon_with_profile_links_when_clicked' => _('Show a balloon with profile links when a profile image is clicked'), | 128 | 'show_balloon_with_profile_links_when_clicked' => _('Show a balloon with profile links when a profile image is clicked'), |
128 | 'xmpp_chat' => _('XMPP/Jabber based chat'), | 129 | 'xmpp_chat' => _('XMPP/Jabber based chat'), |
129 | 'show_zoom_button_on_article_images' => _('Show a zoom link on all article images'), | 130 | 'show_zoom_button_on_article_images' => _('Show a zoom link on all article images'), |
@@ -132,7 +133,8 @@ class Environment < ActiveRecord::Base | @@ -132,7 +133,8 @@ class Environment < ActiveRecord::Base | ||
132 | 'send_welcome_email_to_new_users' => _('Send welcome e-mail to new users'), | 133 | 'send_welcome_email_to_new_users' => _('Send welcome e-mail to new users'), |
133 | 'allow_change_of_redirection_after_login' => _('Allow users to set the page to redirect after login'), | 134 | 'allow_change_of_redirection_after_login' => _('Allow users to set the page to redirect after login'), |
134 | 'display_my_communities_on_user_menu' => _('Display on menu the list of communities the user can manage'), | 135 | 'display_my_communities_on_user_menu' => _('Display on menu the list of communities the user can manage'), |
135 | - 'display_my_enterprises_on_user_menu' => _('Display on menu the list of enterprises the user can manage') | 136 | + 'display_my_enterprises_on_user_menu' => _('Display on menu the list of enterprises the user can manage'), |
137 | + 'restrict_to_members' => _('Show content only to members') | ||
136 | } | 138 | } |
137 | end | 139 | end |
138 | 140 | ||
@@ -175,14 +177,10 @@ class Environment < ActiveRecord::Base | @@ -175,14 +177,10 @@ class Environment < ActiveRecord::Base | ||
175 | 177 | ||
176 | # "left" area | 178 | # "left" area |
177 | env.boxes[1].blocks << LoginBlock.new | 179 | env.boxes[1].blocks << LoginBlock.new |
178 | - # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from | ||
179 | - # the Noosfero core soon, see ActionItem3045 | ||
180 | - env.boxes[1].blocks << EnvironmentStatisticsBlock.new | ||
181 | env.boxes[1].blocks << RecentDocumentsBlock.new | 180 | env.boxes[1].blocks << RecentDocumentsBlock.new |
182 | 181 | ||
183 | # "right" area | 182 | # "right" area |
184 | env.boxes[2].blocks << CommunitiesBlock.new(:limit => 6) | 183 | env.boxes[2].blocks << CommunitiesBlock.new(:limit => 6) |
185 | - env.boxes[2].blocks << PeopleBlock.new(:limit => 6) | ||
186 | end | 184 | end |
187 | 185 | ||
188 | # One Environment can be reached by many domains | 186 | # One Environment can be reached by many domains |
@@ -287,7 +285,7 @@ class Environment < ActiveRecord::Base | @@ -287,7 +285,7 @@ class Environment < ActiveRecord::Base | ||
287 | www.youtube.com | 285 | www.youtube.com |
288 | ] + ('a' .. 'z').map{|i| "#{i}.yimg.com"} | 286 | ] + ('a' .. 'z').map{|i| "#{i}.yimg.com"} |
289 | 287 | ||
290 | - settings_items :enabled_plugins, :type => Array, :default => [] | 288 | + settings_items :enabled_plugins, :type => Array, :default => Noosfero::Plugin.available_plugin_names |
291 | 289 | ||
292 | settings_items :search_hints, :type => Hash, :default => {} | 290 | settings_items :search_hints, :type => Hash, :default => {} |
293 | 291 | ||
@@ -298,6 +296,23 @@ class Environment < ActiveRecord::Base | @@ -298,6 +296,23 @@ class Environment < ActiveRecord::Base | ||
298 | settings_items :access_control_allow_origin, :type => Array, :default => [] | 296 | settings_items :access_control_allow_origin, :type => Array, :default => [] |
299 | settings_items :access_control_allow_methods, :type => String | 297 | settings_items :access_control_allow_methods, :type => String |
300 | 298 | ||
299 | + settings_items :signup_welcome_screen_body, :type => String | ||
300 | + | ||
301 | + def has_custom_welcome_screen? | ||
302 | + settings[:signup_welcome_screen_body].present? | ||
303 | + end | ||
304 | + | ||
305 | + settings_items :members_whitelist_enabled, :type => :boolean, :default => false | ||
306 | + settings_items :members_whitelist, :type => Array, :default => [] | ||
307 | + | ||
308 | + def in_whitelist?(person) | ||
309 | + !members_whitelist_enabled || members_whitelist.include?(person.id) | ||
310 | + end | ||
311 | + | ||
312 | + def members_whitelist=(members) | ||
313 | + settings[:members_whitelist] = members.split(',').map(&:to_i) | ||
314 | + end | ||
315 | + | ||
301 | def news_amount_by_folder=(amount) | 316 | def news_amount_by_folder=(amount) |
302 | settings[:news_amount_by_folder] = amount.to_i | 317 | settings[:news_amount_by_folder] = amount.to_i |
303 | end | 318 | end |
@@ -637,10 +652,15 @@ class Environment < ActiveRecord::Base | @@ -637,10 +652,15 @@ class Environment < ActiveRecord::Base | ||
637 | domain | 652 | domain |
638 | end | 653 | end |
639 | 654 | ||
655 | + def admin_url | ||
656 | + { :controller => 'admin_panel', :action => 'index' } | ||
657 | + end | ||
658 | + | ||
640 | def top_url | 659 | def top_url |
641 | url = 'http://' | 660 | url = 'http://' |
642 | url << (Noosfero.url_options.key?(:host) ? Noosfero.url_options[:host] : default_hostname) | 661 | url << (Noosfero.url_options.key?(:host) ? Noosfero.url_options[:host] : default_hostname) |
643 | url << ':' << Noosfero.url_options[:port].to_s if Noosfero.url_options.key?(:port) | 662 | url << ':' << Noosfero.url_options[:port].to_s if Noosfero.url_options.key?(:port) |
663 | + url << Noosfero.root('') | ||
644 | url | 664 | url |
645 | end | 665 | end |
646 | 666 | ||
@@ -785,7 +805,7 @@ class Environment < ActiveRecord::Base | @@ -785,7 +805,7 @@ class Environment < ActiveRecord::Base | ||
785 | end | 805 | end |
786 | 806 | ||
787 | def notification_emails | 807 | def notification_emails |
788 | - [noreply_email.blank? ? nil : noreply_email].compact + admins.map(&:email) | 808 | + [contact_email].select(&:present?) + admins.map(&:email) |
789 | end | 809 | end |
790 | 810 | ||
791 | after_create :create_templates | 811 | after_create :create_templates |
app/models/environment_statistics_block.rb
@@ -1,33 +0,0 @@ | @@ -1,33 +0,0 @@ | ||
1 | -# TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from | ||
2 | -# the Noosfero core soon, see ActionItem3045 | ||
3 | - | ||
4 | -class EnvironmentStatisticsBlock < Block | ||
5 | - | ||
6 | - def self.description | ||
7 | - _('Environment stastistics (DEPRECATED)') | ||
8 | - end | ||
9 | - | ||
10 | - def default_title | ||
11 | - _('Statistics for %s') % owner.name | ||
12 | - end | ||
13 | - | ||
14 | - def help | ||
15 | - _('This block presents some statistics about your environment.') | ||
16 | - end | ||
17 | - | ||
18 | - def content(args={}) | ||
19 | - users = owner.people.visible.count | ||
20 | - enterprises = owner.enterprises.visible.count | ||
21 | - communities = owner.communities.visible.count | ||
22 | - | ||
23 | - info = [] | ||
24 | - info << (n_('One user', '%{num} users', users) % { :num => users }) | ||
25 | - unless owner.enabled?('disable_asset_enterprises') | ||
26 | - info << (n_('One enterprise', '%{num} enterprises', enterprises) % { :num => enterprises }) | ||
27 | - end | ||
28 | - info << (n_('One community', '%{num} communities', communities) % { :num => communities }) | ||
29 | - | ||
30 | - block_title(title) + content_tag('ul', info.map {|item| content_tag('li', item) }.join("\n")) | ||
31 | - end | ||
32 | - | ||
33 | -end |
app/models/external_feed.rb
@@ -13,6 +13,7 @@ class ExternalFeed < ActiveRecord::Base | @@ -13,6 +13,7 @@ class ExternalFeed < ActiveRecord::Base | ||
13 | attr_accessible :address, :enabled | 13 | attr_accessible :address, :enabled |
14 | 14 | ||
15 | def add_item(title, link, date, content) | 15 | def add_item(title, link, date, content) |
16 | + return if content.blank? | ||
16 | doc = Hpricot(content) | 17 | doc = Hpricot(content) |
17 | doc.search('*').each do |p| | 18 | doc.search('*').each do |p| |
18 | if p.instance_of? Hpricot::Elem | 19 | if p.instance_of? Hpricot::Elem |
@@ -30,6 +31,7 @@ class ExternalFeed < ActiveRecord::Base | @@ -30,6 +31,7 @@ class ExternalFeed < ActiveRecord::Base | ||
30 | article.source = link | 31 | article.source = link |
31 | article.profile = blog.profile | 32 | article.profile = blog.profile |
32 | article.parent = blog | 33 | article.parent = blog |
34 | + article.author_name = self.feed_title | ||
33 | unless blog.children.exists?(:slug => article.slug) | 35 | unless blog.children.exists?(:slug => article.slug) |
34 | article.save! | 36 | article.save! |
35 | article.delay.create_activity | 37 | article.delay.create_activity |
app/models/featured_products_block.rb
1 | class FeaturedProductsBlock < Block | 1 | class FeaturedProductsBlock < Block |
2 | 2 | ||
3 | + attr_accessible :product_ids, :groups_of, :speed, :reflect | ||
4 | + | ||
3 | settings_items :product_ids, :type => Array, :default => [] | 5 | settings_items :product_ids, :type => Array, :default => [] |
4 | settings_items :groups_of, :type => :integer, :default => 3 | 6 | settings_items :groups_of, :type => :integer, :default => 3 |
5 | settings_items :speed, :type => :integer, :default => 1000 | 7 | settings_items :speed, :type => :integer, :default => 1000 |
app/models/feed_reader_block.rb
app/models/forum.rb
@@ -3,7 +3,7 @@ class Forum < Folder | @@ -3,7 +3,7 @@ class Forum < Folder | ||
3 | acts_as_having_posts :order => 'updated_at DESC' | 3 | acts_as_having_posts :order => 'updated_at DESC' |
4 | include PostsLimit | 4 | include PostsLimit |
5 | 5 | ||
6 | - attr_accessible :has_terms_of_use, :terms_of_use | 6 | + attr_accessible :has_terms_of_use, :terms_of_use, :allows_members_to_create_topics |
7 | 7 | ||
8 | settings_items :terms_of_use, :type => :string, :default => "" | 8 | settings_items :terms_of_use, :type => :string, :default => "" |
9 | settings_items :has_terms_of_use, :type => :boolean, :default => false | 9 | settings_items :has_terms_of_use, :type => :boolean, :default => false |
app/models/friends_block.rb
@@ -1,26 +0,0 @@ | @@ -1,26 +0,0 @@ | ||
1 | -class FriendsBlock < ProfileListBlock | ||
2 | - | ||
3 | - def self.description | ||
4 | - _('Friends') | ||
5 | - end | ||
6 | - | ||
7 | - def default_title | ||
8 | - n_('{#} friend', '{#} friends', profile_count) | ||
9 | - end | ||
10 | - | ||
11 | - def help | ||
12 | - _('This block displays your friends.') | ||
13 | - end | ||
14 | - | ||
15 | - def footer | ||
16 | - owner_id = owner.identifier | ||
17 | - proc do | ||
18 | - link_to s_('friends|View all'), :profile => owner_id, :controller => 'profile', :action => 'friends' | ||
19 | - end | ||
20 | - end | ||
21 | - | ||
22 | - def profiles | ||
23 | - owner.friends | ||
24 | - end | ||
25 | - | ||
26 | -end |
app/models/friendship.rb
@@ -15,4 +15,9 @@ class Friendship < ActiveRecord::Base | @@ -15,4 +15,9 @@ class Friendship < ActiveRecord::Base | ||
15 | Friendship.update_cache_counter(:friends_count, friendship.person, -1) | 15 | Friendship.update_cache_counter(:friends_count, friendship.person, -1) |
16 | Friendship.update_cache_counter(:friends_count, friendship.friend, -1) | 16 | Friendship.update_cache_counter(:friends_count, friendship.friend, -1) |
17 | end | 17 | end |
18 | + | ||
19 | + def self.remove_friendship(person1, person2) | ||
20 | + person1.remove_friend(person2) | ||
21 | + person2.remove_friend(person1) | ||
22 | + end | ||
18 | end | 23 | end |
app/models/highlights_block.rb
1 | class HighlightsBlock < Block | 1 | class HighlightsBlock < Block |
2 | 2 | ||
3 | - attr_accessible :images | 3 | + attr_accessible :images, :interval, :shuffle, :navigation |
4 | 4 | ||
5 | settings_items :images, :type => Array, :default => [] | 5 | settings_items :images, :type => Array, :default => [] |
6 | settings_items :interval, :type => 'integer', :default => 4 | 6 | settings_items :interval, :type => 'integer', :default => 4 |
app/models/image.rb
app/models/input.rb
1 | class Input < ActiveRecord::Base | 1 | class Input < ActiveRecord::Base |
2 | 2 | ||
3 | - attr_accessible :product, :product_category | 3 | + attr_accessible :product, :product_category, :product_category_id, :amount_used, :unit_id, :price_per_unit, :relevant_to_price |
4 | 4 | ||
5 | belongs_to :product | 5 | belongs_to :product |
6 | belongs_to :product_category | 6 | belongs_to :product_category |
app/models/link_list_block.rb
@@ -78,16 +78,17 @@ class LinkListBlock < Block | @@ -78,16 +78,17 @@ class LinkListBlock < Block | ||
78 | address | 78 | address |
79 | end | 79 | end |
80 | if add !~ /^[a-z]+:\/\// && add !~ /^\// | 80 | if add !~ /^[a-z]+:\/\// && add !~ /^\// |
81 | - 'http://' + add | 81 | + '//' + add |
82 | else | 82 | else |
83 | + if root = Noosfero.root | ||
84 | + if !add.starts_with?(root) | ||
85 | + add = root + add | ||
86 | + end | ||
87 | + end | ||
83 | add | 88 | add |
84 | end | 89 | end |
85 | end | 90 | end |
86 | 91 | ||
87 | - def editable? | ||
88 | - true | ||
89 | - end | ||
90 | - | ||
91 | def icons_options | 92 | def icons_options |
92 | ICONS.map do |i| | 93 | ICONS.map do |i| |
93 | "<span title=\"#{i[1]}\" class=\"icon-#{i[0]}\" onclick=\"changeIcon(this, '#{i[0]}')\"></span>".html_safe | 94 | "<span title=\"#{i[1]}\" class=\"icon-#{i[0]}\" onclick=\"changeIcon(this, '#{i[0]}')\"></span>".html_safe |
@@ -100,4 +101,5 @@ class LinkListBlock < Block | @@ -100,4 +101,5 @@ class LinkListBlock < Block | ||
100 | sanitizer = HTML::WhiteListSanitizer.new | 101 | sanitizer = HTML::WhiteListSanitizer.new |
101 | sanitizer.sanitize(text) | 102 | sanitizer.sanitize(text) |
102 | end | 103 | end |
104 | + | ||
103 | end | 105 | end |
app/models/location_block.rb
1 | class LocationBlock < Block | 1 | class LocationBlock < Block |
2 | 2 | ||
3 | + attr_accessible :zoom, :map_type | ||
4 | + | ||
3 | settings_items :zoom, :type => :integer, :default => 4 | 5 | settings_items :zoom, :type => :integer, :default => 4 |
4 | settings_items :map_type, :type => :string, :default => 'roadmap' | 6 | settings_items :map_type, :type => :string, :default => 'roadmap' |
5 | 7 |
app/models/main_block.rb
app/models/members_block.rb
@@ -1,52 +0,0 @@ | @@ -1,52 +0,0 @@ | ||
1 | -class MembersBlock < ProfileListBlock | ||
2 | - settings_items :show_join_leave_button, :type => :boolean, :default => false | ||
3 | - | ||
4 | - attr_accessible :show_join_leave_button | ||
5 | - | ||
6 | - def self.description | ||
7 | - _('Members') | ||
8 | - end | ||
9 | - | ||
10 | - def default_title | ||
11 | - _('{#} members') | ||
12 | - end | ||
13 | - | ||
14 | - def help | ||
15 | - _('This block presents the members of a collective.') | ||
16 | - end | ||
17 | - | ||
18 | - def footer | ||
19 | - profile = self.owner | ||
20 | - s = show_join_leave_button | ||
21 | - | ||
22 | - proc do | ||
23 | - render :file => 'blocks/members', :locals => { :profile => profile, :show_join_leave_button => s} | ||
24 | - end | ||
25 | - end | ||
26 | - | ||
27 | - def profiles | ||
28 | - owner.members | ||
29 | - end | ||
30 | - | ||
31 | - def extra_option | ||
32 | - data = { | ||
33 | - :human_name => _("Show join leave button"), | ||
34 | - :name => 'block[show_join_leave_button]', | ||
35 | - :value => true, | ||
36 | - :checked => show_join_leave_button, | ||
37 | - :options => {} | ||
38 | - } | ||
39 | - end | ||
40 | - | ||
41 | - def cache_key(language='en', user=nil) | ||
42 | - logged = '' | ||
43 | - if user | ||
44 | - logged += '-logged-in' | ||
45 | - if user.is_member_of? self.owner | ||
46 | - logged += '-member' | ||
47 | - end | ||
48 | - end | ||
49 | - super + logged | ||
50 | - end | ||
51 | - | ||
52 | -end |
@@ -0,0 +1,59 @@ | @@ -0,0 +1,59 @@ | ||
1 | +class ModerateUserRegistration < Task | ||
2 | + | ||
3 | + settings_items :user_id, :type => String | ||
4 | + settings_items :name, :type => String | ||
5 | + settings_items :author_name, :type => String | ||
6 | + settings_items :email, :type => String | ||
7 | + | ||
8 | + after_create :schedule_spam_checking | ||
9 | + | ||
10 | + alias :environment :target | ||
11 | + alias :environment= :target= | ||
12 | + | ||
13 | + def schedule_spam_checking | ||
14 | + self.delay.check_for_spam | ||
15 | + end | ||
16 | + | ||
17 | + include Noosfero::Plugin::HotSpot | ||
18 | + | ||
19 | + def sender | ||
20 | + "#{name} (#{email})" | ||
21 | + end | ||
22 | + | ||
23 | + def perform | ||
24 | + user=environment.users.find_by_id(user_id) | ||
25 | + user.activate | ||
26 | + end | ||
27 | + | ||
28 | + def title | ||
29 | + _("New user") | ||
30 | + end | ||
31 | + | ||
32 | + def subject | ||
33 | + name | ||
34 | + end | ||
35 | + | ||
36 | + def information | ||
37 | + { :message => _('%{sender} wants to register.'), | ||
38 | + :variables => {:sender => sender} } | ||
39 | + end | ||
40 | + | ||
41 | + def icon | ||
42 | + result = {:type => :defined_image, :src => '/images/icons-app/person-minor.png', :name => name} | ||
43 | + end | ||
44 | + | ||
45 | + def target_notification_description | ||
46 | + _('%{sender} tried to register.') % | ||
47 | + {:sender => sender} | ||
48 | + end | ||
49 | + | ||
50 | + def target_notification_message | ||
51 | + target_notification_description + "\n\n" + | ||
52 | + _('You need to login on %{system} in order to approve or reject this user.') % { :environment => self.environment } | ||
53 | + end | ||
54 | + | ||
55 | + def target_notification_message | ||
56 | + _("User \"%{user}\" just requested to register. You have to approve or reject it through the \"Pending Validations\" section in your control panel.\n") % { :user => self.name } | ||
57 | + end | ||
58 | + | ||
59 | +end | ||
0 | \ No newline at end of file | 60 | \ No newline at end of file |
app/models/organization.rb
@@ -30,6 +30,16 @@ class Organization < Profile | @@ -30,6 +30,16 @@ class Organization < Profile | ||
30 | 30 | ||
31 | scope :more_popular, :order => 'members_count DESC' | 31 | scope :more_popular, :order => 'members_count DESC' |
32 | 32 | ||
33 | + validate :presence_of_required_fieds, :unless => :is_template | ||
34 | + | ||
35 | + def presence_of_required_fieds | ||
36 | + self.required_fields.each do |field| | ||
37 | + if self.send(field).blank? | ||
38 | + self.errors.add_on_blank(field) | ||
39 | + end | ||
40 | + end | ||
41 | + end | ||
42 | + | ||
33 | def validation_methodology | 43 | def validation_methodology |
34 | self.validation_info ? self.validation_info.validation_methodology : nil | 44 | self.validation_info ? self.validation_info.validation_methodology : nil |
35 | end | 45 | end |
@@ -123,7 +133,7 @@ class Organization < Profile | @@ -123,7 +133,7 @@ class Organization < Profile | ||
123 | [ | 133 | [ |
124 | [MainBlock.new], | 134 | [MainBlock.new], |
125 | [ProfileImageBlock.new, LinkListBlock.new(:links => links)], | 135 | [ProfileImageBlock.new, LinkListBlock.new(:links => links)], |
126 | - [MembersBlock.new, RecentDocumentsBlock.new] | 136 | + [RecentDocumentsBlock.new] |
127 | ] | 137 | ] |
128 | end | 138 | end |
129 | 139 | ||
@@ -135,7 +145,11 @@ class Organization < Profile | @@ -135,7 +145,11 @@ class Organization < Profile | ||
135 | end | 145 | end |
136 | 146 | ||
137 | def notification_emails | 147 | def notification_emails |
138 | - [contact_email.blank? ? nil : contact_email].compact + admins.map(&:email) | 148 | + emails = [contact_email].select(&:present?) + admins.map(&:email) |
149 | + if emails.empty? | ||
150 | + emails << environment.contact_email | ||
151 | + end | ||
152 | + emails | ||
139 | end | 153 | end |
140 | 154 | ||
141 | def already_request_membership?(person) | 155 | def already_request_membership?(person) |
app/models/people_block.rb
@@ -1,25 +0,0 @@ | @@ -1,25 +0,0 @@ | ||
1 | -class PeopleBlock < ProfileListBlock | ||
2 | - | ||
3 | - def default_title | ||
4 | - _('People') | ||
5 | - end | ||
6 | - | ||
7 | - def help | ||
8 | - _('Clicking a person takes you to his/her homepage') | ||
9 | - end | ||
10 | - | ||
11 | - def self.description | ||
12 | - _('Random people') | ||
13 | - end | ||
14 | - | ||
15 | - def profiles | ||
16 | - owner.people | ||
17 | - end | ||
18 | - | ||
19 | - def footer | ||
20 | - lambda do |context| | ||
21 | - link_to _('View all'), :controller => 'search', :action => 'people' | ||
22 | - end | ||
23 | - end | ||
24 | - | ||
25 | -end |
app/models/person.rb
1 | # A person is the profile of an user holding all relationships with the rest of the system | 1 | # A person is the profile of an user holding all relationships with the rest of the system |
2 | class Person < Profile | 2 | class Person < Profile |
3 | 3 | ||
4 | - attr_accessible :organization, :contact_information, :sex, :birth_date | 4 | + attr_accessible :organization, :contact_information, :sex, :birth_date, :cell_phone, :comercial_phone, :jabber_id, :personal_website, :nationality, :address_reference, :district, :schooling, :schooling_status, :formation, :custom_formation, :area_of_study, :custom_area_of_study, :professional_activity, :organization_website |
5 | 5 | ||
6 | SEARCH_FILTERS += %w[ | 6 | SEARCH_FILTERS += %w[ |
7 | more_popular | 7 | more_popular |
@@ -161,7 +161,7 @@ class Person < Profile | @@ -161,7 +161,7 @@ class Person < Profile | ||
161 | FIELDS | 161 | FIELDS |
162 | end | 162 | end |
163 | 163 | ||
164 | - validate :presence_of_required_fields | 164 | + validate :presence_of_required_fields, :unless => :is_template |
165 | 165 | ||
166 | def presence_of_required_fields | 166 | def presence_of_required_fields |
167 | self.required_fields.each do |field| | 167 | self.required_fields.each do |field| |
@@ -269,7 +269,7 @@ class Person < Profile | @@ -269,7 +269,7 @@ class Person < Profile | ||
269 | [ | 269 | [ |
270 | [MainBlock.new], | 270 | [MainBlock.new], |
271 | [ProfileImageBlock.new(:show_name => true), LinkListBlock.new(:links => links), RecentDocumentsBlock.new], | 271 | [ProfileImageBlock.new(:show_name => true), LinkListBlock.new(:links => links), RecentDocumentsBlock.new], |
272 | - [FriendsBlock.new, CommunitiesBlock.new] | 272 | + [CommunitiesBlock.new] |
273 | ] | 273 | ] |
274 | end | 274 | end |
275 | 275 |
app/models/person_notifier.rb
@@ -82,7 +82,7 @@ class PersonNotifier | @@ -82,7 +82,7 @@ class PersonNotifier | ||
82 | @url = @profile.environment.top_url | 82 | @url = @profile.environment.top_url |
83 | mail( | 83 | mail( |
84 | content_type: "text/html", | 84 | content_type: "text/html", |
85 | - from: "#{@profile.environment.name} <#{@profile.environment.contact_email}>", | 85 | + from: "#{@profile.environment.name} <#{@profile.environment.noreply_email}>", |
86 | to: @profile.email, | 86 | to: @profile.email, |
87 | subject: _("[%s] Network Activity") % [@profile.environment.name] | 87 | subject: _("[%s] Network Activity") % [@profile.environment.name] |
88 | ) | 88 | ) |
app/models/product.rb
@@ -11,7 +11,7 @@ class Product < ActiveRecord::Base | @@ -11,7 +11,7 @@ class Product < ActiveRecord::Base | ||
11 | 11 | ||
12 | SEARCH_DISPLAYS = %w[map full] | 12 | SEARCH_DISPLAYS = %w[map full] |
13 | 13 | ||
14 | - attr_accessible :name, :product_category, :highlighted, :price, :enterprise, :image_builder, :description, :available, :qualifiers | 14 | + attr_accessible :name, :product_category, :highlighted, :price, :enterprise, :image_builder, :description, :available, :qualifiers, :unit_id, :discount, :inputs |
15 | 15 | ||
16 | def self.default_search_display | 16 | def self.default_search_display |
17 | 'full' | 17 | 'full' |
app/models/product_categories_block.rb
@@ -17,7 +17,7 @@ class ProductCategoriesBlock < Block | @@ -17,7 +17,7 @@ class ProductCategoriesBlock < Block | ||
17 | profile = owner | 17 | profile = owner |
18 | proc do | 18 | proc do |
19 | if @categories.nil? or @categories.length == 0 | 19 | if @categories.nil? or @categories.length == 0 |
20 | - categories = ProductCategory.on_level().order(:name) | 20 | + categories = ProductCategory.on_level(nil).order(:name) |
21 | if @categories and @categories.length == 0 | 21 | if @categories and @categories.length == 0 |
22 | notice = _('There are no sub-categories for %s') % @category.name | 22 | notice = _('There are no sub-categories for %s') % @category.name |
23 | end | 23 | end |
@@ -33,7 +33,7 @@ class ProductCategoriesBlock < Block | @@ -33,7 +33,7 @@ class ProductCategoriesBlock < Block | ||
33 | end | 33 | end |
34 | end | 34 | end |
35 | 35 | ||
36 | - DISPLAY_OPTIONS['catalog_only'] = _('Only on the catalog') | 36 | + DISPLAY_OPTIONS = DISPLAY_OPTIONS.merge('catalog_only' => _('Only on the catalog')) |
37 | 37 | ||
38 | def display | 38 | def display |
39 | settings[:display].nil? ? 'catalog_only' : super | 39 | settings[:display].nil? ? 'catalog_only' : super |
app/models/products_block.rb
@@ -49,17 +49,10 @@ class ProductsBlock < Block | @@ -49,17 +49,10 @@ class ProductsBlock < Block | ||
49 | 49 | ||
50 | def products(reload = false) | 50 | def products(reload = false) |
51 | if product_ids.blank? | 51 | if product_ids.blank? |
52 | - products_list = owner.products(reload) | ||
53 | - result = [] | ||
54 | - [4, products_list.size].min.times do | ||
55 | - p = products_list.sample | ||
56 | - result << p | ||
57 | - products_list -= [p] | ||
58 | - end | ||
59 | - result | 52 | + owner.products.order('RANDOM()').limit([4,owner.products.count].min) |
60 | else | 53 | else |
61 | - product_ids.map {|item| owner.products.find(item) } | ||
62 | - end | 54 | + owner.products.where(:id => product_ids) |
55 | + end.compact | ||
63 | end | 56 | end |
64 | 57 | ||
65 | end | 58 | end |
app/models/profile.rb
@@ -3,7 +3,7 @@ | @@ -3,7 +3,7 @@ | ||
3 | # which by default is the one returned by Environment:default. | 3 | # which by default is the one returned by Environment:default. |
4 | class Profile < ActiveRecord::Base | 4 | class Profile < ActiveRecord::Base |
5 | 5 | ||
6 | - attr_accessible :name, :identifier, :public_profile, :nickname, :custom_footer, :custom_header, :address, :zip_code, :contact_phone, :image_builder, :description, :closed, :template_id, :environment, :lat, :lng, :is_template, :fields_privacy, :preferred_domain_id, :category_ids, :country, :city, :state, :national_region_code, :email, :contact_email, :redirect_l10n, :notification_time | 6 | + attr_accessible :name, :identifier, :public_profile, :nickname, :custom_footer, :custom_header, :address, :zip_code, :contact_phone, :image_builder, :description, :closed, :template_id, :environment, :lat, :lng, :is_template, :fields_privacy, :preferred_domain_id, :category_ids, :country, :city, :state, :national_region_code, :email, :contact_email, :redirect_l10n, :notification_time, :redirection_after_login |
7 | 7 | ||
8 | # use for internationalizable human type names in search facets | 8 | # use for internationalizable human type names in search facets |
9 | # reimplement on subclasses | 9 | # reimplement on subclasses |
@@ -346,16 +346,17 @@ class Profile < ActiveRecord::Base | @@ -346,16 +346,17 @@ class Profile < ActiveRecord::Base | ||
346 | end | 346 | end |
347 | 347 | ||
348 | def copy_blocks_from(profile) | 348 | def copy_blocks_from(profile) |
349 | + template_boxes = profile.boxes.select{|box| box.position} | ||
349 | self.boxes.destroy_all | 350 | self.boxes.destroy_all |
350 | - profile.boxes.each do |box| | ||
351 | - new_box = Box.new | 351 | + self.boxes = template_boxes.size.times.map { Box.new } |
352 | + | ||
353 | + template_boxes.each_with_index do |box, i| | ||
354 | + new_box = self.boxes[i] | ||
352 | new_box.position = box.position | 355 | new_box.position = box.position |
353 | - self.boxes << new_box | ||
354 | box.blocks.each do |block| | 356 | box.blocks.each do |block| |
355 | new_block = block.class.new(:title => block[:title]) | 357 | new_block = block.class.new(:title => block[:title]) |
356 | - new_block.settings = block.settings | ||
357 | - new_block.position = block.position | ||
358 | - self.boxes[-1].blocks << new_block | 358 | + new_block.copy_from(block) |
359 | + new_box.blocks << new_block | ||
359 | end | 360 | end |
360 | end | 361 | end |
361 | end | 362 | end |
app/models/profile_image_block.rb
app/models/profile_info_block.rb
app/models/profile_list_block.rb
1 | class ProfileListBlock < Block | 1 | class ProfileListBlock < Block |
2 | 2 | ||
3 | - attr_accessible :limit, :prioritize_profiles_with_image | 3 | + attr_accessible :prioritize_profiles_with_image |
4 | 4 | ||
5 | settings_items :limit, :type => :integer, :default => 6 | 5 | settings_items :limit, :type => :integer, :default => 6 |
6 | settings_items :prioritize_profiles_with_image, :type => :boolean, :default => true | 6 | settings_items :prioritize_profiles_with_image, :type => :boolean, :default => true |
@@ -18,13 +18,13 @@ class ProfileListBlock < Block | @@ -18,13 +18,13 @@ class ProfileListBlock < Block | ||
18 | result = nil | 18 | result = nil |
19 | visible_profiles = profiles.visible.includes([:image,:domains,:preferred_domain,:environment]) | 19 | visible_profiles = profiles.visible.includes([:image,:domains,:preferred_domain,:environment]) |
20 | if !prioritize_profiles_with_image | 20 | if !prioritize_profiles_with_image |
21 | - result = visible_profiles.all(:limit => limit, :order => 'updated_at DESC').sort_by{ rand } | ||
22 | - elsif profiles.visible.with_image.count >= limit | ||
23 | - result = visible_profiles.with_image.all(:limit => limit * 5, :order => 'updated_at DESC').sort_by{ rand } | 21 | + result = visible_profiles.all(:limit => get_limit, :order => 'profiles.updated_at DESC').sort_by{ rand } |
22 | + elsif profiles.visible.with_image.count >= get_limit | ||
23 | + result = visible_profiles.with_image.all(:limit => get_limit * 5, :order => 'profiles.updated_at DESC').sort_by{ rand } | ||
24 | else | 24 | else |
25 | - result = visible_profiles.with_image.sort_by{ rand } + visible_profiles.without_image.all(:limit => limit * 5, :order => 'profiles.updated_at DESC').sort_by{ rand } | 25 | + result = visible_profiles.with_image.sort_by{ rand } + visible_profiles.without_image.all(:limit => get_limit * 5, :order => 'profiles.updated_at DESC').sort_by{ rand } |
26 | end | 26 | end |
27 | - result.slice(0..limit-1) | 27 | + result.slice(0..get_limit-1) |
28 | end | 28 | end |
29 | 29 | ||
30 | def profile_count | 30 | def profile_count |
app/models/profile_search_block.rb
app/models/recent_documents_block.rb
@@ -33,7 +33,7 @@ class RecentDocumentsBlock < Block | @@ -33,7 +33,7 @@ class RecentDocumentsBlock < Block | ||
33 | end | 33 | end |
34 | 34 | ||
35 | def docs | 35 | def docs |
36 | - self.limit.nil? ? owner.recent_documents(nil, {}, false) : owner.recent_documents(self.limit, {}, false) | 36 | + self.limit.nil? ? owner.recent_documents(nil, {}, false) : owner.recent_documents(self.get_limit, {}, false) |
37 | end | 37 | end |
38 | 38 | ||
39 | def self.expire_on | 39 | def self.expire_on |
app/models/rss_feed.rb
app/models/slideshow_block.rb
@@ -6,6 +6,8 @@ class SlideshowBlock < Block | @@ -6,6 +6,8 @@ class SlideshowBlock < Block | ||
6 | settings_items :navigation, :type => 'boolean', :default => false | 6 | settings_items :navigation, :type => 'boolean', :default => false |
7 | settings_items :image_size, :type => 'string', :default => 'thumb' | 7 | settings_items :image_size, :type => 'string', :default => 'thumb' |
8 | 8 | ||
9 | + attr_accessible :gallery_id, :image_size, :interval, :shuffle, :navigation | ||
10 | + | ||
9 | def self.description | 11 | def self.description |
10 | _('Slideshow') | 12 | _('Slideshow') |
11 | end | 13 | end |
app/models/task.rb
@@ -73,10 +73,6 @@ class Task < ActiveRecord::Base | @@ -73,10 +73,6 @@ class Task < ActiveRecord::Base | ||
73 | end | 73 | end |
74 | end | 74 | end |
75 | 75 | ||
76 | - def self.all_types | ||
77 | - %w[Invitation EnterpriseActivation AddMember Ticket SuggestArticle AddFriend CreateCommunity AbuseComplaint ApproveComment ApproveArticle CreateEnterprise ChangePassword EmailActivation InviteFriend InviteMember] | ||
78 | - end | ||
79 | - | ||
80 | # this method finished the task. It calls #perform, which must be overriden | 76 | # this method finished the task. It calls #perform, which must be overriden |
81 | # by subclasses. At the end a message (as returned by #finish_message) is | 77 | # by subclasses. At the end a message (as returned by #finish_message) is |
82 | # sent to the requestor with #notify_requestor. | 78 | # sent to the requestor with #notify_requestor. |
@@ -254,6 +250,10 @@ class Task < ActiveRecord::Base | @@ -254,6 +250,10 @@ class Task < ActiveRecord::Base | ||
254 | { :conditions => [environment_condition, profile_condition].compact.join(' OR ') } | 250 | { :conditions => [environment_condition, profile_condition].compact.join(' OR ') } |
255 | } | 251 | } |
256 | 252 | ||
253 | + def self.pending_types_for(profile) | ||
254 | + Task.to(profile).pending.select('distinct type').map { |t| [t.class.name, t.title] } | ||
255 | + end | ||
256 | + | ||
257 | def opened? | 257 | def opened? |
258 | status == Task::Status::ACTIVE || status == Task::Status::HIDDEN | 258 | status == Task::Status::ACTIVE || status == Task::Status::HIDDEN |
259 | end | 259 | end |
app/models/user.rb
@@ -5,7 +5,7 @@ require 'user_activation_job' | @@ -5,7 +5,7 @@ require 'user_activation_job' | ||
5 | # Rails generator. | 5 | # Rails generator. |
6 | class User < ActiveRecord::Base | 6 | class User < ActiveRecord::Base |
7 | 7 | ||
8 | - attr_accessible :login, :email, :password, :password_confirmation | 8 | + attr_accessible :login, :email, :password, :password_confirmation, :activated_at |
9 | 9 | ||
10 | N_('Password') | 10 | N_('Password') |
11 | N_('Password confirmation') | 11 | N_('Password confirmation') |
@@ -16,15 +16,18 @@ class User < ActiveRecord::Base | @@ -16,15 +16,18 @@ class User < ActiveRecord::Base | ||
16 | end | 16 | end |
17 | 17 | ||
18 | # FIXME ugly workaround | 18 | # FIXME ugly workaround |
19 | - def self.human_attribute_name(attrib, options={}) | 19 | + def self.human_attribute_name_with_customization(attrib, options={}) |
20 | case attrib.to_sym | 20 | case attrib.to_sym |
21 | when :login | 21 | when :login |
22 | return [_('Username'), _('Email')].join(' / ') | 22 | return [_('Username'), _('Email')].join(' / ') |
23 | when :email | 23 | when :email |
24 | return _('e-Mail') | 24 | return _('e-Mail') |
25 | - else _(self.superclass.human_attribute_name(attrib)) | 25 | + else _(self.human_attribute_name_without_customization(attrib)) |
26 | end | 26 | end |
27 | end | 27 | end |
28 | + class << self | ||
29 | + alias_method_chain :human_attribute_name, :customization | ||
30 | + end | ||
28 | 31 | ||
29 | before_create do |user| | 32 | before_create do |user| |
30 | if user.environment.nil? | 33 | if user.environment.nil? |
@@ -47,8 +50,12 @@ class User < ActiveRecord::Base | @@ -47,8 +50,12 @@ class User < ActiveRecord::Base | ||
47 | 50 | ||
48 | user.person = p | 51 | user.person = p |
49 | end | 52 | end |
50 | - if user.environment.enabled?('skip_new_user_email_confirmation') | ||
51 | - user.activate | 53 | + if user.environment.enabled?('skip_new_user_email_confirmation') |
54 | + if user.environment.enabled?('admin_must_approve_new_users') | ||
55 | + create_moderate_task | ||
56 | + else | ||
57 | + user.activate | ||
58 | + end | ||
52 | end | 59 | end |
53 | end | 60 | end |
54 | after_create :deliver_activation_code | 61 | after_create :deliver_activation_code |
@@ -63,43 +70,8 @@ class User < ActiveRecord::Base | @@ -63,43 +70,8 @@ class User < ActiveRecord::Base | ||
63 | self.person.preferred_domain && self.person.preferred_domain.name || self.environment.default_hostname(true) | 70 | self.person.preferred_domain && self.person.preferred_domain.name || self.environment.default_hostname(true) |
64 | end | 71 | end |
65 | 72 | ||
66 | - class Mailer < ActionMailer::Base | ||
67 | - def activation_email_notify(user) | ||
68 | - user_email = "#{user.login}@#{user.email_domain}" | ||
69 | - recipients user_email | ||
70 | - from "#{user.environment.name} <#{user.environment.noreply_email}>" | ||
71 | - subject _("[%{environment}] Welcome to %{environment} mail!") % { :environment => user.environment.name } | ||
72 | - body :name => user.name, | ||
73 | - :email => user_email, | ||
74 | - :webmail => MailConf.webmail_url(user.login, user.email_domain), | ||
75 | - :environment => user.environment.name, | ||
76 | - :url => url_for(:host => user.environment.default_hostname, :controller => 'home') | ||
77 | - end | ||
78 | - | ||
79 | - def activation_code(user) | ||
80 | - recipients user.email | ||
81 | - | ||
82 | - from "#{user.environment.name} <#{user.environment.noreply_email}>" | ||
83 | - subject _("[%s] Activate your account") % [user.environment.name] | ||
84 | - body :recipient => user.name, | ||
85 | - :activation_code => user.activation_code, | ||
86 | - :environment => user.environment.name, | ||
87 | - :url => user.environment.top_url, | ||
88 | - :redirection => (true if user.return_to) | ||
89 | - end | ||
90 | - | ||
91 | - def signup_welcome_email(user) | ||
92 | - email_body = user.environment.signup_welcome_text_body.gsub('{user_name}', user.name) | ||
93 | - email_subject = user.environment.signup_welcome_text_subject | ||
94 | - | ||
95 | - content_type 'text/html' | ||
96 | - recipients user.email | ||
97 | - | ||
98 | - from "#{user.environment.name} <#{user.environment.noreply_email}>" | ||
99 | - subject email_subject.blank? ? _("Welcome to environment %s") % [user.environment.name] : email_subject | ||
100 | - body email_body | ||
101 | - end | ||
102 | - end | 73 | + # virtual attribute used to stash which community to join on signup or login |
74 | + attr_accessor :community_to_join | ||
103 | 75 | ||
104 | def signup! | 76 | def signup! |
105 | User.transaction do | 77 | User.transaction do |
@@ -172,6 +144,15 @@ class User < ActiveRecord::Base | @@ -172,6 +144,15 @@ class User < ActiveRecord::Base | ||
172 | end | 144 | end |
173 | end | 145 | end |
174 | 146 | ||
147 | + def create_moderate_task | ||
148 | + @task = ModerateUserRegistration.new | ||
149 | + @task.user_id = self.id | ||
150 | + @task.name = self.name | ||
151 | + @task.email = self.email | ||
152 | + @task.target = self.environment | ||
153 | + @task.save | ||
154 | + end | ||
155 | + | ||
175 | def activated? | 156 | def activated? |
176 | self.activation_code.nil? && !self.activated_at.nil? | 157 | self.activation_code.nil? && !self.activated_at.nil? |
177 | end | 158 | end |
app/presenters/image.rb
@@ -11,4 +11,9 @@ class FilePresenter::Image < FilePresenter | @@ -11,4 +11,9 @@ class FilePresenter::Image < FilePresenter | ||
11 | def short_description | 11 | def short_description |
12 | _('Image (%s)') % content_type.split('/')[1].upcase | 12 | _('Image (%s)') % content_type.split('/')[1].upcase |
13 | end | 13 | end |
14 | + | ||
15 | + #Overwriting method from FilePresenter to allow download of images | ||
16 | + def download?(view = nil) | ||
17 | + view.blank? || view == 'false' | ||
18 | + end | ||
14 | end | 19 | end |
app/sweepers/friendship_sweeper.rb
@@ -34,8 +34,7 @@ protected | @@ -34,8 +34,7 @@ protected | ||
34 | expire_timeout_fragment(profile.manage_friends_cache_key(:npage => i.to_s)) | 34 | expire_timeout_fragment(profile.manage_friends_cache_key(:npage => i.to_s)) |
35 | end | 35 | end |
36 | 36 | ||
37 | - blocks = profile.blocks.select{|b| b.kind_of?(FriendsBlock)} | ||
38 | - BlockSweeper.expire_blocks(blocks) | 37 | + expire_blocks_cache(profile, [:profile]) |
39 | end | 38 | end |
40 | 39 | ||
41 | end | 40 | end |
app/sweepers/profile_sweeper.rb
@@ -8,9 +8,6 @@ class ProfileSweeper # < ActiveRecord::Observer | @@ -8,9 +8,6 @@ class ProfileSweeper # < ActiveRecord::Observer | ||
8 | end | 8 | end |
9 | 9 | ||
10 | def after_create(profile) | 10 | def after_create(profile) |
11 | - # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from | ||
12 | - # the Noosfero core soon, see ActionItem3045 | ||
13 | - expire_statistics_block_cache(profile) | ||
14 | end | 11 | end |
15 | 12 | ||
16 | protected | 13 | protected |
@@ -31,13 +28,6 @@ protected | @@ -31,13 +28,6 @@ protected | ||
31 | expire_blogs(profile) if profile.organization? | 28 | expire_blogs(profile) if profile.organization? |
32 | end | 29 | end |
33 | 30 | ||
34 | - # TODO EnvironmentStatisticsBlock is DEPRECATED and will be removed from | ||
35 | - # the Noosfero core soon, see ActionItem3045 | ||
36 | - def expire_statistics_block_cache(profile) | ||
37 | - blocks = profile.environment.blocks.select { |b| b.kind_of?(EnvironmentStatisticsBlock) } | ||
38 | - BlockSweeper.expire_blocks(blocks) | ||
39 | - end | ||
40 | - | ||
41 | def expire_blogs(profile) | 31 | def expire_blogs(profile) |
42 | profile.blogs.select{|b| !b.empty?}.each do |blog| | 32 | profile.blogs.select{|b| !b.empty?}.each do |blog| |
43 | pages = blog.posts.count / blog.posts_per_page + 1 | 33 | pages = blog.posts.count / blog.posts_per_page + 1 |
app/sweepers/role_assignment_sweeper.rb
@@ -14,19 +14,21 @@ protected | @@ -14,19 +14,21 @@ protected | ||
14 | 14 | ||
15 | def expire_caches(role_assignment) | 15 | def expire_caches(role_assignment) |
16 | expire_cache(role_assignment.accessor) | 16 | expire_cache(role_assignment.accessor) |
17 | - expire_cache(role_assignment.resource) if role_assignment.resource.respond_to?(:cache_keys) | 17 | + expire_cache(role_assignment.resource) if role_assignment.resource.kind_of?(Profile) |
18 | end | 18 | end |
19 | 19 | ||
20 | def expire_cache(profile) | 20 | def expire_cache(profile) |
21 | per_page = Noosfero::Constants::PROFILE_PER_PAGE | 21 | per_page = Noosfero::Constants::PROFILE_PER_PAGE |
22 | - profile.cache_keys(:per_page => per_page).each { |ck| | ||
23 | - expire_timeout_fragment(ck) | ||
24 | - } | 22 | + |
23 | + profile.cache_keys(:per_page => per_page).each { |ck| expire_timeout_fragment(ck) } | ||
24 | + expire_timeout_fragment(profile.members_cache_key(:per_page => per_page)) | ||
25 | 25 | ||
26 | profile.blocks_to_expire_cache.each { |block| | 26 | profile.blocks_to_expire_cache.each { |block| |
27 | blocks = profile.blocks.select{|b| b.kind_of?(block)} | 27 | blocks = profile.blocks.select{|b| b.kind_of?(block)} |
28 | BlockSweeper.expire_blocks(blocks) | 28 | BlockSweeper.expire_blocks(blocks) |
29 | } | 29 | } |
30 | + | ||
31 | + expire_blocks_cache(profile, [:role_assignment]) | ||
30 | end | 32 | end |
31 | 33 | ||
32 | end | 34 | end |
app/views/account/_signup_form.html.erb
@@ -136,8 +136,6 @@ | @@ -136,8 +136,6 @@ | ||
136 | <script type="text/javascript"> | 136 | <script type="text/javascript"> |
137 | jQuery(function($) { | 137 | jQuery(function($) { |
138 | 138 | ||
139 | - $('#signup-form #user_login').css('width', 335 - $('#signup-domain').outerWidth()); | ||
140 | - | ||
141 | $('#signup-form input[type=text], #signup-form textarea').each(function() { | 139 | $('#signup-form input[type=text], #signup-form textarea').each(function() { |
142 | $(this).bind('blur', function() { | 140 | $(this).bind('blur', function() { |
143 | if ($(this).val() == '') { | 141 | if ($(this).val() == '') { |
app/views/account/accept_terms.html.erb
@@ -19,10 +19,18 @@ | @@ -19,10 +19,18 @@ | ||
19 | <%= hidden_field_tag :enterprise_code, params[:enterprise_code] %> | 19 | <%= hidden_field_tag :enterprise_code, params[:enterprise_code] %> |
20 | <%= hidden_field_tag :answer, params[:answer] %> | 20 | <%= hidden_field_tag :answer, params[:answer] %> |
21 | 21 | ||
22 | - <%= labelled_check_box(environment.terms_of_use_acceptance_text.blank? ? _('I read the terms of use and accepted them') : environment.terms_of_use_acceptance_text, :terms_accepted, '1', false, :onclick => 'toggle_submit_button("submit-accept-terms", this.checked)') %> | 22 | + <%= labelled_check_box(environment.terms_of_use_acceptance_text.blank? ? _('I read the terms of use and accepted them') : environment.terms_of_use_acceptance_text, :terms_accepted, '1', false, :id => 'accept-terms') %> |
23 | <% button_bar do %> | 23 | <% button_bar do %> |
24 | <%= button 'cancel', _('Cancel'), :controller => 'home', :action => 'index' %> | 24 | <%= button 'cancel', _('Cancel'), :controller => 'home', :action => 'index' %> |
25 | <%= submit_button 'forward', _('Continue'), {:disabled => true, :class => 'disabled', :id => 'submit-accept-terms'} %> | 25 | <%= submit_button 'forward', _('Continue'), {:disabled => true, :class => 'disabled', :id => 'submit-accept-terms'} %> |
26 | <% end %> | 26 | <% end %> |
27 | <% end %> | 27 | <% end %> |
28 | </div> | 28 | </div> |
29 | + | ||
30 | +<script type="text/javascript"> | ||
31 | + jQuery('#accept-terms').change(function(){ | ||
32 | + jQuery("#submit-accept-terms").toggleClass("disabled"); | ||
33 | + jQuery("#submit-accept-terms").prop("disabled", !jQuery("#submit-accept-terms").prop("disabled")); | ||
34 | + }); | ||
35 | +</script> | ||
36 | + |
app/views/account/signup.html.erb
1 | <% if @register_pending %> | 1 | <% if @register_pending %> |
2 | -<div id='thanks-for-signing'> | ||
3 | - <h1><%= _("Welcome to %s!") % environment.name %></h1> | ||
4 | - <h3><%= _("Thanks for signing up, we're thrilled to have you on our social network!") %></h3> | ||
5 | - <p><%= _("Firstly, some tips for getting started:") %></p> | ||
6 | - <h4><%= _("Confirm your account!") %></h4> | ||
7 | - <p><%= _("You should receive a welcome email from us shortly. Please take a second to follow the link within to confirm your account.") %></p> | ||
8 | - <p><%= _("You won't appear as %s until your account is confirmed.") % link_to(_('user'), {:controller => :search, :action => :people, :filter => 'more_recent'}, :target => '_blank') %></p> | ||
9 | - <h4><%= _("What to do next?") %></h4> | ||
10 | - <p><%= _("%s. Upload an avatar and let your friends find you easily :)") % link_to(_('Customize your profile'), {:controller => 'doc', :section => 'user', :topic => 'editing-person-info'}, :target => '_blank') %></p> | ||
11 | - <p><%= _("Learn the guidelines. Read the %s for more details on how to use this social network!") % link_to(_('Documentation'), {:controller => 'doc'}, :target => '_blank') %></p> | ||
12 | - <p><%= _("%s your Gmail, Yahoo and Hotmail contacts!") % link_to(_('Invite and find'), {:controller => 'doc', :section => 'user', :topic => 'invite-contacts'}, :target => '_blank') %></p> | ||
13 | - <p><%= _("Start exploring and have fun!") %></p> | ||
14 | -</div> | 2 | + <div id='thanks-for-signing'> |
3 | + <% if environment.has_custom_welcome_screen? %> | ||
4 | + <%= environment.settings[:signup_welcome_screen_body].html_safe %> | ||
5 | + <% elsif environment.enabled?('admin_must_approve_new_users')%> | ||
6 | + <h1><%= _("Welcome to %s!") % environment.name %></h1> | ||
7 | + <h3><%= _("Thanks for signing up, we're thrilled to have you on our social network!") %></h3> | ||
8 | + <p><%= _("Firstly, some tips for getting started:") %></p> | ||
9 | + <% unless environment.enabled?('skip_new_user_email_confirmation') %> | ||
10 | + <h4><%= _("Confirm your account and wait for admin approvement!") %></h4> | ||
11 | + <p><%= _("You should receive a welcome email from us shortly. Please take a second to follow the link within to confirm your account.") %></p> | ||
12 | + <p><%= _("You won't appear as %s until your account is confirmed and approved.") % link_to(_('user'), {:controller => :search, :action => :people, :filter => 'more_recent'}, :target => '_blank') %></p> | ||
13 | + <% else %> | ||
14 | + <h4><%= _("Wait for admin approvement!") %></h4> | ||
15 | + <p><%= _("The administrators will evaluate your signup request for approvement.") %></p> | ||
16 | + <p><%= _("You won't appear as %s until your account is approved.") % link_to(_('user'), {:controller => :search, :action => :people, :filter => 'more_recent'}, :target => '_blank') %></p> | ||
17 | + <% end %> | ||
18 | + <h4><%= _("What to do next?") %></h4> | ||
19 | + <p><%= _("%s. Upload an avatar and let your friends find you easily :)") % link_to(_('Customize your profile'), {:controller => 'doc', :section => 'user', :topic => 'editing-person-info'}, :target => '_blank') %></p> | ||
20 | + <p><%= _("Learn the guidelines. Read the %s for more details on how to use this social network!") % link_to(_('Documentation'), {:controller => 'doc'}, :target => '_blank') %></p> | ||
21 | + <p><%= _("%s your Gmail, Yahoo and Hotmail contacts!") % link_to(_('Invite and find'), {:controller => 'doc', :section => 'user', :topic => 'invite-contacts'}, :target => '_blank') %></p> | ||
22 | + <p><%= _("Start exploring and have fun!") %></p> | ||
23 | + <% else %> | ||
24 | + <h1><%= _("Welcome to %s!") % environment.name %></h1> | ||
25 | + <h3><%= _("Thanks for signing up, we're thrilled to have you on our social network!") %></h3> | ||
26 | + <p><%= _("Firstly, some tips for getting started:") %></p> | ||
27 | + <h4><%= _("Confirm your account!") %></h4> | ||
28 | + <p><%= _("You should receive a welcome email from us shortly. Please take a second to follow the link within to confirm your account.") %></p> | ||
29 | + <p><%= _("You won't appear as %s until your account is confirmed.") % link_to(_('user'), {:controller => :search, :action => :people, :filter => 'more_recent'}, :target => '_blank') %></p> | ||
30 | + <h4><%= _("What to do next?") %></h4> | ||
31 | + <p><%= _("%s. Upload an avatar and let your friends find you easily :)") % link_to(_('Customize your profile'), {:controller => 'doc', :section => 'user', :topic => 'editing-person-info'}, :target => '_blank') %></p> | ||
32 | + <p><%= _("Learn the guidelines. Read the %s for more details on how to use this social network!") % link_to(_('Documentation'), {:controller => 'doc'}, :target => '_blank') %></p> | ||
33 | + <p><%= _("%s your Gmail, Yahoo and Hotmail contacts!") % link_to(_('Invite and find'), {:controller => 'doc', :section => 'user', :topic => 'invite-contacts'}, :target => '_blank') %></p> | ||
34 | + <p><%= _("Start exploring and have fun!") %></p> | ||
35 | + <% end %> | ||
36 | + </div> | ||
15 | <% else %> | 37 | <% else %> |
16 | <h1><%= _('Sign up for %s!') % environment.name %></h1> | 38 | <h1><%= _('Sign up for %s!') % environment.name %></h1> |
17 | <%= render :partial => 'signup_form' %> | 39 | <%= render :partial => 'signup_form' %> |
@@ -0,0 +1,5 @@ | @@ -0,0 +1,5 @@ | ||
1 | +<div class='description'> | ||
2 | + <%= _('This text will be showed as a welcome message to users after signup') %><br/><br/> | ||
3 | +</div> | ||
4 | + | ||
5 | +<%= labelled_form_field(_('Body'), text_area(:environment, :signup_welcome_screen_body, :cols => 40, :style => 'width: 100%', :class => 'mceEditor')) %> |
app/views/admin_panel/site_info.html.erb
@@ -12,6 +12,8 @@ | @@ -12,6 +12,8 @@ | ||
12 | :content => (render :partial => 'terms_of_use', :locals => {:f => f})} %> | 12 | :content => (render :partial => 'terms_of_use', :locals => {:f => f})} %> |
13 | <% tabs << {:title => _('Signup welcome text'), :id => 'signup-welcome-text', | 13 | <% tabs << {:title => _('Signup welcome text'), :id => 'signup-welcome-text', |
14 | :content => (render :partial => 'signup_welcome_text', :locals => {:f => f})} %> | 14 | :content => (render :partial => 'signup_welcome_text', :locals => {:f => f})} %> |
15 | + <% tabs << {:title => _('Signup welcome message'), :id => 'signup-welcome-message', | ||
16 | + :content => (render :partial => 'signup_welcome_screen', :locals => {:f => f}) }%> | ||
15 | <%= render_tabs(tabs) %> | 17 | <%= render_tabs(tabs) %> |
16 | <% button_bar do %> | 18 | <% button_bar do %> |
17 | <%= submit_button(:save, _('Save'), :cancel => {:action => 'index'}) %> | 19 | <%= submit_button(:save, _('Save'), :cancel => {:action => 'index'}) %> |
app/views/blocks/login_block.html.erb
1 | -<div class="logged-user-info" style='display: none;'> | ||
2 | - <h2><%= _('Logged in as %s') % '{login}' %></h2> | ||
3 | - <ul> | ||
4 | - <li><%= _('User since {year}/{month}') %></li> | ||
5 | - <li><%= link_to _('Homepage'), '/{login}' %></li> | ||
6 | - </ul> | ||
7 | - <div class="user-actions"> | ||
8 | - <%= link_to content_tag('span', _('Logout')), { :controller => 'account', :action => 'logout' }, :class => 'button with-text icon-menu-logout' %> | 1 | +<% if user.present? %> |
2 | + <div class="logged-user-info"> | ||
3 | + <h2><%= _('Logged in as %s') % user.identifier %></h2> | ||
4 | + <ul> | ||
5 | + <li><%= _('User since %s/%s') % [user.created_at.month, user.created_at.year] %></li> | ||
6 | + <li><%= link_to _('Homepage'), user.public_profile_url %></li> | ||
7 | + </ul> | ||
8 | + <div class="user-actions"> | ||
9 | + <%= link_to content_tag('span', _('Logout')), { :controller => 'account', :action => 'logout' }, :class => 'button with-text icon-menu-logout' %> | ||
10 | + </div> | ||
9 | </div> | 11 | </div> |
10 | -</div> | ||
11 | -<div class='not-logged-user' style='display: none;'> | ||
12 | - <%= render :file => 'account/login_block' %> | ||
13 | -</div> | 12 | +<% else %> |
13 | + <div class='not-logged-user'> | ||
14 | + <%= render :file => 'account/login_block' %> | ||
15 | + </div> | ||
16 | +<% end%> |
app/views/blocks/members.html.erb
app/views/blocks/my_network.html.erb
1 | <%= block_title(title) %> | 1 | <%= block_title(title) %> |
2 | 2 | ||
3 | -<%= render :file => 'blocks/my_network/' + owner.class.name.underscore, :locals => { :owner => owner } %> | 3 | +<%= render_profile_actions owner.class %> |
4 | 4 | ||
5 | <ul> | 5 | <ul> |
6 | <li><%= link_to(_('Homepage'), owner.url, :class => 'url') %></li> | 6 | <li><%= link_to(_('Homepage'), owner.url, :class => 'url') %></li> |
@@ -11,5 +11,5 @@ | @@ -11,5 +11,5 @@ | ||
11 | </ul> | 11 | </ul> |
12 | 12 | ||
13 | <div class="my-network-actions"> | 13 | <div class="my-network-actions"> |
14 | - <%= render :file => 'blocks/profile_info_actions/' + owner.class.name.underscore %> | 14 | + <%= render 'blocks/profile_info_actions/' + owner.class.name.underscore %> |
15 | </div> | 15 | </div> |
app/views/blocks/profile_image.html.erb
@@ -23,6 +23,6 @@ | @@ -23,6 +23,6 @@ | ||
23 | <% end %> | 23 | <% end %> |
24 | 24 | ||
25 | <div class="profile-info-options"> | 25 | <div class="profile-info-options"> |
26 | - <%= render :file => view_for_profile_actions(block.owner.class) %> | 26 | + <%= render_profile_actions block.owner.class %> |
27 | </div> | 27 | </div> |
28 | </div><!-- end class="vcard" --> | 28 | </div><!-- end class="vcard" --> |
app/views/blocks/profile_info.html.erb
@@ -40,7 +40,7 @@ | @@ -40,7 +40,7 @@ | ||
40 | <% end %> | 40 | <% end %> |
41 | 41 | ||
42 | <div class="profile-info-options"> | 42 | <div class="profile-info-options"> |
43 | - <%= render :file => view_for_profile_actions(block.owner.class) %> | 43 | + <%= render_profile_actions block.owner.class %> |
44 | </div> | 44 | </div> |
45 | 45 | ||
46 | </div><!-- end class="vcard" --> | 46 | </div><!-- end class="vcard" --> |
app/views/blocks/profile_info_actions/_community.html.erb
0 → 100644
@@ -0,0 +1,20 @@ | @@ -0,0 +1,20 @@ | ||
1 | +<ul> | ||
2 | + <li> | ||
3 | + <%= render "blocks/profile_info_actions/join_leave_community" %> | ||
4 | + </li> | ||
5 | + <% if logged_in? %> | ||
6 | + <% if profile.enable_contact? %> | ||
7 | + <li> | ||
8 | + <%= link_to content_tag('span', _('Send an e-mail')), | ||
9 | + { :profile => profile.identifier, | ||
10 | + :controller => 'contact', | ||
11 | + :action => 'new' }, | ||
12 | + {:class => 'button with-text icon-menu-mail', :title => _('Send an e-mail to the administrators')} %> | ||
13 | + </li> | ||
14 | + <% end %> | ||
15 | + | ||
16 | + <li><%= report_abuse(profile, :button) %></li> | ||
17 | + | ||
18 | + <%= render_environment_features(:profile_actions) %> | ||
19 | + <% end %> | ||
20 | +</ul> |