Commit db0d70fc0eb48b5508f6b8a52daad9ada1a18a9e
Exists in
master
and in
29 other branches
Merge branch 'master' into api
Showing
897 changed files
with
40376 additions
and
10326 deletions
Show diff stats
Too many changes.
To preserve performance only 100 of 897 files displayed.
AUTHORS.md
1 | +This list is automatically generated at release time. Please do not change it. | |
2 | + | |
1 | 3 | If you are not listed here, but should be, please write to the noosfero mailing |
2 | 4 | list: http://listas.softwarelivre.org/cgi-bin/mailman/listinfo/noosfero-dev |
3 | 5 | (this list requires subscription to post, but since you are an author of |
... | ... | @@ -6,280 +8,123 @@ noosfero, that's not a problem). |
6 | 8 | Developers |
7 | 9 | ========== |
8 | 10 | |
11 | +Ábner Silva de Oliveira <abner.oliveira@serpro.gov.br> | |
9 | 12 | Alan Freihof Tygel <alantygel@gmail.com> |
10 | -Alessandro Palmeira + Caio C. Salgado <alessandro.palmeira@gmail.com> | |
11 | -Alessandro Palmeira + Caio Salgado + Diego Araújo + João M. M. da Silva <diegoamc90@gmail.com> | |
12 | -Alessandro Palmeira + Caio Salgado <alessandro.palmeira@gmail.com> | |
13 | -Alessandro Palmeira + Caio Salgado <caio.csalgado@gmail.com> | |
14 | -Alessandro Palmeira + Carlos Morais <alessandro.palmeira@gmail.com> | |
15 | -Alessandro Palmeira + Daniel Alves + Diego Araújo + Guilherme Rojas <danpaulalves@gmail.com> | |
16 | -Alessandro Palmeira + Daniel Alves + Diego Araújo <diegoamc90@gmail.com> | |
17 | -Alessandro Palmeira + Daniel Alves <alessandro.palmeira@gmail.com> | |
18 | -Alessandro Palmeira + Diego Araujo + Daniela Feitosa <alessandro.palmeira@gmail.com> | |
19 | -Alessandro Palmeira + Diego Araujo + Eduardo Morais <alessandro.palmeira@gmail.com> | |
20 | -Alessandro Palmeira + Diego Araujo + João M. M. da Silva + Paulo Meirelles <alessandro.palmeira@gmail.com> | |
21 | -Alessandro Palmeira + Diego Araujo + Rafael Manzo <alessandro.palmeira@gmail.com> | |
22 | -Alessandro Palmeira + Diego Araujo <alessandro.palmeira@gmail.com> | |
23 | -Alessandro Palmeira + Diego Araujo <diegoamc90@gmail.com> | |
24 | -Alessandro Palmeira + Diego Araújo + João M. M. da Silva <alessandro.palmeira@gmail.com> | |
25 | -Alessandro Palmeira + Diego Araújo + João M. M. da Silva <diegoamc90@gmail.com> | |
26 | -Alessandro Palmeira + Diego Araújo + Pedro Leal + João M. M. da Silva <diegoamc90@gmail.com> | |
27 | -Alessandro Palmeira + Diego Araújo + Pedro Leal <diegoamc90@gmail.com> | |
28 | -Alessandro Palmeira + Diego Araújo <alessandro.palmeira@gmail.com> | |
29 | -Alessandro Palmeira + Diego Araújo <diegoamc90@gmail.com> | |
30 | -Alessandro Palmeira + Eduardo Morais <alessandro.palmeira@gmail.com> | |
31 | -Alessandro Palmeira + Guilherme Rojas <alessandro.palmeira@gmail.com> | |
32 | -Alessandro Palmeira + Jefferson Fernandes <alessandro.palmeira@gmail.com> | |
33 | -Alessandro Palmeira + Joao M. M. da Silva + Diego Araujo <alessandro.palmeira@gmail.com> | |
34 | -Alessandro Palmeira + João M. M. Silva <alessandro.palmeira@gmail.com> | |
35 | -Alessandro Palmeira + João M. M. da Silva + Renan Teruo <alessandro.palmeira@gmail.com> | |
36 | -Alessandro Palmeira + João M. M. da Silva <alessandro.palmeira@gmail.com> | |
37 | -Alessandro Palmeira + Paulo Meirelles + João M. M. da Silva <alessandro.palmeira@gmail.com> | |
38 | -Alessandro Palmeira + Paulo Meirelles <alessandro.palmeira@gmail.com> | |
39 | -Alessandro Palmeira + Rafael Manzo <alessandro.palmeira@gmail.com> | |
40 | 13 | Alessandro Palmeira <alessandro.palmeira@gmail.com> |
14 | +Alex Campelo <campelo.al1@gmail.com> | |
15 | +Álvaro Fernando <alvarofernandoms@gmail.com> | |
41 | 16 | Ana Losnak <analosnak@gmail.com> |
42 | -Andre Bernardes <andrebsguedes@gmail.com> | |
43 | -André Bernardes <andrebsguedes@gmail.com> | |
44 | -André Guedes <andrebsguedes@fedora.local> | |
17 | +Ana Paula Vargas <anapaulavnoronha@gmail.com> | |
18 | +Andre Bedran <bedran.fleck@gmail.com> | |
45 | 19 | André Guedes <andrebsguedes@gmail.com> |
46 | -Antonio Terceiro + Carlos Morais <terceiro@colivre.coop.br> | |
47 | -Antonio Terceiro + Paulo Meirelles <terceiro@colivre.coop.br> | |
20 | +Andrey Aleksanyants <aaleksanyants@yahoo.com> | |
48 | 21 | Antonio Terceiro <terceiro@colivre.coop.br> |
49 | 22 | Arthur Del Esposte <arthurmde@gmail.com> |
50 | -Arthur Del Esposte <arthurmde@yahoo.com.br> | |
51 | 23 | Athos Ribeiro <athoscribeiro@gmail.com> |
52 | 24 | Aurelio A. Heckert <aurelio@colivre.coop.br> |
53 | 25 | Braulio Bhavamitra <braulio@eita.org.br> |
54 | -Braulio Bhavamitra <brauliobo@gmail.com> | |
55 | -Bráulio Bhavamitra <brauliobo@gmail.com> | |
56 | -Caio + Diego + Pedro + João <caio.csalgado@gmail.com> | |
57 | -Caio <caio.csalgado@gmail.com> | |
26 | +Brenddon Gontijo <brenddongontijo@msn.com> | |
58 | 27 | Caio Formiga <caio.formiga@gmail.com> |
59 | -Caio SBA <caio@colivre.coop.br> | |
60 | -Caio Salgado + Alessandro Palmeira <caio.csalgado@gmail.com> | |
61 | -Caio Salgado + Carlos Morais + Diego Araújo + Pedro Leal <diegoamc90@gmail.com> | |
62 | -Caio Salgado + Diego Araujo <caio.csalgado@gmail.com> | |
63 | -Caio Salgado + Diego Araújo + Jefferson Fernandes <caio.csalgado@gmail.com> | |
64 | -Caio Salgado + Diego Araújo + João M. M. da Silva <caio.csalgado@gmail.com> | |
65 | -Caio Salgado + Diego Araújo + Pedro Leal <caio.csalgado@gmail.com> | |
66 | -Caio Salgado + Diego Araújo + Pedro Leal <diegoamc90@gmail.com> | |
67 | -Caio Salgado + Diego Araújo + Rafael Manzo <diegoamc90@gmail.com> | |
68 | -Caio Salgado + Diego Araújo <caio.csalgado@gmail.com> | |
69 | -Caio Salgado + Diego Araújo <diegoamc90@gmail.com> | |
70 | -Caio Salgado + Jefferson Fernandes <caio.csalgado@gmail.com> | |
71 | -Caio Salgado + Jefferson Fernandes <jeffs.fernandes@gmail.com> | |
72 | -Caio Salgado + Rafael Manzo <caio.csalgado@gmail.com> | |
73 | -Caio Salgado + Renan Teruo + Jefferson Fernandes <jeffs.fernandes@gmail.com> | |
74 | -Caio Salgado + Renan Teruo <caio.csalgado@gmail.com> | |
75 | -Caio Salgado + Renan Teruo <caio.salgado@gmail.com> | |
76 | -Caio Salgado + Renan Teruo <renanteruoc@gmail.com> | |
77 | 28 | Caio Salgado <caio.csalgado@gmail.com> |
29 | +Caio SBA <caio@colivre.coop.br> | |
78 | 30 | Caio Tiago Oliveira <caiotiago@colivre.coop.br> |
79 | -Caio, Pedro <caio.csalgado@gmail.com> | |
80 | 31 | Carlos Andre de Souza <carlos.andre.souza@msn.com> |
81 | -Carlos Morais + Diego Araújo <diegoamc90@gmail.com> | |
82 | -Carlos Morais + Eduardo Morais <carlos88morais@gmail.com> | |
83 | -Carlos Morais + Paulo Meirelles <carlos88morais@gmail.com> | |
84 | -Carlos Morais + Pedro Leal <carlos88morais@gmail.com> | |
85 | 32 | Carlos Morais <carlos88morais@gmail.com> |
86 | 33 | Christophe DANIEL <papaeng@gmail.com> |
87 | -Daniel Alves + Diego Araújo <danpaulalves@gmail.com> | |
88 | -Daniel Alves + Diego Araújo <diegoamc90@gmail.com> | |
89 | -Daniel Alves + Diego Araújo + Guilherme Rojas <danpaulalves@gmail.com> | |
90 | -Daniel Alves + Diego Araújo + Guilherme Rojas <diegoamc90@gmail.com> | |
91 | -Daniel Alves + Diego Araújo + Guilherme Rojas <guilhermehrojas@gmail.com> | |
92 | -Daniel Alves + Diego Araújo <danpaulalves@gmail.com> | |
93 | -Daniel Alves + Diego Araújo <diegoamc90@gmail.com> | |
94 | -Daniel Alves + Guilherme Rojas <danpaulalves@gmail.com> | |
95 | -Daniel Alves + Rafael Manzo <rr.manzo@gmail.com> | |
34 | +Daniela Feitosa <alessandro.palmeira@gmail.com> | |
35 | +Daniel Alves <danpaulalves@gmail.com> | |
36 | +Daniela Soares Feitosa <danielafeitosa@colivre.coop.br> | |
96 | 37 | Daniel Bucher <daniel.bucher88@gmail.com> |
97 | 38 | Daniel Cunha <daniel@colivre.coop.br> |
98 | -Daniela Soares Feitosa <danielafeitosa@colivre.coop.br> | |
39 | +Daniel Tygel <dtygel@eita.org.br> | |
99 | 40 | David Carlos <ddavidcarlos1392@gmail.com> |
100 | -Diego + Jefferson <diegoamc90@gmail.com> | |
101 | -Diego + Renan <renanteruoc@gmail.com> | |
102 | -Diego Araujo + Caio Salgado <diegoamc90@gmail.com> | |
103 | -Diego Araujo + Jefferson Fernandes <jeffs.fernandes@gmail.com> | |
104 | -Diego Araujo + Rafael Manzo <diegoamc90@gmail.com> | |
105 | -Diego Araujo + Rodrigo Souto + Rafael Manzo <rr.manzo@gmail.com> | |
106 | -Diego Araújo + Alessandro Palmeira + João M. M. da Silva <diegoamc90@gmail.com> | |
107 | -Diego Araújo + Alessandro Palmeira + Rafael Manzo <rr.manzo@gmail.com> | |
108 | -Diego Araújo + Alessandro Palmeira <diegoamc90@gmail.com> | |
109 | -Diego Araújo + Daniel Alves + Rafael Manzo <rr.manzo@gmail.com> | |
110 | -Diego Araújo + Eduardo Morais + Paulo Meirelles <diegoamc90@gmail.com> | |
111 | -Diego Araújo + Guilherme Rojas <diegoamc90@gmail.com> | |
112 | -Diego Araújo + Jefferson Fernandes <diegoamc90@gmail.com> | |
113 | -Diego Araújo + João M. M. da Silva + Alessandro Palmeira <jaodsilv@linux.ime.usp.br> | |
114 | -Diego Araújo + João M. M. da Silva + João Machini <diegoamc90@gmail.com> | |
115 | -Diego Araújo + João M. M. da Silva + Pedro Leal <diegoamc90@gmail.com> | |
116 | -Diego Araújo + João M. M. da Silva <diegoamc90@gmail.com> | |
117 | -Diego Araújo + João Machini <diegoamc90@gmail.com> | |
118 | -Diego Araújo + João Machini <digoamc90@gmail.com> | |
119 | -Diego Araújo + Paulo Meirelles <diegoamc90@gmail.com> | |
120 | -Diego Araújo + Pedro Leal <diegoamc90@gmail.com> | |
121 | -Diego Araújo + Rafael Manzo <diegoamc90@gmail.com> | |
122 | -Diego Araújo + Renan Teruo + Alessandro Palmeira <diegoamc90@gmail.com> | |
123 | -Diego Araújo + Renan Teruo <diegoamc90@gmail.com> | |
124 | -Diego Araújo <diegoamc90@gmail.com> | |
125 | -Diego Martinez <diegoamc90@gmail.com> | |
126 | -DylanGuedes <djmgguedes@gmail.com> | |
127 | -Eduardo Passos <eduardo@risa.localdomain.localhost> | |
41 | +Diego Araujo <diegoamc90@gmail.com> | |
42 | +Dylan Guedes <djmgguedes@gmail.com> | |
43 | +Eduardo Morais | |
128 | 44 | Eduardo Passos <eduardosteps@gmail.com> |
129 | 45 | Eduardo Tourinho Edington <eduardo.edington@serpro.gov.br> |
130 | 46 | Eduardo Vital <vitaldu@gmail.com> |
131 | -Evandro Jr <evandrojr@gmail.com> | |
132 | -Evandro Junior <evandrojr@gmail.com> | |
133 | 47 | Evandro Magalhaes Leite Junior <evandro.leite@serpro.gov.br> |
134 | 48 | Fabio Teixeira <fabio1079@gmail.com> |
135 | 49 | FAMMA TV NOTICIAS MEDIOS DE CO <revistafammatvmusic.oficial@gmail.com> |
136 | -Fabio Teixeira <fabio1079@gmail.com> | |
137 | 50 | Fernanda Lopes <nanda.listas+psl@gmail.com> |
138 | 51 | Filipe Ribeiro <firibeiro77@live.com> |
139 | -Francisco Marcelo A. Lima Júnior <francisco.lima-junior@serpro.gov.br> | |
140 | -Francisco Marcelo de Araujo Lima Junior <79350259591@serpro-1457614.(none)> | |
141 | 52 | Francisco Marcelo de Araújo Lima Júnior <francisco.lima-junior@serpro.gov.br> |
142 | -Francisco Marcelo de Araújo Lima Júnior <maljunior@gmail.com> | |
143 | 53 | Gabriela Navarro <navarro1703@gmail.com> |
144 | 54 | Gonzalo Exequiel Pedone <hipersayan.x@gmail.com> |
145 | 55 | Grazieno Pellegrino <grazieno@gmail.com> |
146 | -Gust <darksshades@hotmail.com> | |
56 | +Guilherme C. Muniz <guilherme.cmuniz@gmail.com> | |
57 | +Guilherme Rojas <guilhermehrojas@gmail.com> | |
58 | +Gustavo Jaruga <darksshades@gmail.com> | |
147 | 59 | Hebert Douglas <hebertdougl@gmail.com> |
148 | 60 | Hugo Melo <hugo@riseup.net> |
61 | +Iolane Andrade <andrade.icaa@gmail.com> | |
149 | 62 | Isaac Canan <isaac@intelletto.com.br> |
150 | 63 | Italo Valcy <italo@dcc.ufba.br> |
151 | -Jefferson Fernandes + Diego Araujo + Rafael Manzo <jeffs.fernandes@gmail.com> | |
152 | -Jefferson Fernandes + Joao M. M. Silva <jeffs.fernandes@gmail.com> | |
153 | -Jefferson Fernandes + Joao M. M. da Silva <jeffs.fernandes@gmail.com> | |
154 | -Joao M. M. Silva + Jefferson Fernandes <jaodsilv@linux.ime.usp.br> | |
155 | -Joao M. M. da Silva + Alessandro Palmeira <jaodsilv@linux.ime.usp.br> | |
156 | -Joao M. M. da Silva + Jefferson Fernandes <jaodsilv@linux.ime.usp.br> | |
64 | +Jefferson Fernandes <jeffs.fernandes@gmail.com> | |
65 | +Jérôme Jutteau <j.jutteau@gmail.com> | |
66 | +João Machini | |
67 | +João M. M. da Silva <jaodsilv@linux.ime.usp.br> | |
157 | 68 | Joenio Costa <joenio@colivre.coop.br> |
158 | -Jose Pedro <1jpsneto@gmail.com> | |
159 | 69 | Josef Spillner <josef.spillner@tu-dresden.de> |
160 | -João M. M. Silva + Caio Salgado <jaodsilv@linux.ime.usp.br> | |
161 | -João M. M. Silva + Diego Araújo <jaodsilv@linux.ime.usp.br> | |
162 | -João M. M. Silva + Paulo Meirelles <jaodsilv@linux.ime.usp.br> | |
163 | -João M. M. Silva + Rafael Manzo <jaodsilv@linux.ime.usp.br> | |
164 | -João M. M. Silva + Renan Teruo <jaodsilv@linux.ime.usp.br> | |
165 | -João M. M. da Silva + Alessandro Palmeira + Diego Araújo + Caio Salgado <jaodsilv@linux.ime.usp.br> | |
166 | -João M. M. da Silva + Alessandro Palmeira + Diego Araújo <jaodsilv@linux.ime.usp.br> | |
167 | -João M. M. da Silva + Alessandro Palmeira + João Machini <jaodsilv@linux.ime.usp.br> | |
168 | -João M. M. da Silva + Alessandro Palmeira <jaodsilv@linux.ime.usp.br> | |
169 | -João M. M. da Silva + Caio Salgado + Alessandro Palmeira <jaodsilv@linux.ime.usp.br> | |
170 | -João M. M. da Silva + Caio Salgado <jaodsilv@linux.ime.usp.br> | |
171 | -João M. M. da Silva + Carlos Morais <jaodsilv@linux.ime.usp.br> | |
172 | -João M. M. da Silva + Diego Araújo + Pedro Leal <jaodsilv@linux.ime.usp.br> | |
173 | -João M. M. da Silva + Diego Araújo <diegoamc90@gmail.com> | |
174 | -João M. M. da Silva + Diego Araújo <jaodsilv@linux.ime.usp.br> | |
175 | -João M. M. da Silva + Jefferson Fernandes <jaodsilv@linux.ime.usp.br> | |
176 | -João M. M. da Silva + João M. Miranda <jaodsilv@linux.ime.usp.br> | |
177 | -João M. M. da Silva + Paulo Meirelles <jaodsilv@linux.ime.usp.br> | |
178 | -João M. M. da Silva + Pedro Leal <jaodsilv@linux.ime.usp.br> | |
179 | -João M. M. da Silva + Rafael Manzo + Diego Araújo <jaodsilv@linux.ime.usp.br> | |
180 | -João M. M. da Silva + Rafael Manzo <jaodsilv@linux.ime.usp.br> | |
181 | -João M. M. da Silva + Renan Teruo <jaodsilv@linux.ime.usp.br> | |
182 | -João M. M. da Silva <jaodsilv@linux.ime.usp.br> | |
183 | -João Marco Maciel da Silva + Rafael Manzo + Renan Teruo <jaodsilv@linux.ime.usp.br> | |
184 | -João da Silva + Eduardo Morais + Rafael Manzo <rr.manzo@gmail.com> | |
185 | -João da Silva <jaodsilv@linux.ime.usp.br> | |
186 | -Junior Silva <junior@bajor.localhost.localdomain> | |
187 | -Junior Silva <junior@sedeantigo.colivre.coop.br> | |
70 | +Jose Pedro <1jpsneto@gmail.com> | |
188 | 71 | Junior Silva <juniorsilva1001@gmail.com> |
189 | -Junior Silva <juniorsilva7@juniorsilva-Aspire-5750Z.(none)> | |
190 | -Junior Silva <juniorsilva@colivre.coop.br> | |
191 | -Jérôme Jutteau <j.jutteau@gmail.com> | |
192 | 72 | Keilla Menezes <keilla@colivre.coop.br> |
193 | 73 | Larissa Reis <larissa@colivre.coop.br> |
194 | -Larissa Reis <reiss.larissa@gmail.com> | |
195 | 74 | Leandro Alves <leandrosustenido@gmail.com> |
196 | -Leandro Nunes dos Santos <81665687568@serpro-1541727.(none)> | |
197 | -Leandro Nunes dos Santos <81665687568@serpro-1541727.Home> | |
198 | 75 | Leandro Nunes dos Santos <leandro.santos@serpro.gov.br> |
199 | -Leandro Nunes dos Santos <leandronunes@gmail.com> | |
76 | +Leandro Veloso <leandrovelosorodrigues@gmail.com> | |
200 | 77 | LinguÁgil 2010 <linguagil.bahia@gmail.com> |
78 | +Lucas Couto <loc.unb@gmail.com> | |
201 | 79 | Lucas Kanashiro <kanashiro.duarte@gmail.com> |
202 | -Lucas Melo <lucas@colivre.coop.br> | |
203 | 80 | Lucas Melo <lucaspradomelo@gmail.com> |
204 | -Luciano <lucianopcbr@gmail.com> | |
205 | -Luciano Prestes Cavacanti <lucianopcbr@gmail.com> | |
206 | 81 | Luciano Prestes Cavalcanti <lucianopcbr@gmail.com> |
207 | 82 | Luis David Aguilar Carlos <ludwig9003@gmail.com> |
208 | 83 | Luiz Fernando de Freitas Matos <luiz@luizff.matos@gmail.com> |
209 | -M for Momo <mo@rtnp.org> | |
210 | -Marcelo Júnior <maljunior@gmail.com> | |
211 | -Marcos <marcos.rpj2@gmail.com> | |
84 | +Luiz Matos <luizff.matos@gmail.com> | |
212 | 85 | Marcos Ramos <ms.ramos@outlook.com> |
86 | +Marcos Ronaldo <marcos.rpj2@gmail.com> | |
87 | +Mariel Zasso <noosfero-br@listas.softwarelivre.org> | |
213 | 88 | Martín Olivera <molivera@solar.org.ar> |
89 | +Matheus Faria <matheus.sousa.faria@gmail.com> | |
214 | 90 | Maurilio Atila <cabelotaina@gmail.com> |
91 | +M for Momo <mo@rtnp.org> | |
215 | 92 | Michal Čihař <michal@cihar.com> |
216 | 93 | Michel Felipe <mfelipeof@gmail.com> |
217 | 94 | Moises Machado <moises@colivre.coop.br> |
218 | -Nanda Lopes <nanda.listas+psl@gmail.com> | |
219 | 95 | Naíla Alves <naila@colivre.coop.br> |
96 | +Nanda Lopes <nanda.listas+psl@gmail.com> | |
220 | 97 | Niemand Jedermann <predatorix@web.de> |
221 | 98 | Parley Martins <parleypachecomartins@gmail.com> |
222 | -Paulo Meirelles + Alessandro Palmeira + João M. M. da Silva <paulo@softwarelivre.org> | |
223 | -Paulo Meirelles + Alessandro Palmeira <paulo@softwarelivre.org> | |
224 | -Paulo Meirelles + Carlos Morais <paulo@softwarelivre.org> | |
225 | -Paulo Meirelles + Diego Araújo <paulo@softwarelivre.org> | |
226 | -Paulo Meirelles + João M. M. da Silva <paulo@softwarelivre.org> | |
227 | -Paulo Meirelles + Rafael Manzo <paulo@softwarelivre.org> | |
228 | 99 | Paulo Meirelles <paulo@softwarelivre.org> |
100 | +Pedro de Lyra <pedrodelyra@gmail.com> | |
101 | +Pedro Leal | |
102 | +Rafael de Souza Queiroz <querafael@live.com> | |
229 | 103 | Rafael Gomes <rafaelgomes@techfree.com.br> |
230 | -Rafael Manzo + Alessandro Palmeira <rr.manzo@gmail.com> | |
231 | -Rafael Manzo + Daniel Alves <danpaulalves@gmail.com> | |
232 | -Rafael Manzo + Diego Araújo <rr.manzo@gmail.com> | |
233 | -Rafael Manzo + João M. M. Silva <rr.manzo@gmail.com> | |
234 | -Rafael Manzo + Paulo Meirelles <rr.manzo@gmail.com> | |
235 | 104 | Rafael Martins <rmmartins@gmail.com> |
236 | -Rafael Reggiani Manzo + Caio Salgado + Jefferson Fernandes <rr.manzo@gmail.com> | |
237 | -Rafael Reggiani Manzo + Diego Araujo <diegoamc90@gmail.com> | |
238 | -Rafael Reggiani Manzo + Diego Araujo <rr.manzo@gmail.com> | |
239 | -Rafael Reggiani Manzo + Diego Araújo <rr.manzo@gmail.com> | |
240 | -Rafael Reggiani Manzo + João M. M. da Silva <rr.manzo@gmail.com> | |
241 | 105 | Rafael Reggiani Manzo <rr.manzo@gmail.com> |
242 | 106 | Raphaël Rousseau <raph@r4f.org> |
243 | -Raquel <rcordioli@gmail.com> | |
244 | 107 | Raquel Lira <raquel.lira@gmail.com> |
245 | -Renan Teruo + Caio Salgado <renanteruoc@gmail.com> | |
246 | -Renan Teruo + Diego Araujo <renanteruoc@gmail.com> | |
247 | -Renan Teruo + Diego Araújo <renanteruoc@gmail.com> | |
248 | -Renan Teruo + Paulo Meirelles <renanteruoc@gmail.com> | |
249 | -Renan Teruo + Rafael Manzo <renanteruoc@gmail.com> | |
250 | -Renan Teruoc + Diego Araujo <renanteruoc@gmail.com> | |
251 | -Rodrigo Souto + Ana Losnak + Daniel Bucher + Caio Almeida + Leandro Nunes + Daniela Feitosa + Mariel Zasso <noosfero-br@listas.softwarelivre.org> | |
108 | +Raquel <rcordioli@gmail.com> | |
109 | +Renan Costa <renan2727@hotmail.com> | |
110 | +Renan Teruo <renanteruoc@gmail.com> | |
111 | +Rodrigo Medeiros <rodrigo.mss01@gmail.com> | |
252 | 112 | Rodrigo Souto <rodrigo@colivre.coop.br> |
253 | 113 | Ronny Kursawe <kursawe.ronny@googlemail.com> |
254 | 114 | Samuel R. C. Vale <srcvale@holoscopio.com> |
255 | -TWS <tablettws@gmail.com> | |
256 | -Tallys Martins <tallysmartins@gmail.com> | |
257 | 115 | Tallys Martins <tallysmartins@yahoo.com.br> |
258 | 116 | Thiago Casotti <thiago.casotti@uol.com.br> |
117 | +Thiago Kairala <thiagor.kairala@gmail.com> | |
259 | 118 | Thiago Ribeiro <thiagitosouza@hotmail.com> |
260 | 119 | Thiago Zoroastro <thiago.zoroastro@bol.com.br> |
261 | 120 | Tuux <tuxa@galaxie.eu.org> |
121 | +TWS <tablettws@gmail.com> | |
262 | 122 | Valessio Brito <contato@valessiobrito.com.br> |
263 | -Valessio Brito <contato@valessiobrito.info> | |
264 | -Valessio Brito <valessio@gmail.com> | |
265 | -Victor Carvalho <victorhugodf.ac@gmail.com> | |
266 | 123 | Victor Costa <vfcosta@gmail.com> |
267 | 124 | Victor Hugo Alves de Carvalho <victorhugodf.ac@gmail.com> |
268 | 125 | Vinicius Cubas Brand <viniciuscb@gmail.com> |
269 | -Visita <visita@debian.(none)> | |
126 | +Wilton Rodrigues <braynwilton@gmail.com> | |
270 | 127 | Yann Lugrin <yann.lugrin@liquid-concept.ch> |
271 | -alcampelo <alcampelo@alcampelo.(none)> | |
272 | -analosnak <analosnak@gmail.com> | |
273 | -daniel <dtygel@eita.org.br> | |
274 | -diegoamc <diegoamc90@gmail.com> | |
275 | -dtygel <dtygel@gmail.com> | |
276 | -juniorsilva <juniorsilva@QonoS.localhost.localdomain> | |
277 | -root <root@17edebf1ae91> | |
278 | -root <root@debian.sdr.serpro> | |
279 | -tallys <tallys@tallys.(none)> | |
280 | -tallys <tallys@tallys> | |
281 | -vfcosta <vfcosta@gmail.com> | |
282 | -Ábner Silva de Oliveira <abner.oliveira@serpro.gov.br> | |
283 | 128 | |
284 | 129 | Ideas, specifications and incentive |
285 | 130 | =================================== | ... | ... |
app/controllers/application_controller.rb
... | ... | @@ -7,7 +7,10 @@ class ApplicationController < ActionController::Base |
7 | 7 | before_filter :detect_stuff_by_domain |
8 | 8 | before_filter :init_noosfero_plugins |
9 | 9 | before_filter :allow_cross_domain_access |
10 | + | |
11 | + before_filter :login_from_cookie | |
10 | 12 | before_filter :login_required, :if => :private_environment? |
13 | + | |
11 | 14 | before_filter :verify_members_whitelist, :if => [:private_environment?, :user] |
12 | 15 | before_filter :redirect_to_current_user |
13 | 16 | ... | ... |
app/controllers/my_profile/cms_controller.rb
... | ... | @@ -111,10 +111,7 @@ class CmsController < MyProfileController |
111 | 111 | end |
112 | 112 | end |
113 | 113 | |
114 | - unless @article.kind_of?(RssFeed) | |
115 | - @escaped_body = CGI::escapeHTML(@article.body || '') | |
116 | - @escaped_abstract = CGI::escapeHTML(@article.abstract || '') | |
117 | - end | |
114 | + escape_fields @article | |
118 | 115 | end |
119 | 116 | |
120 | 117 | def new |
... | ... | @@ -185,6 +182,8 @@ class CmsController < MyProfileController |
185 | 182 | end |
186 | 183 | end |
187 | 184 | |
185 | + escape_fields @article | |
186 | + | |
188 | 187 | render :action => 'edit' |
189 | 188 | end |
190 | 189 | |
... | ... | @@ -534,4 +533,10 @@ class CmsController < MyProfileController |
534 | 533 | end |
535 | 534 | end |
536 | 535 | |
536 | + def escape_fields article | |
537 | + unless article.kind_of?(RssFeed) | |
538 | + @escaped_body = CGI::escapeHTML(article.body || '') | |
539 | + @escaped_abstract = CGI::escapeHTML(article.abstract || '') | |
540 | + end | |
541 | + end | |
537 | 542 | end | ... | ... |
app/controllers/my_profile/enterprise_validation_controller.rb
1 | 1 | class EnterpriseValidationController < MyProfileController |
2 | 2 | |
3 | 3 | protect 'validate_enterprise', :profile |
4 | - | |
4 | + | |
5 | 5 | def index |
6 | 6 | @pending_validations = profile.pending_validations |
7 | 7 | end |
... | ... | @@ -27,7 +27,7 @@ class EnterpriseValidationController < MyProfileController |
27 | 27 | post_only :reject |
28 | 28 | def reject |
29 | 29 | @pending = profile.find_pending_validation(params[:id]) |
30 | - if @pending | |
30 | + if @pending | |
31 | 31 | @pending.reject_explanation = params[:reject_explanation] |
32 | 32 | begin |
33 | 33 | @pending.reject | ... | ... |
app/controllers/my_profile/favorite_enterprises_controller.rb
1 | 1 | class FavoriteEnterprisesController < MyProfileController |
2 | - | |
3 | -# protect 'manage_favorite_enteprises', :profile | |
2 | + | |
3 | +# protect 'manage_favorite_enterprises', :profile | |
4 | 4 | |
5 | 5 | requires_profile_class Person |
6 | - | |
6 | + | |
7 | 7 | def index |
8 | 8 | @favorite_enterprises = profile.favorite_enterprises |
9 | 9 | end |
... | ... | @@ -12,7 +12,7 @@ class FavoriteEnterprisesController < MyProfileController |
12 | 12 | @favorite_enterprise = Enterprise.find(params[:id]) |
13 | 13 | if request.post? && params[:confirmation] |
14 | 14 | profile.favorite_enterprises << @favorite_enterprise |
15 | - redirect_to :action => 'index' | |
15 | + redirect_to :action => 'index' | |
16 | 16 | end |
17 | 17 | end |
18 | 18 | ... | ... |
app/controllers/my_profile/profile_editor_controller.rb
... | ... | @@ -5,6 +5,7 @@ class ProfileEditorController < MyProfileController |
5 | 5 | |
6 | 6 | before_filter :access_welcome_page, :only => [:welcome_page] |
7 | 7 | before_filter :back_to |
8 | + before_filter :forbid_destroy_profile, :only => [:destroy_profile] | |
8 | 9 | helper_method :has_welcome_page |
9 | 10 | |
10 | 11 | def index |
... | ... | @@ -109,7 +110,7 @@ class ProfileEditorController < MyProfileController |
109 | 110 | profile = environment.profiles.find(params[:id]) |
110 | 111 | if profile.disable |
111 | 112 | profile.save |
112 | - session[:notice] = _("The profile '#{profile.name}' was deactivated.") | |
113 | + session[:notice] = _("The profile '%s' was deactivated.") % profile.name | |
113 | 114 | else |
114 | 115 | session[:notice] = _('Could not deactivate profile.') |
115 | 116 | end |
... | ... | @@ -123,7 +124,7 @@ class ProfileEditorController < MyProfileController |
123 | 124 | profile = environment.profiles.find(params[:id]) |
124 | 125 | |
125 | 126 | if profile.enable |
126 | - session[:notice] = _("The profile '#{profile.name}' was activated.") | |
127 | + session[:notice] = _("The profile '%s' was activated.") % profile.name | |
127 | 128 | else |
128 | 129 | session[:notice] = _('Could not activate the profile.') |
129 | 130 | end |
... | ... | @@ -162,4 +163,10 @@ class ProfileEditorController < MyProfileController |
162 | 163 | end |
163 | 164 | end |
164 | 165 | |
166 | + def forbid_destroy_profile | |
167 | + if environment.enabled?('forbid_destroy_profile') && !current_person.is_admin?(environment) | |
168 | + session[:notice] = _('You can not destroy the profile.') | |
169 | + redirect_to_previous_location | |
170 | + end | |
171 | + end | |
165 | 172 | end | ... | ... |
app/controllers/public/account_controller.rb
... | ... | @@ -46,14 +46,20 @@ class AccountController < ApplicationController |
46 | 46 | |
47 | 47 | self.current_user = plugins_alternative_authentication |
48 | 48 | |
49 | - self.current_user ||= User.authenticate(params[:user][:login], params[:user][:password], environment) if params[:user] | |
50 | - | |
49 | + begin | |
50 | + self.current_user ||= User.authenticate(params[:user][:login], params[:user][:password], environment) if params[:user] | |
51 | + rescue User::UserNotActivated => e | |
52 | + session[:notice] = e.message | |
53 | + return | |
54 | + end | |
51 | 55 | if logged_in? |
52 | 56 | check_join_in_community(self.current_user) |
57 | + | |
53 | 58 | if params[:remember_me] == "1" |
54 | 59 | self.current_user.remember_me |
55 | - cookies[:auth_token] = { :value => self.current_user.remember_token , :expires => self.current_user.remember_token_expires_at } | |
60 | + cookies[:auth_token] = {value: self.current_user.remember_token, expires: self.current_user.remember_token_expires_at} | |
56 | 61 | end |
62 | + | |
57 | 63 | if redirect? |
58 | 64 | go_to_initial_page |
59 | 65 | session[:notice] = _("Logged in successfully") |
... | ... | @@ -92,6 +98,7 @@ class AccountController < ApplicationController |
92 | 98 | @invitation_code = params[:invitation_code] |
93 | 99 | begin |
94 | 100 | @user = User.build(params[:user], params[:profile_data], environment) |
101 | + @user.session = session | |
95 | 102 | @terms_of_use = environment.terms_of_use |
96 | 103 | @user.return_to = session[:return_to] |
97 | 104 | @person = Person.new(params[:profile_data]) |
... | ... | @@ -432,7 +439,7 @@ class AccountController < ApplicationController |
432 | 439 | end |
433 | 440 | |
434 | 441 | def go_to_signup_initial_page |
435 | - check_redirection_options(user, user.environment.redirection_after_signup, user.url) | |
442 | + check_redirection_options user, user.environment.redirection_after_signup, user.url, signup: true | |
436 | 443 | end |
437 | 444 | |
438 | 445 | def redirect_if_logged_in |
... | ... | @@ -452,8 +459,11 @@ class AccountController < ApplicationController |
452 | 459 | |
453 | 460 | protected |
454 | 461 | |
455 | - def check_redirection_options(user, condition, default) | |
456 | - case condition | |
462 | + def check_redirection_options user, condition, default, options={} | |
463 | + if options[:signup] and target = session.delete(:after_signup_redirect_to) | |
464 | + redirect_to target | |
465 | + else | |
466 | + case condition | |
457 | 467 | when 'keep_on_same_page' |
458 | 468 | redirect_back_or_default(user.admin_url) |
459 | 469 | when 'site_homepage' |
... | ... | @@ -466,8 +476,11 @@ class AccountController < ApplicationController |
466 | 476 | redirect_to user.admin_url |
467 | 477 | when 'welcome_page' |
468 | 478 | redirect_to :controller => :home, :action => :welcome, :template_id => (user.template && user.template.id) |
469 | - else | |
470 | - redirect_back_or_default(default) | |
479 | + when 'custom_url' | |
480 | + if (url = user.custom_url_redirection).present? then redirect_to url else redirect_back_or_default default end | |
481 | + else | |
482 | + redirect_back_or_default(default) | |
483 | + end | |
471 | 484 | end |
472 | 485 | end |
473 | 486 | ... | ... |
app/controllers/public/profile_controller.rb
... | ... | @@ -6,6 +6,7 @@ class ProfileController < PublicController |
6 | 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 | 8 | helper TagsHelper |
9 | + helper ActionTrackerHelper | |
9 | 10 | |
10 | 11 | protect 'send_mail_to_members', :profile, :only => [:send_mail] |
11 | 12 | ... | ... |
app/controllers/public/search_controller.rb
... | ... | @@ -92,10 +92,10 @@ class SearchController < PublicController |
92 | 92 | |
93 | 93 | def events |
94 | 94 | if params[:year].blank? && params[:year].blank? && params[:day].blank? |
95 | - @date = Date.today | |
95 | + @date = DateTime.now | |
96 | 96 | else |
97 | - year = (params[:year] ? params[:year].to_i : Date.today.year) | |
98 | - month = (params[:month] ? params[:month].to_i : Date.today.month) | |
97 | + year = (params[:year] ? params[:year].to_i : DateTime.now.year) | |
98 | + month = (params[:month] ? params[:month].to_i : DateTime.now.month) | |
99 | 99 | day = (params[:day] ? params[:day].to_i : 1) |
100 | 100 | @date = build_date(year, month, day) |
101 | 101 | end |
... | ... | @@ -106,9 +106,7 @@ class SearchController < PublicController |
106 | 106 | @events = @category ? |
107 | 107 | environment.events.by_day(@date).in_category(Category.find(@category_id)).paginate(:per_page => per_page, :page => params[:page]) : |
108 | 108 | environment.events.by_day(@date).paginate(:per_page => per_page, :page => params[:page]) |
109 | - end | |
110 | - | |
111 | - if params[:year] || params[:month] | |
109 | + elsif params[:year] || params[:month] | |
112 | 110 | @events = @category ? |
113 | 111 | environment.events.by_month(@date).in_category(Category.find(@category_id)).paginate(:per_page => per_page, :page => params[:page]) : |
114 | 112 | environment.events.by_month(@date).paginate(:per_page => per_page, :page => params[:page]) | ... | ... |
... | ... | @@ -0,0 +1,94 @@ |
1 | +module ActionTrackerHelper | |
2 | + | |
3 | + def create_article_description ta | |
4 | + _('published an article: %{title}') % { title: link_to(truncate(ta.get_name), ta.get_url) } | |
5 | + end | |
6 | + | |
7 | + def new_friendship_description ta | |
8 | + n_('has made 1 new friend:<br />%{name}', 'has made %{num} new friends:<br />%{name}', ta.get_friend_name.size) % { | |
9 | + num: ta.get_friend_name.size, | |
10 | + name: ta.collect_group_with_index(:friend_name) do |n,i| | |
11 | + link_to image_tag(ta.get_friend_profile_custom_icon[i] || default_or_themed_icon("/images/icons-app/person-icon.png")), | |
12 | + ta.get_friend_url[i], title: n | |
13 | + end.join | |
14 | + } | |
15 | + end | |
16 | + | |
17 | + def join_community_description ta | |
18 | + n_('has joined 1 community:<br />%{name}', 'has joined %{num} communities:<br />%{name}', ta.get_resource_name.size) % { | |
19 | + num: ta.get_resource_name.size, | |
20 | + name: ta.collect_group_with_index(:resource_name) do |n,i| | |
21 | + link_to image_tag(ta.get_resource_profile_custom_icon[i] || default_or_themed_icon("/images/icons-app/community-icon.png")), | |
22 | + ta.get_resource_url[i], title: n | |
23 | + end.join | |
24 | + } | |
25 | + end | |
26 | + | |
27 | + def add_member_in_community_description ta | |
28 | + _('has joined the community.') | |
29 | + end | |
30 | + | |
31 | + def upload_image_description ta | |
32 | + total = ta.get_view_url.size | |
33 | + (n_('uploaded 1 image', 'uploaded %d images', total) % total) + | |
34 | + tag(:br) + | |
35 | + ta.collect_group_with_index(:thumbnail_path) do |t,i| | |
36 | + if total == 1 | |
37 | + link_to image_tag(t), ta.get_view_url[i], class: 'upimg' | |
38 | + else | |
39 | + pos = total-i; | |
40 | + morethen2 = pos>2 ? 'morethen2' : '' | |
41 | + morethen5 = pos>5 ? 'morethen5' : '' | |
42 | + t = t.gsub(/(.*)(display)(.*)/, '\\1thumb\\3') | |
43 | + | |
44 | + link_to ' '.html_safe, ta.get_view_url[i], | |
45 | + style: "background-image:url(#{t})", | |
46 | + class: "upimg pos#{pos} #{morethen2} #{morethen5}" | |
47 | + end | |
48 | + end.reverse.join + | |
49 | + if total <= 5 then ''.html_safe else content_tag :span, '…'.html_safe, | |
50 | + class: 'more', onclick: "this.parentNode.className+=' show-all'" end + | |
51 | + tag(:br, style: 'clear: both') | |
52 | + end | |
53 | + | |
54 | + def reply_scrap_description ta | |
55 | + _('sent a message to %{receiver}: <br /> "%{message}"') % { | |
56 | + receiver: link_to(ta.get_receiver_name, ta.get_receiver_url), | |
57 | + message: auto_link_urls(ta.get_content) | |
58 | + } | |
59 | + end | |
60 | + | |
61 | + alias :leave_scrap_description :reply_scrap_description | |
62 | + alias :reply_scrap_on_self_description :reply_scrap_description | |
63 | + | |
64 | + def leave_scrap_to_self_description ta | |
65 | + _('wrote: <br /> "%{text}"') % { | |
66 | + text: auto_link_urls(ta.get_content) | |
67 | + } | |
68 | + end | |
69 | + | |
70 | + def create_product_description | |
71 | + _('created the product %{title}') % { | |
72 | + title: link_to(truncate(ta.get_name), ta.get_url), | |
73 | + } | |
74 | + end | |
75 | + | |
76 | + def update_product_description | |
77 | + _('updated the product %{title}') % { | |
78 | + title: link_to(truncate(ta.get_name), ta.get_url), | |
79 | + } | |
80 | + end | |
81 | + | |
82 | + def remove_product_description | |
83 | + _('removed the product %{title}') % { | |
84 | + title: truncate(ta.get_name), | |
85 | + } | |
86 | + end | |
87 | + | |
88 | + def favorite_enterprise_description ta | |
89 | + _('favorited enterprise %{title}') % { | |
90 | + title: link_to(truncate(ta.get_enterprise_name), ta.get_enterprise_url), | |
91 | + } | |
92 | + end | |
93 | + | |
94 | +end | ... | ... |
app/helpers/application_helper.rb
app/helpers/article_helper.rb
... | ... | @@ -88,7 +88,7 @@ module ArticleHelper |
88 | 88 | content_tag( 'small', _('Who will be able to create new topics on this forum?')) + |
89 | 89 | content_tag('div', '', slider_options) + |
90 | 90 | hidden_field_tag('article[topic_creation]', article.topic_creation) + |
91 | - javascript_include_tag('topic-creation-config') | |
91 | + javascript_include_tag("#{Noosfero.root}/assets/topic-creation-config.js") | |
92 | 92 | end |
93 | 93 | |
94 | 94 | def privacity_exceptions(article, tokenized_children) | ... | ... |
app/helpers/blog_helper.rb
... | ... | @@ -6,7 +6,13 @@ module BlogHelper |
6 | 6 | @article = article |
7 | 7 | hidden_field_tag('article[published]', 1) + |
8 | 8 | hidden_field_tag('article[accept_comments]', 0) + |
9 | - visibility_options(article,tokenized_children) | |
9 | + visibility_options(article,tokenized_children) + | |
10 | + content_tag('h4', _('Visualization of posts')) + | |
11 | + content_tag( | |
12 | + 'div', | |
13 | + check_box(:article, :display_preview) + | |
14 | + content_tag('label', _('I want to display the preview of posts before the text'), :for => 'article_display_preview') | |
15 | + ) | |
10 | 16 | end |
11 | 17 | |
12 | 18 | def cms_label_for_new_children | ... | ... |
app/helpers/content_viewer_helper.rb
... | ... | @@ -51,7 +51,7 @@ module ContentViewerHelper |
51 | 51 | elsif date_format == 'past_time' |
52 | 52 | left_time = true |
53 | 53 | end |
54 | - content_tag('span', show_date(article.published_at, use_numbers , year, left_time), :class => 'date') | |
54 | + content_tag('span', show_time(article.published_at, use_numbers , year, left_time), :class => 'date') | |
55 | 55 | end |
56 | 56 | |
57 | 57 | def link_to_comments(article, args = {}) | ... | ... |
app/helpers/dates_helper.rb
... | ... | @@ -43,9 +43,14 @@ module DatesHelper |
43 | 43 | end |
44 | 44 | |
45 | 45 | # formats a datetime for displaying. |
46 | - def show_time(time) | |
47 | - if time | |
48 | - _('%{day} %{month} %{year}, %{hour}:%{minutes}') % { :year => time.year, :month => month_name(time.month), :day => time.day, :hour => time.hour, :minutes => time.strftime("%M") } | |
46 | + def show_time(time, use_numbers = false, year = true, left_time = false) | |
47 | + if time && use_numbers | |
48 | + _('%{month}/%{day}/%{year}, %{hour}:%{minutes}') % { :year => (year ? time.year : ''), :month => time.month, :day => time.day, :hour => time.hour, :minutes => time.strftime("%M") } | |
49 | + elsif time && left_time | |
50 | + date_format = time_ago_in_words(time) | |
51 | + elsif time | |
52 | + date_format = year ? _('%{month_name} %{day}, %{year} %{hour}:%{minutes}') : _('%{month_name} %{day} %{hour}:%{minutes}') | |
53 | + date_format % { :day => time.day, :month_name => month_name(time.month), :year => time.year, :hour => time.hour, :minutes => time.strftime("%M") } | |
49 | 54 | else |
50 | 55 | '' |
51 | 56 | end |
... | ... | @@ -53,7 +58,7 @@ module DatesHelper |
53 | 58 | |
54 | 59 | def show_period(date1, date2 = nil, use_numbers = false) |
55 | 60 | if (date1 == date2) || (date2.nil?) |
56 | - show_date(date1, use_numbers) | |
61 | + show_time(date1, use_numbers) | |
57 | 62 | else |
58 | 63 | if date1.year == date2.year |
59 | 64 | if date1.month == date2.month |
... | ... | @@ -72,8 +77,8 @@ module DatesHelper |
72 | 77 | end |
73 | 78 | else |
74 | 79 | _('from %{date1} to %{date2}') % { |
75 | - :date1 => show_date(date1, use_numbers), | |
76 | - :date2 => show_date(date2, use_numbers) | |
80 | + :date1 => show_time(date1, use_numbers), | |
81 | + :date2 => show_time(date2, use_numbers) | |
77 | 82 | } |
78 | 83 | end |
79 | 84 | end |
... | ... | @@ -106,18 +111,18 @@ module DatesHelper |
106 | 111 | |
107 | 112 | def build_date(year, month, day = 1) |
108 | 113 | if year.blank? and month.blank? and day.blank? |
109 | - Date.today | |
114 | + DateTime.now | |
110 | 115 | else |
111 | 116 | if year.blank? |
112 | - year = Date.today.year | |
117 | + year = DateTime.now.year | |
113 | 118 | end |
114 | 119 | if month.blank? |
115 | - month = Date.today.month | |
120 | + month = DateTime.now.month | |
116 | 121 | end |
117 | 122 | if day.blank? |
118 | 123 | day = 1 |
119 | 124 | end |
120 | - Date.new(year.to_i, month.to_i, day.to_i) | |
125 | + DateTime.new(year.to_i, month.to_i, day.to_i) | |
121 | 126 | end |
122 | 127 | end |
123 | 128 | ... | ... |
app/helpers/events_helper.rb
... | ... | @@ -16,7 +16,7 @@ module EventsHelper |
16 | 16 | |
17 | 17 | content_tag( 'tr', |
18 | 18 | content_tag('td', |
19 | - content_tag('div', show_date(article.start_date) + ( article.end_date.nil? ? '' : (_(" to ") + show_date(article.end_date))),:class => 'event-date' ) + | |
19 | + content_tag('div', show_time(article.start_date) + ( article.end_date.nil? ? '' : (_(" to ") + show_time(article.end_date))),:class => 'event-date' ) + | |
20 | 20 | content_tag('div',link_to(article.name,article.url),:class => 'event-title') + |
21 | 21 | content_tag('div',(article.address.nil? or article.address == '') ? '' : (_('Place: ') + article.address),:class => 'event-place') |
22 | 22 | ) |
... | ... | @@ -30,7 +30,7 @@ module EventsHelper |
30 | 30 | # the day itself |
31 | 31 | date, |
32 | 32 | # is there any events in this date? |
33 | - events.any? {|event| event.date_range.include?(date)}, | |
33 | + events.any? {|event| event.date_range.cover?(date)}, | |
34 | 34 | # is this date in the current month? |
35 | 35 | true |
36 | 36 | ] | ... | ... |
app/helpers/forms_helper.rb
... | ... | @@ -151,7 +151,7 @@ module FormsHelper |
151 | 151 | datepicker_options[:close_text] ||= _('Done') |
152 | 152 | datepicker_options[:constrain_input] ||= true |
153 | 153 | datepicker_options[:current_text] ||= _('Today') |
154 | - datepicker_options[:date_format] ||= 'mm/dd/yy' | |
154 | + datepicker_options[:date_format] ||= 'yy/mm/dd' | |
155 | 155 | datepicker_options[:day_names] ||= [_('Sunday'), _('Monday'), _('Tuesday'), _('Wednesday'), _('Thursday'), _('Friday'), _('Saturday')] |
156 | 156 | datepicker_options[:day_names_min] ||= [_('Su'), _('Mo'), _('Tu'), _('We'), _('Th'), _('Fr'), _('Sa')] |
157 | 157 | datepicker_options[:day_names_short] ||= [_('Sun'), _('Mon'), _('Tue'), _('Wed'), _('Thu'), _('Fri'), _('Sat')] |
... | ... | @@ -236,7 +236,7 @@ module FormsHelper |
236 | 236 | weekHeader: #{datepicker_options[:week_header].to_json}, |
237 | 237 | yearRange: #{datepicker_options[:year_range].to_json}, |
238 | 238 | yearSuffix: #{datepicker_options[:year_suffix].to_json} |
239 | - }) | |
239 | + }).datepicker('setDate', new Date('#{value}')) | |
240 | 240 | </script> |
241 | 241 | ".html_safe |
242 | 242 | result | ... | ... |
app/helpers/layout_helper.rb
... | ... | @@ -77,15 +77,8 @@ module LayoutHelper |
77 | 77 | |
78 | 78 | |
79 | 79 | def icon_theme_stylesheet_path |
80 | - icon_themes = [] | |
81 | 80 | theme_icon_themes = theme_option(:icon_theme) || [] |
82 | - for icon_theme in theme_icon_themes do | |
83 | - theme_path = "designs/icons/#{icon_theme}/style.css" | |
84 | - if File.exists?(Rails.root.join('public', theme_path)) | |
85 | - icon_themes << theme_path | |
86 | - end | |
87 | - end | |
88 | - icon_themes | |
81 | + theme_icon_themes.map{ |it| "designs/icons/#{it}/style.css" } | |
89 | 82 | end |
90 | 83 | |
91 | 84 | def jquery_ui_theme_stylesheet_path |
... | ... | @@ -93,7 +86,7 @@ module LayoutHelper |
93 | 86 | end |
94 | 87 | |
95 | 88 | def theme_stylesheet_path |
96 | - "/assets#{theme_path}/style.css" | |
89 | + "#{theme_path}/style.css".gsub(%r{^/}, '') | |
97 | 90 | end |
98 | 91 | |
99 | 92 | def layout_template | ... | ... |
app/mailers/scrap_notifier.rb
app/models/add_member.rb
... | ... | @@ -29,7 +29,8 @@ class AddMember < Task |
29 | 29 | end |
30 | 30 | |
31 | 31 | def information |
32 | - {:message => _('%{requestor} wants to be a member of this community.')} | |
32 | + {:message => _("%{requestor} wants to be a member of '%{organization}'."), | |
33 | + variables: {requestor: requestor.name, organization: organization.name}} | |
33 | 34 | end |
34 | 35 | |
35 | 36 | def accept_details |
... | ... | @@ -45,7 +46,7 @@ class AddMember < Task |
45 | 46 | end |
46 | 47 | |
47 | 48 | def target_notification_description |
48 | - _('%{requestor} wants to be a member of this community.') % {:requestor => requestor.name} | |
49 | + _("%{requestor} wants to be a member of '%{organization}'.") % {:requestor => requestor.name, :organization => organization.name} | |
49 | 50 | end |
50 | 51 | |
51 | 52 | def target_notification_message | ... | ... |
app/models/article.rb
... | ... | @@ -8,7 +8,8 @@ class Article < ActiveRecord::Base |
8 | 8 | :accept_comments, :feed, :published, :source, :source_name, |
9 | 9 | :highlighted, :notify_comments, :display_hits, :slug, |
10 | 10 | :external_feed_builder, :display_versions, :external_link, |
11 | - :image_builder, :show_to_followers | |
11 | + :image_builder, :show_to_followers, | |
12 | + :author, :display_preview | |
12 | 13 | |
13 | 14 | acts_as_having_image |
14 | 15 | |
... | ... | @@ -641,6 +642,20 @@ class Article < ActiveRecord::Base |
641 | 642 | can_display_hits? && display_hits |
642 | 643 | end |
643 | 644 | |
645 | + def display_media_panel? | |
646 | + can_display_media_panel? && environment.enabled?('media_panel') | |
647 | + end | |
648 | + | |
649 | + def can_display_media_panel? | |
650 | + false | |
651 | + end | |
652 | + | |
653 | + settings_items :display_preview, :type => :boolean, :default => false | |
654 | + | |
655 | + def display_preview? | |
656 | + false | |
657 | + end | |
658 | + | |
644 | 659 | def image? |
645 | 660 | false |
646 | 661 | end |
... | ... | @@ -754,9 +769,10 @@ class Article < ActiveRecord::Base |
754 | 769 | end |
755 | 770 | |
756 | 771 | def body_images_paths |
757 | - require 'uri' | |
758 | 772 | Nokogiri::HTML.fragment(self.body.to_s).css('img[src]').collect do |i| |
759 | - (self.profile && self.profile.environment) ? URI.join(self.profile.environment.top_url, URI.escape(i['src'])).to_s : i['src'] | |
773 | + src = i['src'] | |
774 | + src = URI.escape src if self.new_record? # xss_terminate runs on save | |
775 | + (self.profile && self.profile.environment) ? URI.join(self.profile.environment.top_url, src).to_s : src | |
760 | 776 | end |
761 | 777 | end |
762 | 778 | ... | ... |
app/models/category.rb
... | ... | @@ -81,7 +81,7 @@ class Category < ActiveRecord::Base |
81 | 81 | end |
82 | 82 | |
83 | 83 | def upcoming_events(limit = 10) |
84 | - self.events.paginate(:conditions => [ 'start_date >= ?', Date.today ], :order => 'start_date', :page => 1, :per_page => limit) | |
84 | + self.events.paginate(:conditions => [ 'start_date >= ?', DateTime.now.beginning_of_day ], :order => 'start_date', :page => 1, :per_page => limit) | |
85 | 85 | end |
86 | 86 | |
87 | 87 | def display_in_menu? | ... | ... |
app/models/community.rb
... | ... | @@ -86,8 +86,8 @@ class Community < Organization |
86 | 86 | {:title => _('Community Info and settings'), :icon => 'edit-profile-group'} |
87 | 87 | end |
88 | 88 | |
89 | - def activities | |
90 | - Scrap.find_by_sql("SELECT id, updated_at, '#{Scrap.to_s}' AS klass FROM #{Scrap.table_name} WHERE scraps.receiver_id = #{self.id} AND scraps.scrap_id IS NULL UNION SELECT id, updated_at, '#{ActionTracker::Record.to_s}' AS klass FROM #{ActionTracker::Record.table_name} WHERE action_tracker.target_id = #{self.id} and action_tracker.verb != 'join_community' and action_tracker.verb != 'leave_scrap' UNION SELECT at.id, at.updated_at, '#{ActionTracker::Record.to_s}' AS klass FROM #{ActionTracker::Record.table_name} at INNER JOIN articles a ON at.target_id = a.id WHERE a.profile_id = #{self.id} AND at.target_type = 'Article' ORDER BY updated_at DESC") | |
89 | + def exclude_verbs_on_activities | |
90 | + %w[join_community leave_scrap] | |
91 | 91 | end |
92 | 92 | |
93 | 93 | end | ... | ... |
app/models/enterprise.rb
... | ... | @@ -15,12 +15,15 @@ class Enterprise < Organization |
15 | 15 | |
16 | 16 | N_('Enterprise') |
17 | 17 | |
18 | - has_many :products, :foreign_key => :profile_id, :dependent => :destroy, :order => 'name ASC' | |
18 | + acts_as_trackable after_add: proc{ |p, t| notify_activity t } | |
19 | + | |
20 | + has_many :products, :foreign_key => :profile_id, :dependent => :destroy | |
21 | + has_many :product_categories, :through => :products | |
19 | 22 | has_many :inputs, :through => :products |
20 | 23 | has_many :production_costs, :as => :owner |
21 | 24 | |
22 | 25 | has_many :favorite_enterprise_people |
23 | - has_many :fans, through: :favorite_enterprise_people, source: :person | |
26 | + has_many :fans, source: :person, through: :favorite_enterprise_people | |
24 | 27 | |
25 | 28 | def product_categories |
26 | 29 | ProductCategory.by_enterprise(self) |
... | ... | @@ -194,10 +197,6 @@ class Enterprise < Organization |
194 | 197 | true |
195 | 198 | end |
196 | 199 | |
197 | - def activities | |
198 | - Scrap.find_by_sql("SELECT id, updated_at, 'Scrap' AS klass FROM scraps WHERE scraps.receiver_id = #{self.id} AND scraps.scrap_id IS NULL UNION SELECT id, updated_at, 'ActionTracker::Record' AS klass FROM action_tracker WHERE action_tracker.target_id = #{self.id} UNION SELECT action_tracker.id, action_tracker.updated_at, 'ActionTracker::Record' AS klass FROM action_tracker INNER JOIN articles ON action_tracker.target_id = articles.id WHERE articles.profile_id = #{self.id} AND action_tracker.target_type = 'Article' ORDER BY updated_at DESC") | |
199 | - end | |
200 | - | |
201 | 200 | def catalog_url |
202 | 201 | { :profile => identifier, :controller => 'catalog'} |
203 | 202 | end |
... | ... | @@ -206,4 +205,9 @@ class Enterprise < Organization |
206 | 205 | '' |
207 | 206 | end |
208 | 207 | |
208 | + def followed_by? person | |
209 | + super or self.fans.where(id: person.id).count > 0 | |
210 | + end | |
211 | + | |
212 | + | |
209 | 213 | end | ... | ... |
app/models/enterprise_homepage.rb
app/models/environment.rb
... | ... | @@ -13,7 +13,7 @@ class Environment < ActiveRecord::Base |
13 | 13 | :reports_lower_bound, :noreply_email, |
14 | 14 | :signup_welcome_screen_body, :members_whitelist_enabled, |
15 | 15 | :members_whitelist, :highlighted_news_amount, |
16 | - :portal_news_amount, :date_format | |
16 | + :portal_news_amount, :date_format, :signup_intro | |
17 | 17 | |
18 | 18 | has_many :users |
19 | 19 | |
... | ... | @@ -128,6 +128,7 @@ class Environment < ActiveRecord::Base |
128 | 128 | 'disable_select_city_for_contact' => _('Disable state/city select for contact form'), |
129 | 129 | 'disable_contact_person' => _('Disable contact for people'), |
130 | 130 | 'disable_contact_community' => _('Disable contact for groups/communities'), |
131 | + 'forbid_destroy_profile' => _('Forbid users of removing profiles'), | |
131 | 132 | |
132 | 133 | 'products_for_enterprises' => _('Enable products for enterprises'), |
133 | 134 | 'enterprise_registration' => _('Enterprise registration'), |
... | ... | @@ -167,7 +168,8 @@ class Environment < ActiveRecord::Base |
167 | 168 | 'site_homepage' => _('Redirects the user to the environment homepage.'), |
168 | 169 | 'user_profile_page' => _('Redirects the user to his profile page.'), |
169 | 170 | 'user_homepage' => _('Redirects the user to his homepage.'), |
170 | - 'user_control_panel' => _('Redirects the user to his control panel.') | |
171 | + 'user_control_panel' => _('Redirects the user to his control panel.'), | |
172 | + 'custom_url' => _('Specify the URL to redirect to:'), | |
171 | 173 | } |
172 | 174 | end |
173 | 175 | validates_inclusion_of :redirection_after_login, :in => Environment.login_redirection_options.keys, :allow_nil => true |
... | ... | @@ -248,6 +250,9 @@ class Environment < ActiveRecord::Base |
248 | 250 | # store the Environment settings as YAML-serialized Hash. |
249 | 251 | acts_as_having_settings :field => :settings |
250 | 252 | |
253 | + # introduce and explain to users something about the signup | |
254 | + settings_items :signup_intro, :type => String | |
255 | + | |
251 | 256 | # the environment's terms of use: every user must accept them before registering. |
252 | 257 | settings_items :terms_of_use, :type => String |
253 | 258 | |
... | ... | @@ -282,7 +287,20 @@ class Environment < ActiveRecord::Base |
282 | 287 | settings_items :activation_blocked_text, :type => String |
283 | 288 | settings_items :message_for_disabled_enterprise, :type => String, |
284 | 289 | :default => _('This enterprise needs to be enabled.') |
285 | - settings_items :location, :type => String | |
290 | + | |
291 | + settings_items :contact_phone, type: String | |
292 | + settings_items :address, type: String | |
293 | + settings_items :city, type: String | |
294 | + settings_items :state, type: String | |
295 | + settings_items :country_name, type: String | |
296 | + settings_items :lat, type: Float | |
297 | + settings_items :lng, type: Float | |
298 | + settings_items :postal_code, type: String | |
299 | + settings_items :location, type: String | |
300 | + | |
301 | + alias_method :zip_code=, :postal_code | |
302 | + alias_method :zip_code, :postal_code | |
303 | + | |
286 | 304 | settings_items :layout_template, :type => String, :default => 'default' |
287 | 305 | settings_items :homepage, :type => String |
288 | 306 | settings_items :description, :type => String, :default => '<div style="text-align: center"><a href="http://noosfero.org/"><img src="/images/noosfero-network.png" alt="Noosfero"/></a></div>' | ... | ... |
app/models/event.rb
... | ... | @@ -23,7 +23,7 @@ class Event < Article |
23 | 23 | |
24 | 24 | def initialize(*args) |
25 | 25 | super(*args) |
26 | - self.start_date ||= Date.today | |
26 | + self.start_date ||= DateTime.now | |
27 | 27 | end |
28 | 28 | |
29 | 29 | validates_presence_of :title, :start_date |
... | ... | @@ -35,7 +35,7 @@ class Event < Article |
35 | 35 | end |
36 | 36 | |
37 | 37 | scope :by_day, lambda { |date| |
38 | - { :conditions => ['start_date = :date AND end_date IS NULL OR (start_date <= :date AND end_date >= :date)', {:date => date}], | |
38 | + { :conditions => [' start_date >= :start_date AND start_date <= :end_date AND end_date IS NULL OR (start_date <= :end_date AND end_date >= :start_date)', {:start_date => date.beginning_of_day, :end_date => date.end_of_day}], | |
39 | 39 | :order => 'start_date ASC' |
40 | 40 | } |
41 | 41 | } |
... | ... | @@ -80,7 +80,7 @@ class Event < Article |
80 | 80 | |
81 | 81 | def self.date_range(year, month) |
82 | 82 | if year.nil? || month.nil? |
83 | - today = Date.today | |
83 | + today = DateTime.now | |
84 | 84 | year = today.year |
85 | 85 | month = today.month |
86 | 86 | else |
... | ... | @@ -88,7 +88,7 @@ class Event < Article |
88 | 88 | month = month.to_i |
89 | 89 | end |
90 | 90 | |
91 | - first_day = Date.new(year, month, 1) | |
91 | + first_day = DateTime.new(year, month, 1) | |
92 | 92 | last_day = first_day + 1.month - 1.day |
93 | 93 | |
94 | 94 | first_day..last_day |
... | ... | @@ -114,7 +114,7 @@ class Event < Article |
114 | 114 | end |
115 | 115 | |
116 | 116 | def duration |
117 | - ((self.end_date || self.start_date) - self.start_date).to_i | |
117 | + (((self.end_date || self.start_date) - self.start_date).to_i/60/60/24) | |
118 | 118 | end |
119 | 119 | |
120 | 120 | alias_method :article_lead, :lead |
... | ... | @@ -134,6 +134,10 @@ class Event < Article |
134 | 134 | true |
135 | 135 | end |
136 | 136 | |
137 | + def can_display_media_panel? | |
138 | + true | |
139 | + end | |
140 | + | |
137 | 141 | include Noosfero::TranslatableContent |
138 | 142 | include MaybeAddHttp |
139 | 143 | ... | ... |
app/models/favorite_enterprise_person.rb
1 | 1 | class FavoriteEnterprisePerson < ActiveRecord::Base |
2 | 2 | |
3 | - self.table_name = :favorite_enteprises_people | |
3 | + attr_accessible :person, :enterprise | |
4 | + | |
5 | + track_actions :favorite_enterprise, :after_create, keep_params: [:enterprise_name, :enterprise_url], if: proc{ |f| f.is_trackable? } | |
4 | 6 | |
5 | 7 | belongs_to :enterprise |
6 | 8 | belongs_to :person |
7 | 9 | |
10 | + protected | |
11 | + | |
12 | + def is_trackable? | |
13 | + self.enterprise.public? | |
14 | + end | |
15 | + | |
16 | + def enterprise_name | |
17 | + self.enterprise.short_name(nil) | |
18 | + end | |
19 | + def enterprise_url | |
20 | + self.enterprise.url | |
21 | + end | |
22 | + | |
8 | 23 | end | ... | ... |
app/models/organization.rb
... | ... | @@ -59,6 +59,10 @@ class Organization < Profile |
59 | 59 | |
60 | 60 | validate :presence_of_required_fieds, :unless => :is_template |
61 | 61 | |
62 | + def self.notify_activity tracked_action | |
63 | + Delayed::Job.enqueue NotifyActivityToProfilesJob.new(tracked_action.id) | |
64 | + end | |
65 | + | |
62 | 66 | def presence_of_required_fieds |
63 | 67 | self.required_fields.each do |field| |
64 | 68 | if self.send(field).blank? | ... | ... |
app/models/person.rb
... | ... | @@ -94,6 +94,9 @@ roles] } |
94 | 94 | |
95 | 95 | has_many :scraps_sent, :class_name => 'Scrap', :foreign_key => :sender_id, :dependent => :destroy |
96 | 96 | |
97 | + has_many :favorite_enterprise_people | |
98 | + has_many :favorite_enterprises, source: :enterprise, through: :favorite_enterprise_people | |
99 | + | |
97 | 100 | has_and_belongs_to_many :acepted_forums, :class_name => 'Forum', :join_table => 'terms_forum_people' |
98 | 101 | has_and_belongs_to_many :articles_with_access, :class_name => 'Article', :join_table => 'article_privacy_exceptions' |
99 | 102 | |
... | ... | @@ -333,8 +336,6 @@ roles] } |
333 | 336 | ] |
334 | 337 | end |
335 | 338 | |
336 | - has_and_belongs_to_many :favorite_enterprises, :class_name => 'Enterprise', :join_table => 'favorite_enteprises_people' | |
337 | - | |
338 | 339 | def email_domain |
339 | 340 | user && user.email_domain || environment.default_hostname(true) |
340 | 341 | end |
... | ... | @@ -514,8 +515,8 @@ roles] } |
514 | 515 | user.save! |
515 | 516 | end |
516 | 517 | |
517 | - def activities | |
518 | - Scrap.find_by_sql("SELECT id, updated_at, '#{Scrap.to_s}' AS klass FROM #{Scrap.table_name} WHERE scraps.receiver_id = #{self.id} AND scraps.scrap_id IS NULL UNION SELECT id, updated_at, '#{ActionTracker::Record.to_s}' AS klass FROM #{ActionTracker::Record.table_name} WHERE action_tracker.user_id = #{self.id} and action_tracker.verb != 'leave_scrap_to_self' and action_tracker.verb != 'add_member_in_community' and action_tracker.verb != 'reply_scrap_on_self' ORDER BY updated_at DESC") | |
518 | + def exclude_verbs_on_activities | |
519 | + %w[leave_scrap_to_self add_member_in_community reply_scrap_on_self] | |
519 | 520 | end |
520 | 521 | |
521 | 522 | # by default, all fields are private | ... | ... |
app/models/person_notifier.rb
app/models/product.rb
... | ... | @@ -17,13 +17,14 @@ class Product < ActiveRecord::Base |
17 | 17 | 'full' |
18 | 18 | end |
19 | 19 | |
20 | - belongs_to :enterprise, :foreign_key => :profile_id, :class_name => 'Profile' | |
21 | 20 | belongs_to :profile |
21 | + # backwards compatibility | |
22 | + belongs_to :enterprise, :foreign_key => :profile_id, :class_name => 'Profile' | |
22 | 23 | alias_method :enterprise=, :profile= |
23 | 24 | alias_method :enterprise, :profile |
24 | 25 | |
25 | - has_one :region, :through => :enterprise | |
26 | - validates_presence_of :enterprise | |
26 | + has_one :region, :through => :profile | |
27 | + validates_presence_of :profile | |
27 | 28 | |
28 | 29 | belongs_to :product_category |
29 | 30 | |
... | ... | @@ -37,6 +38,10 @@ class Product < ActiveRecord::Base |
37 | 38 | |
38 | 39 | acts_as_having_settings :field => :data |
39 | 40 | |
41 | + track_actions :create_product, :after_create, :keep_params => [:name, :url ], :if => Proc.new { |a| a.is_trackable? }, :custom_user => :action_tracker_user | |
42 | + track_actions :update_product, :before_update, :keep_params => [:name, :url], :if => Proc.new { |a| a.is_trackable? }, :custom_user => :action_tracker_user | |
43 | + track_actions :remove_product, :before_destroy, :keep_params => [:name], :if => Proc.new { |a| a.is_trackable? }, :custom_user => :action_tracker_user | |
44 | + | |
40 | 45 | validates_uniqueness_of :name, :scope => :profile_id, :allow_nil => true, :if => :validate_uniqueness_of_column_name? |
41 | 46 | |
42 | 47 | validates_presence_of :product_category_id |
... | ... | @@ -73,10 +78,10 @@ class Product < ActiveRecord::Base |
73 | 78 | after_update :save_image |
74 | 79 | |
75 | 80 | def lat |
76 | - self.enterprise.lat | |
81 | + self.profile.lat | |
77 | 82 | end |
78 | 83 | def lng |
79 | - self.enterprise.lng | |
84 | + self.profile.lng | |
80 | 85 | end |
81 | 86 | |
82 | 87 | xss_terminate :only => [ :name ], :on => 'validation' |
... | ... | @@ -90,7 +95,7 @@ class Product < ActiveRecord::Base |
90 | 95 | filter_iframes :description |
91 | 96 | |
92 | 97 | def iframe_whitelist |
93 | - enterprise && enterprise.environment && enterprise.environment.trusted_sites_for_iframe | |
98 | + self.profile && self.profile.environment && self.profile.environment.trusted_sites_for_iframe | |
94 | 99 | end |
95 | 100 | |
96 | 101 | def name |
... | ... | @@ -128,16 +133,16 @@ class Product < ActiveRecord::Base |
128 | 133 | end |
129 | 134 | |
130 | 135 | def url |
131 | - enterprise.public_profile_url.merge(:controller => 'manage_products', :action => 'show', :id => id) | |
136 | + self.profile.public_profile_url.merge(:controller => 'manage_products', :action => 'show', :id => id) | |
132 | 137 | end |
133 | 138 | |
134 | 139 | def public? |
135 | - enterprise.public? | |
140 | + self.profile.public? | |
136 | 141 | end |
137 | 142 | |
138 | 143 | def formatted_value(method) |
139 | 144 | value = self[method] || self.send(method) |
140 | - ("%.2f" % value).to_s.gsub('.', enterprise.environment.currency_separator) if value | |
145 | + ("%.2f" % value).to_s.gsub('.', self.profile.environment.currency_separator) if value | |
141 | 146 | end |
142 | 147 | |
143 | 148 | def price_with_discount |
... | ... | @@ -242,16 +247,16 @@ class Product < ActiveRecord::Base |
242 | 247 | end |
243 | 248 | |
244 | 249 | def available_production_costs |
245 | - self.enterprise.environment.production_costs + self.enterprise.production_costs | |
250 | + self.profile.environment.production_costs + self.profile.production_costs | |
246 | 251 | end |
247 | 252 | |
248 | 253 | include Rails.application.routes.url_helpers |
249 | 254 | def price_composition_bar_display_url |
250 | - url_for({:host => enterprise.default_hostname, :controller => 'manage_products', :action => 'display_price_composition_bar', :profile => enterprise.identifier, :id => self.id }.merge(Noosfero.url_options)) | |
255 | + url_for({:host => self.profile.default_hostname, :controller => 'manage_products', :action => 'display_price_composition_bar', :profile => self.profile.identifier, :id => self.id }.merge(Noosfero.url_options)) | |
251 | 256 | end |
252 | 257 | |
253 | 258 | def inputs_cost_update_url |
254 | - url_for({:host => enterprise.default_hostname, :controller => 'manage_products', :action => 'display_inputs_cost', :profile => enterprise.identifier, :id => self.id }.merge(Noosfero.url_options)) | |
259 | + url_for({:host => self.profile.default_hostname, :controller => 'manage_products', :action => 'display_inputs_cost', :profile => self.profile.identifier, :id => self.id }.merge(Noosfero.url_options)) | |
255 | 260 | end |
256 | 261 | |
257 | 262 | def percentage_from_solidarity_economy |
... | ... | @@ -268,7 +273,7 @@ class Product < ActiveRecord::Base |
268 | 273 | end |
269 | 274 | end |
270 | 275 | |
271 | - delegate :enabled, :region, :region_id, :environment, :environment_id, :to => :enterprise | |
276 | + delegate :enabled, :region, :region_id, :environment, :environment_id, :to => :profile, allow_nil: true | |
272 | 277 | |
273 | 278 | protected |
274 | 279 | |
... | ... | @@ -276,4 +281,13 @@ class Product < ActiveRecord::Base |
276 | 281 | true |
277 | 282 | end |
278 | 283 | |
284 | + def is_trackable? | |
285 | + # shopping_cart create products without profile | |
286 | + self.profile.present? | |
287 | + end | |
288 | + | |
289 | + def action_tracker_user | |
290 | + self.profile | |
291 | + end | |
292 | + | |
279 | 293 | end | ... | ... |
app/models/profile.rb
... | ... | @@ -3,7 +3,9 @@ |
3 | 3 | # which by default is the one returned by Environment:default. |
4 | 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, :redirection_after_login, :email_suggestions, :allow_members_to_invite, :invite_friends_only, :secret | |
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, | |
7 | + :redirection_after_login, :custom_url_redirection, | |
8 | + :email_suggestions, :allow_members_to_invite, :invite_friends_only, :secret | |
7 | 9 | |
8 | 10 | # use for internationalizable human type names in search facets |
9 | 11 | # reimplement on subclasses |
... | ... | @@ -188,6 +190,7 @@ class Profile < ActiveRecord::Base |
188 | 190 | |
189 | 191 | acts_as_trackable :dependent => :destroy |
190 | 192 | |
193 | + has_many :profile_activities | |
191 | 194 | has_many :action_tracker_notifications, :foreign_key => 'profile_id' |
192 | 195 | has_many :tracked_notifications, :through => :action_tracker_notifications, :source => :action_tracker, :order => 'updated_at DESC' |
193 | 196 | has_many :scraps_received, :class_name => 'Scrap', :foreign_key => :receiver_id, :order => "updated_at DESC", :dependent => :destroy |
... | ... | @@ -613,6 +616,14 @@ class Profile < ActiveRecord::Base |
613 | 616 | options.merge(Noosfero.url_options) |
614 | 617 | end |
615 | 618 | |
619 | + def top_url(scheme = 'http') | |
620 | + url = scheme + '://' | |
621 | + url << url_options[:host] | |
622 | + url << ':' << url_options[:port].to_s if url_options.key?(:port) | |
623 | + url << Noosfero.root('') | |
624 | + url | |
625 | + end | |
626 | + | |
616 | 627 | private :generate_url, :url_options |
617 | 628 | |
618 | 629 | def default_hostname |
... | ... | @@ -785,7 +796,11 @@ private :generate_url, :url_options |
785 | 796 | include ActionView::Helpers::TextHelper |
786 | 797 | def short_name(chars = 40) |
787 | 798 | if self[:nickname].blank? |
788 | - truncate self.name, :length => chars, :omission => '...' | |
799 | + if chars | |
800 | + truncate self.name, length: chars, omission: '...' | |
801 | + else | |
802 | + self.name | |
803 | + end | |
789 | 804 | else |
790 | 805 | self[:nickname] |
791 | 806 | end |
... | ... | @@ -1025,9 +1040,13 @@ private :generate_url, :url_options |
1025 | 1040 | name |
1026 | 1041 | end |
1027 | 1042 | |
1028 | - # Override in your subclasses | |
1043 | + def exclude_verbs_on_activities | |
1044 | + %w[] | |
1045 | + end | |
1046 | + | |
1047 | + # Customize in subclasses | |
1029 | 1048 | def activities |
1030 | - [] | |
1049 | + self.profile_activities.includes(:activity).order('updated_at DESC') | |
1031 | 1050 | end |
1032 | 1051 | |
1033 | 1052 | def may_display_field_to? field, user = nil |
... | ... | @@ -1074,6 +1093,7 @@ private :generate_url, :url_options |
1074 | 1093 | def preferred_login_redirection |
1075 | 1094 | redirection_after_login.blank? ? environment.redirection_after_login : redirection_after_login |
1076 | 1095 | end |
1096 | + settings_items :custom_url_redirection, type: String, default: nil | |
1077 | 1097 | |
1078 | 1098 | def remove_from_suggestion_list(person) |
1079 | 1099 | suggestion = person.suggested_profiles.find_by_suggestion_id self.id | ... | ... |
... | ... | @@ -0,0 +1,31 @@ |
1 | +class ProfileActivity < ActiveRecord::Base | |
2 | + | |
3 | + self.record_timestamps = false | |
4 | + | |
5 | + attr_accessible :profile_id, | |
6 | + :profile, :activity | |
7 | + | |
8 | + belongs_to :profile | |
9 | + belongs_to :activity, polymorphic: true | |
10 | + | |
11 | + # non polymorphic versions | |
12 | + belongs_to :scrap, foreign_key: :activity_id, class_name: 'Scrap', conditions: {profile_activities: {activity_type: 'Scrap'}} | |
13 | + belongs_to :action_tracker, foreign_key: :activity_id, class_name: 'ActionTracker::Record', conditions: {profile_activities: {activity_type: 'ActionTracker::Record'}} | |
14 | + | |
15 | + before_validation :copy_timestamps | |
16 | + | |
17 | + def self.update_activity activity | |
18 | + profile_activity = ProfileActivity.where(activity_id: activity.id, activity_type: activity.class.base_class.name).first | |
19 | + profile_activity.send :copy_timestamps | |
20 | + profile_activity.save! | |
21 | + profile_activity | |
22 | + end | |
23 | + | |
24 | + protected | |
25 | + | |
26 | + def copy_timestamps | |
27 | + self.created_at = self.activity.created_at | |
28 | + self.updated_at = self.activity.updated_at | |
29 | + end | |
30 | + | |
31 | +end | ... | ... |
app/models/profile_list_block.rb
... | ... | @@ -16,19 +16,19 @@ class ProfileListBlock < Block |
16 | 16 | |
17 | 17 | def profile_list |
18 | 18 | result = nil |
19 | - visible_profiles = profiles.visible.includes([:image,:domains,:preferred_domain,:environment]) | |
19 | + public_profiles = profiles.public.includes([:image,:domains,:preferred_domain,:environment]) | |
20 | 20 | if !prioritize_profiles_with_image |
21 | - result = visible_profiles.all(:limit => get_limit, :order => 'profiles.updated_at DESC').sort_by{ rand } | |
21 | +result = public_profiles.all(:limit => get_limit, :order => 'profiles.updated_at DESC').sort_by{ rand } | |
22 | 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 } | |
23 | + result = public_profiles.with_image.all(:limit => get_limit * 5, :order => 'profiles.updated_at DESC').sort_by{ rand } | |
24 | 24 | else |
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 } | |
25 | + result = public_profiles.with_image.sort_by{ rand } + public_profiles.without_image.all(:limit => get_limit * 5, :order => 'profiles.updated_at DESC').sort_by{ rand } | |
26 | 26 | end |
27 | 27 | result.slice(0..get_limit-1) |
28 | 28 | end |
29 | 29 | |
30 | 30 | def profile_count |
31 | - profiles.visible.length | |
31 | + profiles.public.length | |
32 | 32 | end |
33 | 33 | |
34 | 34 | # the title of the block. Probably will be overriden in subclasses. | ... | ... |
app/models/scrap.rb
... | ... | @@ -13,20 +13,22 @@ class Scrap < ActiveRecord::Base |
13 | 13 | has_many :replies, :class_name => 'Scrap', :foreign_key => 'scrap_id', :dependent => :destroy |
14 | 14 | belongs_to :root, :class_name => 'Scrap', :foreign_key => 'scrap_id' |
15 | 15 | |
16 | + has_many :profile_activities, foreign_key: :activity_id, conditions: {profile_activities: {activity_type: 'Scrap'}}, dependent: :destroy | |
17 | + | |
18 | + after_create :create_activity | |
19 | + after_update :update_activity | |
20 | + | |
16 | 21 | scope :all_scraps, lambda {|profile| {:conditions => ["receiver_id = ? OR sender_id = ?", profile, profile], :limit => 30}} |
17 | 22 | |
18 | 23 | scope :not_replies, :conditions => {:scrap_id => nil} |
19 | 24 | |
20 | - track_actions :leave_scrap, :after_create, :keep_params => ['sender.name', 'content', 'receiver.name', 'receiver.url'], :if => Proc.new{|s| s.sender != s.receiver && s.sender != s.top_root.receiver}, :custom_target => :action_tracker_target | |
25 | + track_actions :leave_scrap, :after_create, :keep_params => ['sender.name', 'content', 'receiver.name', 'receiver.url'], :if => Proc.new{|s| s.sender != s.receiver && s.sender != s.top_root.receiver}, :custom_target => :action_tracker_target, :custom_user => :sender | |
21 | 26 | |
22 | - track_actions :leave_scrap_to_self, :after_create, :keep_params => ['sender.name', 'content'], :if => Proc.new{|s| s.sender == s.receiver} | |
27 | + track_actions :leave_scrap_to_self, :after_create, :keep_params => ['sender.name', 'content'], :if => Proc.new{|s| s.sender == s.receiver}, :custom_user => :sender | |
23 | 28 | |
24 | - track_actions :reply_scrap_on_self, :after_create, :keep_params => ['sender.name', 'content'], :if => Proc.new{|s| s.sender != s.receiver && s.sender == s.top_root.receiver} | |
29 | + track_actions :reply_scrap_on_self, :after_create, :keep_params => ['sender.name', 'content'], :if => Proc.new{|s| s.sender != s.receiver && s.sender == s.top_root.receiver}, :custom_user => :sender | |
25 | 30 | |
26 | - after_create do |scrap| | |
27 | - scrap.root.update_attribute('updated_at', DateTime.now) unless scrap.root.nil? | |
28 | - ScrapNotifier.notification(scrap).deliver if scrap.send_notification? | |
29 | - end | |
31 | + after_create :send_notification | |
30 | 32 | |
31 | 33 | before_validation :strip_all_html_tags |
32 | 34 | |
... | ... | @@ -57,4 +59,21 @@ class Scrap < ActiveRecord::Base |
57 | 59 | sender != receiver && (is_root? ? root.receiver.receives_scrap_notification? : receiver.receives_scrap_notification?) |
58 | 60 | end |
59 | 61 | |
62 | + protected | |
63 | + | |
64 | + def create_activity | |
65 | + # do not scrap replies (when scrap_id is not nil) | |
66 | + return if self.scrap_id.present? | |
67 | + ProfileActivity.create! profile_id: self.receiver_id, activity: self | |
68 | + end | |
69 | + | |
70 | + def update_activity | |
71 | + ProfileActivity.update_activity self | |
72 | + end | |
73 | + | |
74 | + def send_notification | |
75 | + self.root.update_attribute('updated_at', DateTime.now) unless self.root.nil? | |
76 | + ScrapNotifier.notification(self).deliver if self.send_notification? | |
77 | + end | |
78 | + | |
60 | 79 | end | ... | ... |
... | ... | @@ -0,0 +1,18 @@ |
1 | +class Session < ActiveRecord::SessionStore::Session | |
2 | + | |
3 | + # removed and redefined on super class | |
4 | + def self.find_by_session_id session_id | |
5 | + super | |
6 | + end | |
7 | + | |
8 | + belongs_to :user | |
9 | + | |
10 | + before_save :copy_to_columns | |
11 | + | |
12 | + protected | |
13 | + | |
14 | + def copy_to_columns | |
15 | + self.user_id = self.data['user'] | |
16 | + end | |
17 | + | |
18 | +end | ... | ... |
app/models/text_article.rb
... | ... | @@ -33,12 +33,16 @@ class TextArticle < Article |
33 | 33 | end |
34 | 34 | |
35 | 35 | def change_element_path(el, attribute) |
36 | - fullpath = /(https?):\/\/(#{environment.default_hostname})(:\d+)?(\/.*)/.match(el[attribute]) | |
36 | + fullpath = /(https?):\/\/(#{profile.default_hostname})(:\d+)?(\/.*)/.match(el[attribute]) | |
37 | 37 | if fullpath |
38 | 38 | domain = fullpath[2] |
39 | 39 | path = fullpath[4] |
40 | - el[attribute] = path if domain == environment.default_hostname | |
40 | + el[attribute] = path if domain == profile.default_hostname | |
41 | 41 | end |
42 | 42 | end |
43 | 43 | |
44 | + def display_preview? | |
45 | + parent && parent.kind_of?(Blog) && parent.display_preview | |
46 | + end | |
47 | + | |
44 | 48 | end | ... | ... |
app/models/textile_article.rb
app/models/tiny_mce_article.rb
app/models/uploaded_file.rb
app/models/user.rb
... | ... | @@ -16,6 +16,14 @@ class User < ActiveRecord::Base |
16 | 16 | :email => {:label => _('Email'), :weight => 5}, |
17 | 17 | } |
18 | 18 | |
19 | + # see http://stackoverflow.com/a/2513456/670229 | |
20 | + def self.current | |
21 | + Thread.current[:current_user] | |
22 | + end | |
23 | + def self.current=(user) | |
24 | + Thread.current[:current_user] = user | |
25 | + end | |
26 | + | |
19 | 27 | def self.[](login) |
20 | 28 | self.find_by_login(login) |
21 | 29 | end |
... | ... | @@ -97,6 +105,10 @@ class User < ActiveRecord::Base |
97 | 105 | has_one :person, :dependent => :destroy |
98 | 106 | belongs_to :environment |
99 | 107 | |
108 | + has_many :sessions, dependent: :destroy | |
109 | + # holds the current session, see lib/authenticated_system.rb | |
110 | + attr_accessor :session | |
111 | + | |
100 | 112 | attr_protected :activated_at |
101 | 113 | |
102 | 114 | # Virtual attribute for the unencrypted password |
... | ... | @@ -118,11 +130,18 @@ class User < ActiveRecord::Base |
118 | 130 | |
119 | 131 | validates_inclusion_of :terms_accepted, :in => [ '1' ], :if => lambda { |u| ! u.terms_of_use.blank? }, :message => N_('{fn} must be checked in order to signup.').fix_i18n |
120 | 132 | |
133 | + scope :has_login?, lambda { |login,email,environment_id| | |
134 | + where('login = ? OR email = ?', login, email). | |
135 | + where(environment_id: environment_id) | |
136 | + } | |
137 | + | |
121 | 138 | # Authenticates a user by their login name or email and unencrypted password. Returns the user or nil. |
122 | 139 | def self.authenticate(login, password, environment = nil) |
123 | 140 | environment ||= Environment.default |
124 | - u = self.first :conditions => ['(login = ? OR email = ?) AND environment_id = ? AND activated_at IS NOT NULL', | |
125 | - login, login, environment.id] # need to get the salt | |
141 | + | |
142 | + u = self.has_login?(login, login, environment.id) | |
143 | + u = u.first if u.is_a?(ActiveRecord::Relation) | |
144 | + | |
126 | 145 | if u && u.authenticated?(password) |
127 | 146 | u.generate_private_token_if_not_exist |
128 | 147 | return u |
... | ... | @@ -259,7 +278,23 @@ class User < ActiveRecord::Base |
259 | 278 | password.crypt(salt) |
260 | 279 | end |
261 | 280 | |
281 | + class UserNotActivated < StandardError | |
282 | + attr_reader :user | |
283 | + | |
284 | + def initialize(message, user = nil) | |
285 | + @user = user | |
286 | + | |
287 | + super(message) | |
288 | + end | |
289 | + end | |
290 | + | |
262 | 291 | def authenticated?(password) |
292 | + | |
293 | + unless self.activated? | |
294 | + message = _('The user "%{login}" is not activated! Please check your email to activate your user') % {login: self.login} | |
295 | + raise UserNotActivated.new(message, self) | |
296 | + end | |
297 | + | |
263 | 298 | result = (crypted_password == encrypt(password)) |
264 | 299 | if (encryption_method != User.system_encryption_method) && result |
265 | 300 | self.password_type = User.system_encryption_method.to_s |
... | ... | @@ -276,8 +311,9 @@ class User < ActiveRecord::Base |
276 | 311 | |
277 | 312 | # These create and unset the fields required for remembering users between browser closes |
278 | 313 | def remember_me |
279 | - self.remember_token_expires_at = 2.weeks.from_now.utc | |
280 | - self.remember_token = encrypt("#{email}--#{remember_token_expires_at}") | |
314 | + self.remember_token_expires_at = 1.months.from_now.utc | |
315 | + # if the user's email/password changes this won't be valid anymore | |
316 | + self.remember_token = encrypt "#{email}-#{self.crypted_password}-#{remember_token_expires_at}" | |
281 | 317 | save(:validate => false) |
282 | 318 | end |
283 | 319 | |
... | ... | @@ -297,9 +333,15 @@ class User < ActiveRecord::Base |
297 | 333 | # current password. |
298 | 334 | # * Saves the record unless it is a new one. |
299 | 335 | def change_password!(current, new, confirmation) |
300 | - unless self.authenticated?(current) | |
301 | - self.errors.add(:current_password, _('does not match.')) | |
302 | - raise IncorrectPassword | |
336 | + | |
337 | + begin | |
338 | + unless self.authenticated?(current) | |
339 | + self.errors.add(:current_password, _('does not match.')) | |
340 | + raise IncorrectPassword | |
341 | + end | |
342 | + rescue UserNotActivated => e | |
343 | + self.errors.add(:current_password, e.message) | |
344 | + raise UserNotActivated | |
303 | 345 | end |
304 | 346 | self.force_change_password!(new, confirmation) |
305 | 347 | end | ... | ... |
app/models/validation_info.rb
... | ... | @@ -2,9 +2,10 @@ class ValidationInfo < ActiveRecord::Base |
2 | 2 | |
3 | 3 | attr_accessible :validation_methodology, :restrictions, :organization |
4 | 4 | |
5 | - validates_presence_of :validation_methodology | |
6 | - | |
7 | 5 | belongs_to :organization |
8 | 6 | |
7 | + validates_presence_of :organization | |
8 | + validates_presence_of :validation_methodology | |
9 | + | |
9 | 10 | xss_terminate :only => [ :validation_methodology, :restrictions ], :on => 'validation' |
10 | 11 | end | ... | ... |
app/views/account/login.html.erb
... | ... | @@ -13,7 +13,14 @@ |
13 | 13 | |
14 | 14 | <%= f.password_field :password %> |
15 | 15 | |
16 | - <%= @plugins.dispatch(:login_extra_contents).collect { |content| instance_eval(&content) }.join("") %> | |
16 | + <div class='checkbox'> | |
17 | + <label> | |
18 | + <%= check_box_tag :remember_me, '1', true %> | |
19 | + <%= _'Keep me logged in' %> | |
20 | + </label> | |
21 | + </div> | |
22 | + | |
23 | + <%= @plugins.dispatch(:login_extra_contents).collect { |content| instance_exec(&content) }.join("") %> | |
17 | 24 | |
18 | 25 | <% button_bar do %> |
19 | 26 | <%= submit_button( 'login', _('Log in') )%> | ... | ... |
app/views/account/signup.html.erb
... | ... | @@ -0,0 +1,5 @@ |
1 | +<div class='description'> | |
2 | + <%= _('This text will be shown to the user on the top of the sign up form.') %> | |
3 | +</div> | |
4 | + | |
5 | +<%= labelled_form_field(_('Body'), text_area(:environment, :signup_intro, :cols => 40, :style => 'width: 100%', :class => 'mceEditor')) %> | ... | ... |
app/views/admin_panel/site_info.html.erb
... | ... | @@ -17,6 +17,8 @@ |
17 | 17 | :content => (render :partial => 'signup_welcome_text', :locals => {:f => f})} %> |
18 | 18 | <% tabs << {:title => _('Signup welcome page'), :id => 'signup-welcome-message', |
19 | 19 | :content => (render :partial => 'signup_welcome_screen', :locals => {:f => f}) }%> |
20 | + <% tabs << {:title => _('Signup introduction text'), :id => 'signup-intro', | |
21 | + :content => (render :partial => 'signup_intro', :locals => {:f => f})} %> | |
20 | 22 | <%= render_tabs(tabs) %> |
21 | 23 | <% button_bar do %> |
22 | 24 | <%= submit_button(:save, _('Save'), :cancel => {:action => 'index'}) %> | ... | ... |
app/views/blocks/profile_info_actions/_enterprise.html.erb
1 | 1 | <ul> |
2 | 2 | <%if logged_in? %> |
3 | 3 | <%if !user.favorite_enterprises.include?(profile) %> |
4 | - <li><%= button(:add, _('Add as favorite'), { :profile => user.identifier, :controller => 'favorite_enterprises', :action => 'add', :id => profile.id }, :title => _('Add enterprise as favorite')) %></li> | |
4 | + <li><%= button(:love, _('Add as favorite'), { profile: user.identifier, controller: 'favorite_enterprises', action: 'add', id: profile.id }, title: _('Add enterprise as favorite')) %></li> | |
5 | 5 | <% end %> |
6 | 6 | <% end %> |
7 | 7 | <% if profile.enable_contact? %> | ... | ... |
app/views/blocks/profile_info_actions/_join_leave_community.html.erb
1 | 1 | <div class='join-leave-button require-login-popup'> |
2 | 2 | <% if logged_in? %> |
3 | - <% if profile.members.include?(user) %> | |
4 | - <%= button(:delete, content_tag('span', _('Leave community')), profile.leave_url, | |
5 | - :class => 'leave-community', | |
6 | - :title => _("Leave community"), | |
7 | - :style => 'position: relative;') %> | |
8 | - <%= button(:add, content_tag('span', _('Join')), profile.join_url, | |
9 | - :class => 'join-community', | |
10 | - :title => _("Join community"), | |
11 | - :style => 'position: relative; display: none;') %> | |
3 | + <% if profile.already_request_membership? user %> | |
4 | + <%= _('Your membership is waiting for approval') %> | |
12 | 5 | <% else %> |
13 | - <% unless profile.already_request_membership?(user) %> | |
14 | - <%= button(:delete, content_tag('span', _('Leave community')), profile.leave_url, | |
15 | - :class => 'leave-community', | |
16 | - :title => _("Leave community"), | |
17 | - :style => 'position: relative; display: none;') %> | |
18 | - <%= button(:add, content_tag('span', _('Join')), profile.join_url, | |
19 | - :class => 'join-community', | |
20 | - :title => _("Join community"), | |
21 | - :style => 'position: relative;') %> | |
6 | + <% if user.in? profile.members %> | |
7 | + <%= button :delete, content_tag('span', _('Leave community')), profile.leave_url, | |
8 | + class: 'leave-community', | |
9 | + style: 'position: relative;' %> | |
10 | + <%= button :add, content_tag('span', _('Join this community')), profile.join_url, | |
11 | + class: 'join-community', | |
12 | + style: 'position: relative; display: none;' %> | |
13 | + <% else %> | |
14 | + <%= button :add, _('Join this community'), profile.join_url, class: 'join-community' %> | |
22 | 15 | <% end %> |
23 | 16 | <% end %> |
24 | 17 | <% else %> |
25 | - <%= button(:add, _('Join'), profile.join_not_logged_url, :title => _('Join this community')) %> | |
18 | + <%= button :add, _('Join this community'), profile.join_not_logged_url %> | |
26 | 19 | <% end %> |
27 | 20 | </div> |
21 | + | |
22 | +<%= javascript_tag do %> | |
23 | + noosfero.add_and_join.locales.leaveConfirmation = <%= (_("Please confirm to leave the community '%{name}'") % {name: profile.name}).to_json %> | |
24 | +<% end %> | |
25 | + | ... | ... |
app/views/cms/_blog.html.erb
... | ... | @@ -53,7 +53,7 @@ |
53 | 53 | %> |
54 | 54 | </div> |
55 | 55 | |
56 | -<%= labelled_form_field(_('Description:'), text_area(:article, :body, :rows => 10)) %> | |
56 | +<%= labelled_form_field(_('Description:'), text_area(:article, :body, :rows => 10, :class => 'mceEditor')) %> | |
57 | 57 | |
58 | 58 | <%= f.fields_for :image_builder, @article.image do |i| %> |
59 | 59 | <%= file_field_or_thumbnail(_('Cover image:'), @article.image, i)%> | ... | ... |
app/views/cms/_event.html.erb
... | ... | @@ -8,9 +8,8 @@ |
8 | 8 | <%= render :partial => 'general_fields' %> |
9 | 9 | <%= render :partial => 'translatable' %> |
10 | 10 | |
11 | -<%= labelled_form_field(_('Start date'), pick_date(:article, :start_date)) %> | |
11 | +<%= date_range_field('article[start_date]', 'article[end_date]', @article.start_date, @article.end_date, _('%Y-%m-%d %H:%M'), {:time => true}, {:id => 'article_start_date'} ) %> | |
12 | 12 | |
13 | -<%= labelled_form_field(_('End date'), pick_date(:article, :end_date)) %> | |
14 | 13 | |
15 | 14 | <%= labelled_form_field(_('Event website:'), text_field(:article, :link)) %> |
16 | 15 | ... | ... |
app/views/cms/edit.html.erb
1 | 1 | <%= error_messages_for 'article' %> |
2 | 2 | |
3 | -<% show_media_panel = environment.enabled?('media_panel') && [TinyMceArticle, TextileArticle, Event, EnterpriseHomepage].any?{|klass| @article.kind_of?(klass)} %> | |
4 | - | |
5 | -<div class='<%= (show_media_panel ? 'with_media_panel' : 'no_media_panel') %>'> | |
3 | +<div class='<%= (@article.display_media_panel? ? 'with_media_panel' : 'no_media_panel') %>'> | |
6 | 4 | <%= labelled_form_for 'article', :html => { :multipart => true, :class => @type } do |f| %> |
7 | 5 | |
8 | 6 | <%= hidden_field_tag("type", @type) if @type %> |
9 | 7 | |
10 | - <%= hidden_field_tag('parent_id', @parent_id) if @parent_id %> | |
11 | - | |
12 | 8 | <%= hidden_field_tag('back_to', @back_to) %> |
13 | 9 | |
14 | 10 | <%= hidden_field_tag('success_back_to', @success_back_to) %> |
... | ... | @@ -68,7 +64,7 @@ |
68 | 64 | <% end %> |
69 | 65 | </div> |
70 | 66 | |
71 | -<% if show_media_panel %> | |
67 | +<% if @article.display_media_panel? %> | |
72 | 68 | <%= render :partial => 'text_editor_sidebar' %> |
73 | 69 | <% end %> |
74 | 70 | ... | ... |
app/views/content_viewer/_article_title.html.erb
app/views/content_viewer/_article_toolbar.html.erb
... | ... | @@ -29,10 +29,10 @@ |
29 | 29 | <%= expirable_button @page, :locale, content, url %> |
30 | 30 | <% end %> |
31 | 31 | |
32 | - <%= modal_button(:new, label_for_new_article(@page), profile.admin_url.merge(:controller => 'cms', :action => 'new', :parent_id => (@page.folder? ? @page : (@page.parent.nil? ? nil : @page.parent)))) unless remove_content_button(:new, @page) %> | |
32 | + <%= modal_button(:new, label_for_new_article(@page), profile.admin_url.merge(:controller => 'cms', :action => 'new', :parent_id => (@page.folder? ? @page : @page.parent))) unless remove_content_button(:new, @page) %> | |
33 | 33 | |
34 | 34 | <% content = content_tag('span', label_for_clone_article(@page)) %> |
35 | - <% url = profile.admin_url.merge({ :controller => 'cms', :action => 'new', :id => @page.id, :clone => true, :type => @page.class }) %> | |
35 | + <% url = profile.admin_url.merge({ :controller => 'cms', :action => 'new', :id => @page.id, :clone => true, :parent_id => (@page.folder? ? @page : @page.parent), :type => @page.class}) %> | |
36 | 36 | <%= expirable_button @page, :clone, content, url %> |
37 | 37 | <% end %> |
38 | 38 | |
... | ... | @@ -62,7 +62,7 @@ |
62 | 62 | <% if @page.blog? and !@page.image.nil? %> |
63 | 63 | <div class="blog-cover"><%= image_tag(@page.image.public_filename())%></div> |
64 | 64 | <% end %> |
65 | - <%= link_to(image_tag('/images/icons-mime/rss-feed.png'), @page.feed.url, :class => 'blog-feed-link') if @page.has_posts? && @page.feed %> | |
65 | + <%= button_without_text(:feed, _('RSS feed'), @page.feed.url, :class => 'blog-feed-link') if @page.has_posts? && @page.feed %> | |
66 | 66 | <%= @plugins.dispatch(:article_header_extra_contents, @page).collect { |content| instance_exec(&content) }.join("") %> |
67 | 67 | <%= render :partial => 'article_title', :locals => {:no_link => true} %> |
68 | 68 | <%= article_translations(@page) %> | ... | ... |
app/views/content_viewer/_publishing_info.html.erb
app/views/content_viewer/_uploaded_file.html.erb
... | ... | @@ -2,7 +2,7 @@ |
2 | 2 | <%= link_to '', |
3 | 3 | uploaded_file.view_url, |
4 | 4 | :class => 'image', |
5 | - :style => 'background-image: url(%s)'% uploaded_file.public_filename(:thumb) | |
5 | + :style => 'background-image: url(%s)'% [Noosfero.root, uploaded_file.public_filename(:thumb)].join | |
6 | 6 | %> |
7 | 7 | <span><%=h uploaded_file.title %></span> |
8 | 8 | <% else %> | ... | ... |
app/views/content_viewer/article_versions.html.erb
... | ... | @@ -12,7 +12,7 @@ |
12 | 12 | <li> |
13 | 13 | <%= radio_button_tag 'v1', v.version, false, :onclick => 'versionInputClicked(this)' %> |
14 | 14 | <%= radio_button_tag 'v2', v.version, false, :onclick => 'versionInputClicked(this)' %> |
15 | - <%= link_to(_("Version #{v.version}"), @page.url.merge(:version => v.version)) %> | |
15 | + <%= link_to(_("Version %s") % v.version, @page.url.merge(:version => v.version)) %> | |
16 | 16 | <%= @page.version == v.version ? _('(current)') : '' %> |
17 | 17 | <span class='updated-by'><%= _('by %{author}') % {:author => link_to(@page.author_name(v.version), @page.author_url(v.version))} %></span> |
18 | 18 | <span class='updated-on'><%= show_time(v.updated_at) %></span> | ... | ... |
app/views/content_viewer/folder.html.erb
app/views/content_viewer/view_page.html.erb
app/views/file_presenter/_generic.html.erb
1 | -<span class="download-link"> | |
2 | - <span>Download</span> | |
3 | - <strong><%= link_to generic.filename, [Noosfero.root, generic.public_filename].join %></strong> | |
4 | -</span> | |
5 | - | |
6 | 1 | <div class="uploaded-file-description <%= 'empty' if generic.abstract.blank? %>"> |
7 | 2 | <%= generic.abstract %> |
8 | 3 | </div> |
9 | 4 | |
5 | +<%= button(:download, _('Download'), [Noosfero.root, generic.public_filename].join, class:'download-link', option:'primary', size:'lg') %> | ... | ... |
app/views/organizations/_results.html.erb
app/views/person_notifier/mailer/_default_activity.html.erb
... | ... | @@ -4,7 +4,10 @@ |
4 | 4 | </td> |
5 | 5 | <td> |
6 | 6 | <p> |
7 | - <span style="font-size: 14px;"><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></span> | |
7 | + <span style="font-size: 14px;"> | |
8 | + <%= link_to activity.user.name, activity.user.url %> | |
9 | + <%= describe activity %> | |
10 | + </span> | |
8 | 11 | <span style="font-size: 10px; color: #929292; float: right;"><%= time_ago_in_words(activity.created_at) %></span> |
9 | 12 | </p> |
10 | 13 | </td> | ... | ... |
... | ... | @@ -0,0 +1,13 @@ |
1 | +<div class='profile-activity-image'> | |
2 | + <%= link_to image_tag(activity.target.default_image :minor), activity.target.url, class: 'product-pic' if activity.target.present? %> | |
3 | +</div> | |
4 | +<div class='profile-activity-description'> | |
5 | + <p class='profile-activity-text'><%= link_to activity.user.short_name(nil), activity.user.url %> <%= describe activity %></p> | |
6 | + <p class='profile-activity-time'><%= time_ago_as_sentence activity.created_at %></p> | |
7 | + | |
8 | + <div class='profile-wall-actions'> | |
9 | + <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %> | |
10 | + </div> | |
11 | +</div> | |
12 | + | |
13 | +<div style="clear: both"></div> | ... | ... |
... | ... | @@ -0,0 +1,15 @@ |
1 | +<div class='profile-activity-image'> | |
2 | + <%= link_to(profile_image(activity.user, :minor), activity.user.url) %> | |
3 | +</div> | |
4 | +<div class='profile-activity-description'> | |
5 | + <p class='profile-activity-text'> | |
6 | + <%= link_to activity.user.short_name(nil), activity.user.url %> <%= describe activity %> | |
7 | + </p> | |
8 | + <p class='profile-activity-time'><%= time_ago_as_sentence activity.created_at %></p> | |
9 | + | |
10 | + <div class='profile-wall-actions'> | |
11 | + <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %> | |
12 | + </div> | |
13 | +</div> | |
14 | + | |
15 | +<div style="clear: both"></div> | ... | ... |
app/views/profile/_profile_activities_list.html.erb
1 | 1 | <% unless activities.nil? %> |
2 | - <% activities.each do |a| %> | |
3 | - <% activity = a.klass.constantize.find(a.id) %> | |
2 | + <% activities.each do |profile_activity| %> | |
3 | + <% activity = profile_activity.activity %> | |
4 | 4 | <% if activity.kind_of?(ActionTracker::Record) %> |
5 | 5 | <%= render :partial => 'profile_activity', :locals => { :activity => activity, :tab_action => 'wall' } if activity.visible? %> |
6 | 6 | <% else %> | ... | ... |
... | ... | @@ -0,0 +1,12 @@ |
1 | +<div class='profile-activity-image'> | |
2 | +</div> | |
3 | +<div class='profile-activity-description'> | |
4 | + <p class='profile-activity-text'><%= link_to activity.user.short_name(nil), activity.user.url %> <%= describe activity %></p> | |
5 | + <p class='profile-activity-time'><%= time_ago_as_sentence activity.created_at %></p> | |
6 | + | |
7 | + <div class='profile-wall-actions'> | |
8 | + <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %> | |
9 | + </div> | |
10 | +</div> | |
11 | + | |
12 | +<div style="clear: both"></div> | ... | ... |
... | ... | @@ -0,0 +1,13 @@ |
1 | +<div class='profile-activity-image'> | |
2 | + <%= link_to image_tag(activity.target.default_image :minor), activity.target.url, class: 'product-pic' if activity.target.present? %> | |
3 | +</div> | |
4 | +<div class='profile-activity-description'> | |
5 | + <p class='profile-activity-text'><%= link_to activity.user.short_name(nil), activity.user.url %> <%= describe activity %></p> | |
6 | + <p class='profile-activity-time'><%= time_ago_as_sentence activity.created_at %></p> | |
7 | + | |
8 | + <div class='profile-wall-actions'> | |
9 | + <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %> | |
10 | + </div> | |
11 | +</div> | |
12 | + | |
13 | +<div style="clear: both"></div> | ... | ... |
app/views/profile_editor/_redirection_after_login.html.erb
0 → 100644
... | ... | @@ -0,0 +1,9 @@ |
1 | +<% content_for :head do %> | |
2 | + <%= javascript_include_tag 'redirection_after_login' %> | |
3 | +<% end %> | |
4 | + | |
5 | +<h2><%= _('Page to redirect after login') %></h2> | |
6 | +<%= f.select :redirection_after_login, Environment.login_redirection_options.map{ |key,value| [value,key] }, selected: @profile.preferred_login_redirection %> | |
7 | + | |
8 | +<%= f.text_field :custom_url_redirection %> | |
9 | + | ... | ... |
app/views/profile_editor/edit.html.erb
... | ... | @@ -44,8 +44,7 @@ |
44 | 44 | <% end %> |
45 | 45 | |
46 | 46 | <% if environment.enabled?('allow_change_of_redirection_after_login') %> |
47 | - <h2><%= _('Page to redirect after login') %></h2> | |
48 | - <%= select 'profile_data', 'redirection_after_login', Environment.login_redirection_options.map{|key,value|[value,key]}, { :selected => @profile.preferred_login_redirection} %> | |
47 | + <%= render 'redirection_after_login', f: f %> | |
49 | 48 | <% end %> |
50 | 49 | |
51 | 50 | <h2><%= _('Translations') %></h2> |
... | ... | @@ -75,14 +74,23 @@ |
75 | 74 | |
76 | 75 | <% if user && user.has_permission?('destroy_profile', profile) %> |
77 | 76 | <% button_bar(:id => 'delete-profile') do %> |
78 | - <%= button(:remove, _('Delete profile'), {:action => :destroy_profile}) %> | |
79 | 77 | |
80 | - <% if environment.admins.include?(current_person) %> | |
78 | + <% if !environment.enabled?('forbid_destroy_profile') || user.is_admin?(environment) %> | |
79 | + <%= button(:remove, _('Delete profile'), {:action => :destroy_profile}) %> | |
80 | + <% end %> | |
81 | 81 | |
82 | + <% if user.is_admin?(environment) %> | |
82 | 83 | <% if profile.visible? %> |
83 | - <%= button(:remove, _('Deactivate profile'), {:action => :deactivate_profile, :id=>profile.id}, :id=>'deactivate_profile_button', :data => {:confirm=>_("Are you sure you want to deactivate this profile?")}) %> | |
84 | + <%= button(:remove, _('Deactivate profile'), | |
85 | + {:action => :deactivate_profile, :id=>profile.id}, | |
86 | + :id=>'deactivate_profile_button', | |
87 | + :data => {:confirm=>_("Are you sure you want to deactivate this profile?")}) | |
88 | + %> | |
84 | 89 | <% else %> |
85 | - <%= button(:add, _('Activate profile'), {:action => :activate_profile, :id=>profile.id}, :data => {:confirm=>_("Are you sure you want to deactivate this profile?")}) %> | |
90 | + <%= button(:add, _('Activate profile'), | |
91 | + {:action => :activate_profile, :id=>profile.id}, | |
92 | + :data => {:confirm=>_("Are you sure you want to activate this profile?")}) | |
93 | + %> | |
86 | 94 | <% end %> |
87 | 95 | <% end %> |
88 | 96 | <% end %> | ... | ... |
app/views/profile_roles/assign.html.erb
app/views/profile_roles/destroy.html.erb
app/views/profile_roles/edit.html.erb
app/views/role/edit.html.erb
app/views/shared/_content_item.html.erb
... | ... | @@ -6,6 +6,6 @@ |
6 | 6 | <span class="item-description"> |
7 | 7 | <%= link_to(content.name, content.url) %> |
8 | 8 | </span> |
9 | - <span class="item-date"><%= _("Published at: #{show_date(content.updated_at)}") %></span> | |
9 | + <span class="item-date"><%= _("Published at: %s") % show_date(content.updated_at) %></span> | |
10 | 10 | </div> |
11 | 11 | </div> | ... | ... |
app/views/shared/_list_groups.html.erb
1 | 1 | <ul id="groups-list"> |
2 | -<% for group in groups %> | |
3 | - <li> | |
4 | - <div class='common-profile-list-block'> | |
5 | - <%= profile_image_link(group, :portrait, 'div') %> | |
6 | - </div> | |
7 | - <span class='profile-details'> | |
8 | - <strong><%= group.name %></strong><br/> | |
9 | - <%= _('Role: %s') % rolename_for(profile, group) + '<br/>' if profile.role_assignments.find_by_resource_id(group.id) %> | |
10 | - <%= _('Type: %s') % _(group.class.identification) %> <br/> | |
11 | - <%= _('Description: %s') % group.description + '<br/>' if group.community? %> | |
12 | - <%= _('Members: %s') % group.members_count.to_s %> <br/> | |
13 | - <%= _('Created at: %s') % show_date(group.created_at) unless group.enterprise? %> <br/> | |
14 | - <% button_bar do %> | |
15 | - <% if user.has_permission?(:edit_profile, group) %> | |
16 | - <%= button 'menu-ctrl-panel', _('Control panel of this group'), group.admin_url %> | |
17 | - <% end %> | |
18 | - <%= button 'menu-logout', _('Leave community'), group.leave_url(true), :class => 'leave-community' %> | |
19 | - <% if (group.community? && user.has_permission?(:destroy_profile, group)) %> | |
20 | - <%= button 'delete', _('Remove'), { :controller => 'profile_editor', :action => 'destroy_profile', :profile => group.identifier } %> | |
2 | + <% for group in groups %> | |
3 | + <li> | |
4 | + <div class='common-profile-list-block'> | |
5 | + <%= profile_image_link(group, :portrait, 'div') %> | |
6 | + </div> | |
7 | + <span class='profile-details'> | |
8 | + <strong><%= group.name %></strong><br/> | |
9 | + <%= _('Role: %s') % rolename_for(profile, group) + '<br/>' if profile.role_assignments.find_by_resource_id(group.id) %> | |
10 | + <%= _('Type: %s') % _(group.class.identification) %> <br/> | |
11 | + <%= _('Description: %s') % group.description + '<br/>' if group.community? %> | |
12 | + <%= _('Members: %s') % group.members_count.to_s %> <br/> | |
13 | + <%= _('Created at: %s') % show_date(group.created_at) unless group.enterprise? %> <br/> | |
14 | + <% button_bar do %> | |
15 | + <% if user.has_permission?(:edit_profile, group) %> | |
16 | + <%= button 'menu-ctrl-panel', _('Control panel of this group'), group.admin_url %> | |
17 | + <% end %> | |
18 | + <%= button 'menu-logout', _('Leave community'), group.leave_url(true), :class => 'leave-community' %> | |
19 | + | |
20 | + <% if (user.has_permission?(:destroy_profile, group) && !environment.enabled?('forbid_destroy_profile')) || user.is_admin?(environment) %> | |
21 | + <%= button 'delete', _('Remove'), | |
22 | + { :controller => 'profile_editor', | |
23 | + :action => 'destroy_profile', | |
24 | + :profile => group.identifier } | |
25 | + %> | |
26 | + <% end %> | |
21 | 27 | <% end %> |
22 | - <% end %> | |
23 | - </span> | |
24 | - <br class="may-clear" /> | |
25 | - </li> | |
26 | -<% end %> | |
28 | + </span> | |
29 | + <br class="may-clear" /> | |
30 | + </li> | |
31 | + <% end %> | |
27 | 32 | </ul> |
28 | - | ... | ... |
config/application.rb
... | ... | @@ -126,7 +126,7 @@ module Noosfero |
126 | 126 | # Make sure the secret is at least 30 characters and all random, |
127 | 127 | # no regular words or you'll be exposed to dictionary attacks. |
128 | 128 | config.secret_token = noosfero_session_secret |
129 | - config.session_store :cookie_store, :key => '_noosfero_session' | |
129 | + config.session_store :active_record_store, key: '_noosfero_session' | |
130 | 130 | |
131 | 131 | config.paths['db/migrate'] += Dir.glob "#{Rails.root}/{baseplugins,config/plugins}/*/db/migrate" |
132 | 132 | config.i18n.load_path += Dir.glob "#{Rails.root}/{baseplugins,config/plugins}/*/locales/*.{rb,yml}" | ... | ... |
config/initializers/action_tracker.rb
... | ... | @@ -2,67 +2,51 @@ require 'noosfero/i18n' |
2 | 2 | |
3 | 3 | # ActionTracker plugin stuff |
4 | 4 | |
5 | -@reply_scrap_description = proc { _('sent a message to %{receiver}: <br /> "%{message}"') % { :receiver => "{{link_to(ta.get_receiver_name, ta.get_receiver_url)}}", :message => "{{auto_link_urls(ta.get_content)}}" } } | |
6 | - | |
7 | 5 | ActionTrackerConfig.verbs = { |
8 | 6 | |
9 | - :create_article => { | |
10 | - :description => proc { _('published an article: %{title}') % { :title => '{{link_to(truncate(ta.get_name), ta.get_url)}}' } } | |
7 | + create_article: { | |
8 | + }, | |
9 | + | |
10 | + new_friendship: { | |
11 | + type: :groupable | |
12 | + }, | |
13 | + | |
14 | + join_community: { | |
15 | + type: :groupable | |
11 | 16 | }, |
12 | 17 | |
13 | - :new_friendship => { | |
14 | - :description => proc { n_('has made 1 new friend:<br />%{name}', 'has made %{num} new friends:<br />%{name}', get_friend_name.size) % { :num => get_friend_name.size, :name => '{{ta.collect_group_with_index(:friend_name){ |n,i| link_to(image_tag(ta.get_friend_profile_custom_icon[i] || default_or_themed_icon("/images/icons-app/person-icon.png")), ta.get_friend_url[i], :title => n)}.join}}' } }, | |
15 | - :type => :groupable | |
18 | + add_member_in_community: { | |
16 | 19 | }, |
17 | 20 | |
18 | - :join_community => { | |
19 | - :description => proc { n_('has joined 1 community:<br />%{name}', 'has joined %{num} communities:<br />%{name}', get_resource_name.size) % { :num => get_resource_name.size, :name => '{{ta.collect_group_with_index(:resource_name){ |n,i| link_to(image_tag(ta.get_resource_profile_custom_icon[i] || default_or_themed_icon("/images/icons-app/community-icon.png")), ta.get_resource_url[i], :title => n)}.join}}' } }, | |
20 | - :type => :groupable | |
21 | + upload_image: { | |
22 | + type: :groupable | |
21 | 23 | }, |
22 | 24 | |
23 | - :add_member_in_community => { | |
24 | - :description => proc { _('has joined the community.') }, | |
25 | + leave_scrap: { | |
25 | 26 | }, |
26 | 27 | |
27 | - :upload_image => { | |
28 | - :description => proc do | |
29 | - total = get_view_url.size | |
30 | - n_('uploaded 1 image', 'uploaded %d images', total) % total + | |
31 | - '<br />{{'+ | |
32 | - 'ta.collect_group_with_index(:thumbnail_path) { |t,i|' + | |
33 | - " if ( #{total} == 1 );" + | |
34 | - ' link_to( image_tag(t), ta.get_view_url[i], :class => \'upimg\' );' + | |
35 | - ' else;' + | |
36 | - " pos = #{total}-i;" + | |
37 | - ' morethen2 = pos>2 ? \'morethen2\' : \'\';' + | |
38 | - ' morethen5 = pos>5 ? \'morethen5\' : \'\';' + | |
39 | - ' t = t.gsub(/(.*)(display)(.*)/, \'\\1thumb\\3\');' + | |
40 | - ' link_to( \' \', ta.get_view_url[i],' + | |
41 | - ' :style => "background-image:url(#{t})",' + | |
42 | - ' :class => "upimg pos#{pos} #{morethen2} #{morethen5}" );' + | |
43 | - ' end' + | |
44 | - '}.reverse.join}}' + | |
45 | - ( total > 5 ? | |
46 | - '<span class="more" onclick="this.parentNode.className+=\' show-all\'">' + | |
47 | - '…</span>' : '' ) + | |
48 | - '<br style="clear: both;" />' | |
49 | - end, | |
50 | - :type => :groupable | |
28 | + leave_scrap_to_self: { | |
51 | 29 | }, |
52 | 30 | |
53 | - :leave_scrap => { | |
54 | - :description => @reply_scrap_description | |
31 | + reply_scrap_on_self: { | |
55 | 32 | }, |
56 | 33 | |
57 | - :leave_scrap_to_self => { | |
58 | - :description => proc { _('wrote: <br /> "%{text}"') % { :text => "{{auto_link_urls(ta.get_content)}}" } } | |
34 | + create_product: { | |
59 | 35 | }, |
60 | 36 | |
61 | - :reply_scrap_on_self => { | |
62 | - :description => @reply_scrap_description | |
37 | + update_product: { | |
63 | 38 | }, |
39 | + | |
40 | + remove_product: { | |
41 | + }, | |
42 | + | |
43 | + favorite_enterprise: { | |
44 | + }, | |
45 | + | |
64 | 46 | } |
65 | 47 | |
66 | -ActionTrackerConfig.current_user_method = :current_person | |
48 | +ActionTrackerConfig.current_user = proc do | |
49 | + User.current.person rescue nil | |
50 | +end | |
67 | 51 | |
68 | 52 | ActionTrackerConfig.timeout = 24.hours | ... | ... |
config/routes.rb
... | ... | @@ -57,37 +57,37 @@ Noosfero::Application.routes.draw do |
57 | 57 | match 'search(/:action(/*category_path))', :controller => 'search' |
58 | 58 | |
59 | 59 | # events |
60 | - match 'profile/:profile/events_by_day', :controller => 'events', :action => 'events_by_day', :profile => /#{Noosfero.identifier_format_in_url}/ | |
61 | - match 'profile/:profile/events_by_month', :controller => 'events', :action => 'events_by_month', :profile => /#{Noosfero.identifier_format_in_url}/ | |
62 | - match 'profile/:profile/events/:year/:month/:day', :controller => 'events', :action => 'events', :year => /\d*/, :month => /\d*/, :day => /\d*/, :profile => /#{Noosfero.identifier_format_in_url}/ | |
63 | - match 'profile/:profile/events/:year/:month', :controller => 'events', :action => 'events', :year => /\d*/, :month => /\d*/, :profile => /#{Noosfero.identifier_format_in_url}/ | |
64 | - match 'profile/:profile/events', :controller => 'events', :action => 'events', :profile => /#{Noosfero.identifier_format_in_url}/ | |
60 | + match 'profile/:profile/events_by_day', :controller => 'events', :action => 'events_by_day', :profile => /#{Noosfero.identifier_format_in_url}/i | |
61 | + match 'profile/:profile/events_by_month', :controller => 'events', :action => 'events_by_month', :profile => /#{Noosfero.identifier_format_in_url}/i | |
62 | + match 'profile/:profile/events/:year/:month/:day', :controller => 'events', :action => 'events', :year => /\d*/, :month => /\d*/, :day => /\d*/, :profile => /#{Noosfero.identifier_format_in_url}/i | |
63 | + match 'profile/:profile/events/:year/:month', :controller => 'events', :action => 'events', :year => /\d*/, :month => /\d*/, :profile => /#{Noosfero.identifier_format_in_url}/i | |
64 | + match 'profile/:profile/events', :controller => 'events', :action => 'events', :profile => /#{Noosfero.identifier_format_in_url}/i | |
65 | 65 | |
66 | 66 | # catalog |
67 | - match 'catalog/:profile', :controller => 'catalog', :action => 'index', :profile => /#{Noosfero.identifier_format_in_url}/, :as => :catalog | |
67 | + match 'catalog/:profile', :controller => 'catalog', :action => 'index', :profile => /#{Noosfero.identifier_format_in_url}/i, :as => :catalog | |
68 | 68 | |
69 | 69 | # invite |
70 | - match 'profile/:profile/invite/friends', :controller => 'invite', :action => 'invite_friends', :profile => /#{Noosfero.identifier_format_in_url}/ | |
71 | - match 'profile/:profile/invite/:action', :controller => 'invite', :profile => /#{Noosfero.identifier_format_in_url}/ | |
70 | + match 'profile/:profile/invite/friends', :controller => 'invite', :action => 'invite_friends', :profile => /#{Noosfero.identifier_format_in_url}/i | |
71 | + match 'profile/:profile/invite/:action', :controller => 'invite', :profile => /#{Noosfero.identifier_format_in_url}/i | |
72 | 72 | |
73 | 73 | # feeds per tag |
74 | - match 'profile/:profile/tags/:id/feed', :controller => 'profile', :action =>'tag_feed', :id => /.+/, :profile => /#{Noosfero.identifier_format_in_url}/, :as => :tag_feed | |
74 | + match 'profile/:profile/tags/:id/feed', :controller => 'profile', :action =>'tag_feed', :id => /.+/, :profile => /#{Noosfero.identifier_format_in_url}/i, :as => :tag_feed | |
75 | 75 | |
76 | 76 | # profile tags |
77 | - match 'profile/:profile/tags/:id', :controller => 'profile', :action => 'content_tagged', :id => /.+/, :profile => /#{Noosfero.identifier_format_in_url}/ | |
78 | - match 'profile/:profile/tags(/:id)', :controller => 'profile', :action => 'tags', :profile => /#{Noosfero.identifier_format_in_url}/ | |
77 | + match 'profile/:profile/tags/:id', :controller => 'profile', :action => 'content_tagged', :id => /.+/, :profile => /#{Noosfero.identifier_format_in_url}/i | |
78 | + match 'profile/:profile/tags(/:id)', :controller => 'profile', :action => 'tags', :profile => /#{Noosfero.identifier_format_in_url}/i | |
79 | 79 | |
80 | 80 | # profile search |
81 | - match 'profile/:profile/search', :controller => 'profile_search', :action => 'index', :profile => /#{Noosfero.identifier_format_in_url}/ | |
81 | + match 'profile/:profile/search', :controller => 'profile_search', :action => 'index', :profile => /#{Noosfero.identifier_format_in_url}/i | |
82 | 82 | |
83 | 83 | # comments |
84 | - match 'profile/:profile/comment/:action/:id', :controller => 'comment', :profile => /#{Noosfero.identifier_format_in_url}/ | |
84 | + match 'profile/:profile/comment/:action/:id', :controller => 'comment', :profile => /#{Noosfero.identifier_format_in_url}/i | |
85 | 85 | |
86 | 86 | # public profile information |
87 | - match 'profile/:profile(/:action(/:id))', :controller => 'profile', :action => 'index', :id => /[^\/]*/, :profile => /#{Noosfero.identifier_format_in_url}/, :as => :profile | |
87 | + match 'profile/:profile(/:action(/:id))', :controller => 'profile', :action => 'index', :id => /[^\/]*/, :profile => /#{Noosfero.identifier_format_in_url}/i, :as => :profile | |
88 | 88 | |
89 | 89 | # contact |
90 | - match 'contact/:profile/:action(/:id)', :controller => 'contact', :action => 'index', :id => /.*/, :profile => /#{Noosfero.identifier_format_in_url}/ | |
90 | + match 'contact/:profile/:action(/:id)', :controller => 'contact', :action => 'index', :id => /.*/, :profile => /#{Noosfero.identifier_format_in_url}/i | |
91 | 91 | |
92 | 92 | # map balloon |
93 | 93 | match 'map_balloon/:action/:id', :controller => 'map_balloon', :id => /.*/ |
... | ... | @@ -99,8 +99,8 @@ Noosfero::Application.routes.draw do |
99 | 99 | ## Controllers that are profile-specific (for profile admins ) |
100 | 100 | ###################################################### |
101 | 101 | # profile customization - "My profile" |
102 | - match 'myprofile/:profile', :controller => 'profile_editor', :action => 'index', :profile => /#{Noosfero.identifier_format_in_url}/ | |
103 | - match 'myprofile/:profile/:controller(/:action(/:id))', :controller => Noosfero.pattern_for_controllers_in_directory('my_profile'), :profile => /#{Noosfero.identifier_format_in_url}/, :as => :myprofile | |
102 | + match 'myprofile/:profile', :controller => 'profile_editor', :action => 'index', :profile => /#{Noosfero.identifier_format_in_url}/i | |
103 | + match 'myprofile/:profile/:controller(/:action(/:id))', :controller => Noosfero.pattern_for_controllers_in_directory('my_profile'), :profile => /#{Noosfero.identifier_format_in_url}/i, :as => :myprofile | |
104 | 104 | |
105 | 105 | |
106 | 106 | ###################################################### |
... | ... | @@ -128,14 +128,14 @@ Noosfero::Application.routes.draw do |
128 | 128 | # cache stuff - hack |
129 | 129 | match 'public/:action/:id', :controller => 'public' |
130 | 130 | |
131 | - match ':profile/*page/versions', :controller => 'content_viewer', :action => 'article_versions', :profile => /#{Noosfero.identifier_format_in_url}/, :constraints => EnvironmentDomainConstraint.new | |
131 | + match ':profile/*page/versions', :controller => 'content_viewer', :action => 'article_versions', :profile => /#{Noosfero.identifier_format_in_url}/i, :constraints => EnvironmentDomainConstraint.new | |
132 | 132 | match '*page/versions', :controller => 'content_viewer', :action => 'article_versions' |
133 | 133 | |
134 | - match ':profile/*page/versions_diff', :controller => 'content_viewer', :action => 'versions_diff', :profile => /#{Noosfero.identifier_format_in_url}/, :constraints => EnvironmentDomainConstraint.new | |
134 | + match ':profile/*page/versions_diff', :controller => 'content_viewer', :action => 'versions_diff', :profile => /#{Noosfero.identifier_format_in_url}/i, :constraints => EnvironmentDomainConstraint.new | |
135 | 135 | match '*page/versions_diff', :controller => 'content_viewer', :action => 'versions_diff' |
136 | 136 | |
137 | 137 | # match requests for profiles that don't have a custom domain |
138 | - match ':profile(/*page)', :controller => 'content_viewer', :action => 'view_page', :profile => /#{Noosfero.identifier_format_in_url}/, :constraints => EnvironmentDomainConstraint.new | |
138 | + match ':profile(/*page)', :controller => 'content_viewer', :action => 'view_page', :profile => /#{Noosfero.identifier_format_in_url}/i, :constraints => EnvironmentDomainConstraint.new | |
139 | 139 | |
140 | 140 | # match requests for content in domains hosted for profiles |
141 | 141 | match '/(*page)', :controller => 'content_viewer', :action => 'view_page' | ... | ... |
... | ... | @@ -0,0 +1,26 @@ |
1 | +class CreateProfileActivity < ActiveRecord::Migration | |
2 | + def up | |
3 | + ActiveRecord::Base.transaction do | |
4 | + create_table :profile_activities do |t| | |
5 | + t.integer :profile_id | |
6 | + t.integer :activity_id | |
7 | + t.string :activity_type | |
8 | + t.timestamps | |
9 | + end | |
10 | + add_index :profile_activities, :profile_id | |
11 | + add_index :profile_activities, [:activity_id, :activity_type] | |
12 | + add_index :profile_activities, :activity_type | |
13 | + | |
14 | + Scrap.find_each batch_size: 50 do |scrap| | |
15 | + scrap.send :create_activity | |
16 | + end | |
17 | + ActionTracker::Record.find_each batch_size: 50 do |action_tracker| | |
18 | + action_tracker.send :create_activity | |
19 | + end | |
20 | + end | |
21 | + end | |
22 | + | |
23 | + def down | |
24 | + drop_table :profile_activities | |
25 | + end | |
26 | +end | ... | ... |
db/migrate/20150310132902_add_id_to_favorite_enterprises_people.rb
0 → 100644
... | ... | @@ -0,0 +1,26 @@ |
1 | +class AddIdToFavoriteEnterprisesPeople < ActiveRecord::Migration | |
2 | + def up | |
3 | + rename_table :favorite_enteprises_people, :favorite_enterprise_people | |
4 | + | |
5 | + change_table :favorite_enterprise_people do |t| | |
6 | + t.timestamps | |
7 | + end | |
8 | + add_column :favorite_enterprise_people, :id, :primary_key | |
9 | + | |
10 | + add_index :favorite_enterprise_people, [:person_id, :enterprise_id] | |
11 | + add_index :favorite_enterprise_people, :person_id | |
12 | + add_index :favorite_enterprise_people, :enterprise_id | |
13 | + end | |
14 | + | |
15 | + def down | |
16 | + rename_table :favorite_enterprise_people, :favorite_enteprises_people | |
17 | + | |
18 | + remove_column :favorite_enteprises_people, :id | |
19 | + remove_column :favorite_enteprises_people, :created_at | |
20 | + remove_column :favorite_enteprises_people, :updated_at | |
21 | + | |
22 | + remove_index :favorite_enteprises_people, [:person_id, :enterprise_id] | |
23 | + remove_index :favorite_enteprises_people, :person_id | |
24 | + remove_index :favorite_enteprises_people, :enterprise_id | |
25 | + end | |
26 | +end | ... | ... |
... | ... | @@ -0,0 +1,31 @@ |
1 | +class AddUserIdToSession < ActiveRecord::Migration | |
2 | + | |
3 | + def change | |
4 | + add_column :sessions, :user_id, :integer | |
5 | + add_index :sessions, :user_id | |
6 | + end | |
7 | + | |
8 | + def up | |
9 | + Session.reset_column_information | |
10 | + | |
11 | + # cleanup data: {} | |
12 | + Session.where(data: "BAh7AA==\n").delete_all | |
13 | + # cleanup data with lang key only | |
14 | + Session.where("data ~ 'BAh7BjoJbGFuZyIH.{3,3}=\n'").delete_all | |
15 | + | |
16 | + # very slow migration, only do for the last month | |
17 | + Session.where('updated_at > ?', 1.month.ago).find_each batch_size: 50 do |session| | |
18 | + begin | |
19 | + # this calls Session#copy_to_columns | |
20 | + session.save! | |
21 | + rescue ArgumentError | |
22 | + # old ActionController::Flash::FlashHash from rails 2.3 | |
23 | + session.destroy | |
24 | + end | |
25 | + | |
26 | + # limit limitless allocations | |
27 | + GC.start | |
28 | + end | |
29 | + end | |
30 | + | |
31 | +end | ... | ... |
db/migrate/20150722042714_change_article_date_to_datetime.rb
0 → 100644
... | ... | @@ -0,0 +1,27 @@ |
1 | +class ChangeArticleDateToDatetime < ActiveRecord::Migration | |
2 | + | |
3 | + def up | |
4 | + change_table :articles do |t| | |
5 | + t.change :start_date, :datetime | |
6 | + t.change :end_date, :datetime | |
7 | + end | |
8 | + | |
9 | + change_table :article_versions do |t| | |
10 | + t.change :start_date, :datetime | |
11 | + t.change :end_date, :datetime | |
12 | + end | |
13 | + end | |
14 | + | |
15 | + def down | |
16 | + change_table :articles do |t| | |
17 | + t.change :start_date, :date | |
18 | + t.change :end_date, :date | |
19 | + end | |
20 | + | |
21 | + change_table :article_versions do |t| | |
22 | + t.change :start_date, :date | |
23 | + t.change :end_date, :date | |
24 | + end | |
25 | + end | |
26 | + | |
27 | +end | ... | ... |
db/schema.rb
... | ... | @@ -11,7 +11,7 @@ |
11 | 11 | # |
12 | 12 | # It's strongly recommended to check this file into your version control system. |
13 | 13 | |
14 | -ActiveRecord::Schema.define(:version => 20150603182105) do | |
14 | +ActiveRecord::Schema.define(:version => 20150722042714) do | |
15 | 15 | |
16 | 16 | create_table "abuse_reports", :force => true do |t| |
17 | 17 | t.integer "reporter_id" |
... | ... | @@ -75,8 +75,8 @@ ActiveRecord::Schema.define(:version => 20150603182105) do |
75 | 75 | t.integer "comments_count" |
76 | 76 | t.boolean "advertise", :default => true |
77 | 77 | t.boolean "published", :default => true |
78 | - t.date "start_date" | |
79 | - t.date "end_date" | |
78 | + t.datetime "start_date" | |
79 | + t.datetime "end_date" | |
80 | 80 | t.integer "children_count", :default => 0 |
81 | 81 | t.boolean "accept_comments", :default => true |
82 | 82 | t.integer "reference_article_id" |
... | ... | @@ -127,8 +127,8 @@ ActiveRecord::Schema.define(:version => 20150603182105) do |
127 | 127 | t.integer "comments_count", :default => 0 |
128 | 128 | t.boolean "advertise", :default => true |
129 | 129 | t.boolean "published", :default => true |
130 | - t.date "start_date" | |
131 | - t.date "end_date" | |
130 | + t.datetime "start_date" | |
131 | + t.datetime "end_date" | |
132 | 132 | t.integer "children_count", :default => 0 |
133 | 133 | t.boolean "accept_comments", :default => true |
134 | 134 | t.integer "reference_article_id" |
... | ... | @@ -351,11 +351,17 @@ ActiveRecord::Schema.define(:version => 20150603182105) do |
351 | 351 | add_index "external_feeds", ["enabled"], :name => "index_external_feeds_on_enabled" |
352 | 352 | add_index "external_feeds", ["fetched_at"], :name => "index_external_feeds_on_fetched_at" |
353 | 353 | |
354 | - create_table "favorite_enteprises_people", :id => false, :force => true do |t| | |
355 | - t.integer "person_id" | |
356 | - t.integer "enterprise_id" | |
354 | + create_table "favorite_enterprise_people", :force => true do |t| | |
355 | + t.integer "person_id" | |
356 | + t.integer "enterprise_id" | |
357 | + t.datetime "created_at" | |
358 | + t.datetime "updated_at" | |
357 | 359 | end |
358 | 360 | |
361 | + add_index "favorite_enterprise_people", ["enterprise_id"], :name => "index_favorite_enterprise_people_on_enterprise_id" | |
362 | + add_index "favorite_enterprise_people", ["person_id", "enterprise_id"], :name => "index_favorite_enterprise_people_on_person_id_and_enterprise_id" | |
363 | + add_index "favorite_enterprise_people", ["person_id"], :name => "index_favorite_enterprise_people_on_person_id" | |
364 | + | |
359 | 365 | create_table "friendships", :force => true do |t| |
360 | 366 | t.integer "person_id" |
361 | 367 | t.integer "friend_id" |
... | ... | @@ -489,6 +495,18 @@ ActiveRecord::Schema.define(:version => 20150603182105) do |
489 | 495 | add_index "products", ["product_category_id"], :name => "index_products_on_product_category_id" |
490 | 496 | add_index "products", ["profile_id"], :name => "index_products_on_profile_id" |
491 | 497 | |
498 | + create_table "profile_activities", :force => true do |t| | |
499 | + t.integer "profile_id" | |
500 | + t.integer "activity_id" | |
501 | + t.string "activity_type" | |
502 | + t.datetime "created_at", :null => false | |
503 | + t.datetime "updated_at", :null => false | |
504 | + end | |
505 | + | |
506 | + add_index "profile_activities", ["activity_id", "activity_type"], :name => "index_profile_activities_on_activity_id_and_activity_type" | |
507 | + add_index "profile_activities", ["activity_type"], :name => "index_profile_activities_on_activity_type" | |
508 | + add_index "profile_activities", ["profile_id"], :name => "index_profile_activities_on_profile_id" | |
509 | + | |
492 | 510 | create_table "profile_suggestions", :force => true do |t| |
493 | 511 | t.integer "person_id" |
494 | 512 | t.integer "suggestion_id" |
... | ... | @@ -555,6 +573,8 @@ ActiveRecord::Schema.define(:version => 20150603182105) do |
555 | 573 | add_index "profiles", ["identifier"], :name => "index_profiles_on_identifier" |
556 | 574 | add_index "profiles", ["members_count"], :name => "index_profiles_on_members_count" |
557 | 575 | add_index "profiles", ["region_id"], :name => "index_profiles_on_region_id" |
576 | + add_index "profiles", ["user_id", "type"], :name => "index_profiles_on_user_id_and_type" | |
577 | + add_index "profiles", ["user_id"], :name => "index_profiles_on_user_id" | |
558 | 578 | |
559 | 579 | create_table "qualifier_certifiers", :force => true do |t| |
560 | 580 | t.integer "qualifier_id" |
... | ... | @@ -645,10 +665,12 @@ ActiveRecord::Schema.define(:version => 20150603182105) do |
645 | 665 | t.text "data" |
646 | 666 | t.datetime "created_at" |
647 | 667 | t.datetime "updated_at" |
668 | + t.integer "user_id" | |
648 | 669 | end |
649 | 670 | |
650 | 671 | add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id" |
651 | 672 | add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at" |
673 | + add_index "sessions", ["user_id"], :name => "index_sessions_on_user_id" | |
652 | 674 | |
653 | 675 | create_table "suggestion_connections", :force => true do |t| |
654 | 676 | t.integer "suggestion_id", :null => false | ... | ... |
debian/changelog
doc/noosfero/navigation/searching-enterprises.textile
... | ... | @@ -14,7 +14,7 @@ p. Find on top of page the term "Enterprises" and click on it: |
14 | 14 | h2(#description). Description |
15 | 15 | |
16 | 16 | # Fill in the search field with what you want to look for and click on "Search" !=/images/doc/enterprises-search-field.en.png(Enterprises search field)! |
17 | -# Then you will see the search results. To see more results, click on the pages below the search results. !=/images/doc/enterprises-search-results-with-example.en.png(Enteprises search results with example)! | |
17 | +# Then you will see the search results. To see more results, click on the pages below the search results. !=/images/doc/enterprises-search-results-with-example.en.png(Enterprises search results with example)! | |
18 | 18 | # Clicking on one of the search results, you will be redirected to the homepage of choosen enterprise. |
19 | 19 | |
20 | 20 | h3. More options | ... | ... |
features/accept_member.feature
... | ... | @@ -14,6 +14,16 @@ Feature: accept member |
14 | 14 | And the community "My Community" is closed |
15 | 15 | And "Mario Souto" is admin of "My Community" |
16 | 16 | |
17 | + Scenario: a user should see its merbership is pending | |
18 | + Given I am logged in as "mario" | |
19 | + And the following communities | |
20 | + | owner | identifier | name | closed | | |
21 | + | marie | private-community | Private Community | true | | |
22 | + And I go to private-community's homepage | |
23 | + When I follow "Join this community" | |
24 | + And I go to private-community's homepage | |
25 | + Then I should see "Your membership is waiting for approval" | |
26 | + | |
17 | 27 | @selenium |
18 | 28 | Scenario: approve a task to accept a member as admin in a closed community |
19 | 29 | Given "Marie Curie" asked to join "My Community" | ... | ... |
features/events.feature
... | ... | @@ -223,7 +223,7 @@ Feature: events |
223 | 223 | | owner | name | start_date | end_date | |
224 | 224 | | josesilva | WikiSym 2009 | 2009-10-25 | 2009-10-27 | |
225 | 225 | When I am on /profile/josesilva/events/2009/10/26 |
226 | - Then I should see "October 25, 2009 to October 27, 2009" | |
226 | + Then I should see "October 25, 2009 0:00 to October 27, 2009 0:00" | |
227 | 227 | |
228 | 228 | Scenario: show place of the event |
229 | 229 | Given I am on /profile/josesilva/events/2009/10 | ... | ... |
features/members_block.feature
... | ... | @@ -9,8 +9,8 @@ Feature: |
9 | 9 | | joaosilva | Joao Silva | |
10 | 10 | | mariasilva | Maria Silva | |
11 | 11 | And the following communities |
12 | - | owner | identifier | name | | |
13 | - | joaosilva | sample-community | Sample Community | | |
12 | + | owner | identifier | name | | |
13 | + | joaosilva | sample-community | Sample Community | | |
14 | 14 | And the following blocks |
15 | 15 | | owner | type | |
16 | 16 | | sample-community | MembersBlock | |
... | ... | @@ -24,7 +24,7 @@ Feature: |
24 | 24 | Scenario: a user can join in a community by members block's button |
25 | 25 | Given I am logged in as "mariasilva" |
26 | 26 | And I go to sample-community's homepage |
27 | - When I follow "Join" within ".members-block" | |
27 | + When I follow "Join this community" within ".members-block" | |
28 | 28 | And I go to mariasilva's control panel |
29 | 29 | And I follow "Manage my groups" |
30 | 30 | Then I should see "Sample Community" |
... | ... | @@ -41,7 +41,7 @@ Feature: |
41 | 41 | Scenario: a not logged in user can log in by members block's button |
42 | 42 | Given I am not logged in |
43 | 43 | When I go to sample-community's homepage |
44 | - And I follow "Join" within ".members-block" | |
44 | + And I follow "Join this community" within ".members-block" | |
45 | 45 | Then I should see "Username / Email" |
46 | 46 | |
47 | 47 | Scenario: the join-leave button do not appear if the checkbox show-join-leave-button is not checked |
... | ... | @@ -51,5 +51,5 @@ Feature: |
51 | 51 | And I uncheck "Show join leave button" |
52 | 52 | And I press "Save" |
53 | 53 | When I go to sample-community's homepage |
54 | - Then I should not see "Join" within ".members-block" | |
54 | + Then I should not see "Join this community" within ".members-block" | |
55 | 55 | And I should not see "Leave community" within ".members-block" | ... | ... |
lib/authenticated_system.rb
1 | 1 | module AuthenticatedSystem |
2 | + | |
2 | 3 | protected |
4 | + | |
5 | + # See impl. from http://stackoverflow.com/a/2513456/670229 | |
6 | + def self.included? base | |
7 | + base.around_filter do | |
8 | + begin | |
9 | + User.current = current_user | |
10 | + yield | |
11 | + ensure | |
12 | + # to address the thread variable leak issues in Puma/Thin webserver | |
13 | + User.current = nil | |
14 | + end | |
15 | + end | |
16 | + end | |
17 | + | |
3 | 18 | # Returns true or false if the user is logged in. |
4 | 19 | # Preloads @current_user with the user model if they're logged in. |
5 | 20 | def logged_in? |
... | ... | @@ -8,7 +23,13 @@ module AuthenticatedSystem |
8 | 23 | |
9 | 24 | # Accesses the current user from the session. |
10 | 25 | def current_user |
11 | - @current_user ||= (session[:user] && User.find_by_id(session[:user])) || nil | |
26 | + @current_user ||= begin | |
27 | + id = session[:user] | |
28 | + user = User.where(id: id).first if id | |
29 | + user.session = session if user | |
30 | + User.current = user | |
31 | + user | |
32 | + end | |
12 | 33 | end |
13 | 34 | |
14 | 35 | # Store the given user in the session. |
... | ... | @@ -17,9 +38,10 @@ module AuthenticatedSystem |
17 | 38 | session.delete(:user) |
18 | 39 | else |
19 | 40 | session[:user] = new_user.id |
41 | + new_user.session = session | |
20 | 42 | new_user.register_login |
21 | 43 | end |
22 | - @current_user = new_user | |
44 | + @current_user = User.current = new_user | |
23 | 45 | end |
24 | 46 | |
25 | 47 | # Check if the user is authorized. |
... | ... | @@ -121,14 +143,9 @@ module AuthenticatedSystem |
121 | 143 | # When called with before_filter :login_from_cookie will check for an :auth_token |
122 | 144 | # cookie and log the user back in if apropriate |
123 | 145 | def login_from_cookie |
124 | - return unless cookies[:auth_token] && !logged_in? | |
125 | - user = User.find_by_remember_token(cookies[:auth_token]) | |
126 | - if user && user.remember_token? | |
127 | - user.remember_me | |
128 | - self.current_user = user | |
129 | - cookies[:auth_token] = { :value => self.current_user.remember_token , :expires => self.current_user.remember_token_expires_at } | |
130 | - flash[:notice] = "Logged in successfully" | |
131 | - end | |
146 | + return if cookies[:auth_token].blank? or logged_in? | |
147 | + user = User.where(remember_token: cookies[:auth_token]).first | |
148 | + self.current_user = user if user and user.remember_token? | |
132 | 149 | end |
133 | 150 | |
134 | 151 | private | ... | ... |
lib/needs_profile.rb
... | ... | @@ -21,7 +21,11 @@ module NeedsProfile |
21 | 21 | protected |
22 | 22 | |
23 | 23 | def load_profile |
24 | - @profile ||= environment.profiles.find_by_identifier(params[:profile]) | |
24 | + if params[:profile] | |
25 | + params[:profile].downcase! | |
26 | + @profile ||= environment.profiles.where(identifier: params[:profile]).first | |
27 | + end | |
28 | + | |
25 | 29 | if @profile |
26 | 30 | profile_hostname = @profile.hostname |
27 | 31 | if profile_hostname && profile_hostname != request.host | ... | ... |
lib/noosfero/action_tracker_ext.rb
1 | 1 | Rails.configuration.to_prepare do |
2 | - ActionTracker::Record.module_eval do | |
2 | + ActionTracker::Record.class_eval do | |
3 | 3 | extend CacheCounterHelper |
4 | 4 | |
5 | 5 | after_create do |record| |
... | ... | @@ -9,6 +9,11 @@ Rails.configuration.to_prepare do |
9 | 9 | end |
10 | 10 | end |
11 | 11 | |
12 | + has_many :profile_activities, foreign_key: :activity_id, conditions: {profile_activities: {activity_type: 'ActionTracker::Record'}}, dependent: :destroy | |
13 | + | |
14 | + after_create :create_activity | |
15 | + after_update :update_activity | |
16 | + | |
12 | 17 | after_destroy do |record| |
13 | 18 | if record.created_at >= ActionTracker::Record::RECENT_DELAY.days.ago |
14 | 19 | ActionTracker::Record.update_cache_counter(:activities_count, record.user, -1) |
... | ... | @@ -17,5 +22,17 @@ Rails.configuration.to_prepare do |
17 | 22 | end |
18 | 23 | end |
19 | 24 | end |
25 | + | |
26 | + protected | |
27 | + | |
28 | + def create_activity | |
29 | + target = if self.target.is_a? Profile then self.target else self.target.profile rescue self.user end | |
30 | + return if self.verb.in? target.exclude_verbs_on_activities | |
31 | + ProfileActivity.create! profile: target, activity: self | |
32 | + end | |
33 | + def update_activity | |
34 | + ProfileActivity.update_activity self | |
35 | + end | |
36 | + | |
20 | 37 | end |
21 | 38 | end | ... | ... |
lib/noosfero/plugin/routes.rb
... | ... | @@ -19,15 +19,15 @@ Dir.glob(Rails.root.join(plugins_root, '*', 'controllers')) do |controllers_dir| |
19 | 19 | controllers.each do |controller| |
20 | 20 | controller_name = controller.gsub("#{plugin_name}_plugin_",'') |
21 | 21 | if %w[profile myprofile].include?(folder.to_s) |
22 | - match "#{prefixes_by_folder[folder]}/#{plugin_name}/#{controller_name}(/:action(/:id))", :controller => controller, :profile => /#{Noosfero.identifier_format}/ | |
22 | + match "#{prefixes_by_folder[folder]}/#{plugin_name}/#{controller_name}(/:action(/:id))", controller: controller, profile: /#{Noosfero.identifier_format_in_url}/i | |
23 | 23 | else |
24 | - match "#{prefixes_by_folder[folder]}/#{plugin_name}/#{controller_name}(/:action(/:id))", :controller => controller | |
24 | + match "#{prefixes_by_folder[folder]}/#{plugin_name}/#{controller_name}(/:action(/:id))", controller: controller | |
25 | 25 | end |
26 | 26 | end |
27 | 27 | end |
28 | 28 | |
29 | - match 'plugin/' + plugin_name + '(/:action(/:id))', :controller => plugin_name + '_plugin' | |
30 | - match 'profile/:profile/plugin/' + plugin_name + '(/:action(/:id))', :controller => plugin_name + '_plugin_profile', :profile => /#{Noosfero.identifier_format}/ | |
31 | - match 'myprofile/:profile/plugin/' + plugin_name + '(/:action(/:id))', :controller => plugin_name + '_plugin_myprofile', :profile => /#{Noosfero.identifier_format}/ | |
32 | - match 'admin/plugin/' + plugin_name + '(/:action(/:id))', :controller => plugin_name + '_plugin_admin' | |
29 | + match 'plugin/' + plugin_name + '(/:action(/:id))', controller: plugin_name + '_plugin' | |
30 | + match 'profile/:profile/plugin/' + plugin_name + '(/:action(/:id))', controller: plugin_name + '_plugin_profile', profile: /#{Noosfero.identifier_format_in_url}/i | |
31 | + match 'myprofile/:profile/plugin/' + plugin_name + '(/:action(/:id))', controller: plugin_name + '_plugin_myprofile', profile: /#{Noosfero.identifier_format_in_url}/i | |
32 | + match 'admin/plugin/' + plugin_name + '(/:action(/:id))', controller: plugin_name + '_plugin_admin' | |
33 | 33 | end | ... | ... |
lib/noosfero/version.rb
lib/notify_activity_to_profiles_job.rb
... | ... | @@ -22,6 +22,12 @@ class NotifyActivityToProfilesJob < Struct.new(:tracked_action_id) |
22 | 22 | # Notify all friends |
23 | 23 | ActionTrackerNotification.connection.execute("insert into action_tracker_notifications(profile_id, action_tracker_id) select f.friend_id, #{tracked_action.id} from friendships as f where person_id=#{tracked_action.user.id} and f.friend_id not in (select atn.profile_id from action_tracker_notifications as atn where atn.action_tracker_id = #{tracked_action.id})") |
24 | 24 | |
25 | + if tracked_action.user.is_a? Organization | |
26 | + ActionTrackerNotification.connection.execute "insert into action_tracker_notifications(profile_id, action_tracker_id) " + | |
27 | + "select distinct accessor_id, #{tracked_action.id} from role_assignments where resource_id = #{tracked_action.user.id} and resource_type='Profile' " + | |
28 | + if tracked_action.user.is_a? Enterprise then "union select distinct person_id, #{tracked_action.id} from favorite_enterprise_people where enterprise_id = #{tracked_action.user.id}" else "" end | |
29 | + end | |
30 | + | |
25 | 31 | if target.is_a?(Community) |
26 | 32 | ActionTrackerNotification.create(:profile_id => target.id, :action_tracker_id => tracked_action.id) unless NOT_NOTIFY_COMMUNITY.include?(tracked_action.verb) |
27 | 33 | ... | ... |
lib/tasks/ci.rake
... | ... | @@ -37,6 +37,11 @@ namespace :ci do |
37 | 37 | tests << t unless tests.include?(t) |
38 | 38 | end |
39 | 39 | end |
40 | + if f =~ %r{^app/views/(\w*)/} | |
41 | + controller = $1 | |
42 | + t = "test/functional/#{controller}_controller_test.rb" | |
43 | + tests << t if File.exists?(t) && !tests.include?(t) | |
44 | + end | |
40 | 45 | end |
41 | 46 | |
42 | 47 | if tests.empty? && features.empty? && changed_plugins.empty? | ... | ... |
lib/tasks/enable_plugins.rake
lib/tasks/gettext.rake
... | ... | @@ -60,6 +60,8 @@ task :updatepo do |
60 | 60 | |
61 | 61 | puts 'Extracting strings from source. This may take a while ...' |
62 | 62 | |
63 | + # XXX this list is duplicated in test/unit/i18n_test.rb; if you change it | |
64 | + # here, please also update it there. | |
63 | 65 | files_to_translate = [ |
64 | 66 | "{app,lib}/**/*.{rb,rhtml,erb}", |
65 | 67 | 'config/initializers/*.rb', |
... | ... | @@ -98,7 +100,7 @@ Dir.glob('plugins/*').each do |plugindir| |
98 | 100 | } |
99 | 101 | ) |
100 | 102 | plugin_pot = File.join(po_root, "#{plugin}.pot") |
101 | - if File.exists?(plugin_pot) && system("LANG=C msgfmt --statistics --output /dev/null #{plugin_pot} 2>&1 | grep -q '^0 translated messages.'") | |
103 | + if File.exists?(plugin_pot) && system("LANG=C msgfmt --statistics --output /dev/null #{plugin_pot} 2>&1 | grep -q '^0 translated messages.$'") | |
102 | 104 | rm_f plugin_pot |
103 | 105 | end |
104 | 106 | sh 'find', po_root, '-type', 'd', '-empty', '-delete' |
... | ... | @@ -106,8 +108,25 @@ Dir.glob('plugins/*').each do |plugindir| |
106 | 108 | end |
107 | 109 | end |
108 | 110 | |
111 | +def checkpo(po_files) | |
112 | + max = po_files.map(&:size).max | |
113 | + po_files.each do |po| | |
114 | + printf "%#{max}s: ", po | |
115 | + system "msgfmt --statistics --output /dev/null " + po | |
116 | + end | |
117 | +end | |
118 | + | |
119 | +desc "checks core translation files" | |
109 | 120 | task :checkpo do |
110 | - sh 'for po in po/*/noosfero.po; do echo -n "$po: "; msgfmt --statistics --output /dev/null $po; done' | |
121 | + checkpo(Dir.glob('po/*/noosfero.po')) | |
122 | +end | |
123 | + | |
124 | +languages = Dir.glob('po/*').select { |d| File.directory?(d) }.map { |d| File.basename(d) } | |
125 | +languages.each do |lang| | |
126 | + desc "checks #{lang} translation files" | |
127 | + task "checkpo:#{lang}" do | |
128 | + checkpo(Dir.glob("po/#{lang}/*.po") + Dir.glob("plugins/*/po/#{lang}/*.po")) | |
129 | + end | |
111 | 130 | end |
112 | 131 | |
113 | 132 | # vim: ft=ruby | ... | ... |
lib/tasks/plugins_tests.rake