Commit 26e347c97700057eb31a2b12722ccb32540e03e5

Authored by Joenio Costa
2 parents bc6b356a f9358611

Merge branch 'master' into AI3280-tagging

Showing 182 changed files with 10801 additions and 6311 deletions   Show diff stats

Too many changes.

To preserve performance only 100 of 182 files displayed.

... ... @@ -1,250 +0,0 @@
1   -If you are not listed here, but should be, please write to the noosfero mailing
2   -list: http://listas.softwarelivre.org/cgi-bin/mailman/listinfo/noosfero-dev
3   -(this list requires subscription to post, but since you are an author of
4   -noosfero, that's not a problem).
5   -
6   -Developers
7   -==========
8   -
9   -Ábner Silva de Oliveira <abner.oliveira@serpro.gov.br>
10   -Alan Freihof Tygel <alantygel@gmail.com>
11   -alcampelo <alcampelo@alcampelo.(none)>
12   -Alessandro Palmeira <alessandro.palmeira@gmail.com>
13   -Alessandro Palmeira + Caio C. Salgado <alessandro.palmeira@gmail.com>
14   -Alessandro Palmeira + Caio Salgado <alessandro.palmeira@gmail.com>
15   -Alessandro Palmeira + Caio Salgado <caio.csalgado@gmail.com>
16   -Alessandro Palmeira + Caio Salgado + Diego Araújo + João M. M. da Silva <diegoamc90@gmail.com>
17   -Alessandro Palmeira + Carlos Morais <alessandro.palmeira@gmail.com>
18   -Alessandro Palmeira + Daniel Alves <alessandro.palmeira@gmail.com>
19   -Alessandro Palmeira + Daniel Alves + Diego Araújo <diegoamc90@gmail.com>
20   -Alessandro Palmeira + Daniel Alves + Diego Araújo + Guilherme Rojas <danpaulalves@gmail.com>
21   -Alessandro Palmeira + Diego Araujo <alessandro.palmeira@gmail.com>
22   -Alessandro Palmeira + Diego Araújo <alessandro.palmeira@gmail.com>
23   -Alessandro Palmeira + Diego Araujo + Daniela Feitosa <alessandro.palmeira@gmail.com>
24   -Alessandro Palmeira + Diego Araujo <diegoamc90@gmail.com>
25   -Alessandro Palmeira + Diego Araújo <diegoamc90@gmail.com>
26   -Alessandro Palmeira + Diego Araujo + Eduardo Morais <alessandro.palmeira@gmail.com>
27   -Alessandro Palmeira + Diego Araújo + João M. M. da Silva <alessandro.palmeira@gmail.com>
28   -Alessandro Palmeira + Diego Araújo + João M. M. da Silva <diegoamc90@gmail.com>
29   -Alessandro Palmeira + Diego Araujo + João M. M. da Silva + Paulo Meirelles <alessandro.palmeira@gmail.com>
30   -Alessandro Palmeira + Diego Araújo + Pedro Leal <diegoamc90@gmail.com>
31   -Alessandro Palmeira + Diego Araújo + Pedro Leal + João M. M. da Silva <diegoamc90@gmail.com>
32   -Alessandro Palmeira + Diego Araujo + Rafael Manzo <alessandro.palmeira@gmail.com>
33   -Alessandro Palmeira + Eduardo Morais <alessandro.palmeira@gmail.com>
34   -Alessandro Palmeira + Guilherme Rojas <alessandro.palmeira@gmail.com>
35   -Alessandro Palmeira + Jefferson Fernandes <alessandro.palmeira@gmail.com>
36   -Alessandro Palmeira + João M. M. da Silva <alessandro.palmeira@gmail.com>
37   -Alessandro Palmeira + Joao M. M. da Silva + Diego Araujo <alessandro.palmeira@gmail.com>
38   -Alessandro Palmeira + João M. M. da Silva + Renan Teruo <alessandro.palmeira@gmail.com>
39   -Alessandro Palmeira + João M. M. Silva <alessandro.palmeira@gmail.com>
40   -Alessandro Palmeira + Paulo Meirelles <alessandro.palmeira@gmail.com>
41   -Alessandro Palmeira + Paulo Meirelles + João M. M. da Silva <alessandro.palmeira@gmail.com>
42   -Alessandro Palmeira + Rafael Manzo <alessandro.palmeira@gmail.com>
43   -Ana Losnak <analosnak@gmail.com>
44   -Antonio Terceiro + Carlos Morais <terceiro@colivre.coop.br>
45   -Antonio Terceiro + Paulo Meirelles <terceiro@colivre.coop.br>
46   -Antonio Terceiro <terceiro@colivre.coop.br>
47   -Arthur Del Esposte <arthurmde@gmail.com>
48   -Arthur Del Esposte <arthurmde@yahoo.com.br>
49   -Aurelio A. Heckert <aurelio@colivre.coop.br>
50   -Braulio Bhavamitra <brauliobo@gmail.com>
51   -Bráulio Bhavamitra <brauliobo@gmail.com>
52   -Braulio Bhavamitra <braulio@eita.org.br>
53   -Caio <caio.csalgado@gmail.com>
54   -Caio + Diego + Pedro + João <caio.csalgado@gmail.com>
55   -Caio Formiga <caio.formiga@gmail.com>
56   -Caio, Pedro <caio.csalgado@gmail.com>
57   -Caio Salgado + Alessandro Palmeira <caio.csalgado@gmail.com>
58   -Caio Salgado <caio.csalgado@gmail.com>
59   -Caio Salgado + Carlos Morais + Diego Araújo + Pedro Leal <diegoamc90@gmail.com>
60   -Caio Salgado + Diego Araujo <caio.csalgado@gmail.com>
61   -Caio Salgado + Diego Araújo <caio.csalgado@gmail.com>
62   -Caio Salgado + Diego Araújo <diegoamc90@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 + Jefferson Fernandes <caio.csalgado@gmail.com>
69   -Caio Salgado + Jefferson Fernandes <jeffs.fernandes@gmail.com>
70   -Caio Salgado + Rafael Manzo <caio.csalgado@gmail.com>
71   -Caio Salgado + Renan Teruo <caio.csalgado@gmail.com>
72   -Caio Salgado + Renan Teruo <caio.salgado@gmail.com>
73   -Caio Salgado + Renan Teruo + Jefferson Fernandes <jeffs.fernandes@gmail.com>
74   -Caio Salgado + Renan Teruo <renanteruoc@gmail.com>
75   -Caio SBA <caio@colivre.coop.br>
76   -Caio Tiago Oliveira <caiotiago@colivre.coop.br>
77   -Carlos Andre de Souza <carlos.andre.souza@msn.com>
78   -Carlos Morais <carlos88morais@gmail.com>
79   -Carlos Morais + Diego Araújo <diegoamc90@gmail.com>
80   -Carlos Morais + Eduardo Morais <carlos88morais@gmail.com>
81   -Carlos Morais + Paulo Meirelles <carlos88morais@gmail.com>
82   -Carlos Morais + Pedro Leal <carlos88morais@gmail.com>
83   -Daniela Feitosa <dani@dohko.(none)>
84   -Daniel Alves + Diego Araújo <danpaulalves@gmail.com>
85   -Daniel Alves + Diego Araújo <diegoamc90@gmail.com>
86   -Daniel Alves + Diego Araújo + Guilherme Rojas <danpaulalves@gmail.com>
87   -Daniel Alves + Diego Araújo + Guilherme Rojas <diegoamc90@gmail.com>
88   -Daniel Alves + Diego Araújo + Guilherme Rojas <guilhermehrojas@gmail.com>
89   -Daniel Alves + Guilherme Rojas <danpaulalves@gmail.com>
90   -Daniel Alves + Rafael Manzo <rr.manzo@gmail.com>
91   -Daniela Soares Feitosa <danielafeitosa@colivre.coop.br>
92   -Daniel Bucher <daniel.bucher88@gmail.com>
93   -Daniel Cunha <daniel@colivre.coop.br>
94   -David Carlos <ddavidcarlos1392@gmail.com>
95   -diegoamc <diegoamc90@gmail.com>
96   -Diego Araújo + Alessandro Palmeira <diegoamc90@gmail.com>
97   -Diego Araújo + Alessandro Palmeira + João M. M. da Silva <diegoamc90@gmail.com>
98   -Diego Araújo + Alessandro Palmeira + Rafael Manzo <rr.manzo@gmail.com>
99   -Diego Araujo + Caio Salgado <diegoamc90@gmail.com>
100   -Diego Araújo + Daniel Alves + Rafael Manzo <rr.manzo@gmail.com>
101   -Diego Araújo <diegoamc90@gmail.com>
102   -Diego Araújo + Eduardo Morais + Paulo Meirelles <diegoamc90@gmail.com>
103   -Diego Araújo + Guilherme Rojas <diegoamc90@gmail.com>
104   -Diego Araújo + Jefferson Fernandes <diegoamc90@gmail.com>
105   -Diego Araujo + Jefferson Fernandes <jeffs.fernandes@gmail.com>
106   -Diego Araújo + João Machini <diegoamc90@gmail.com>
107   -Diego Araújo + João Machini <digoamc90@gmail.com>
108   -Diego Araújo + João M. M. da Silva + Alessandro Palmeira <jaodsilv@linux.ime.usp.br>
109   -Diego Araújo + João M. M. da Silva <diegoamc90@gmail.com>
110   -Diego Araújo + João M. M. da Silva + João Machini <diegoamc90@gmail.com>
111   -Diego Araújo + João M. M. da Silva + Pedro Leal <diegoamc90@gmail.com>
112   -Diego Araújo + Paulo Meirelles <diegoamc90@gmail.com>
113   -Diego Araújo + Pedro Leal <diegoamc90@gmail.com>
114   -Diego Araujo + Rafael Manzo <diegoamc90@gmail.com>
115   -Diego Araújo + Rafael Manzo <diegoamc90@gmail.com>
116   -Diego Araújo + Renan Teruo + Alessandro Palmeira <diegoamc90@gmail.com>
117   -Diego Araújo + Renan Teruo <diegoamc90@gmail.com>
118   -Diego Araujo + Rodrigo Souto + Rafael Manzo <rr.manzo@gmail.com>
119   -Diego + Jefferson <diegoamc90@gmail.com>
120   -Diego Martinez <diegoamc90@gmail.com>
121   -Diego Martinez <diego@diego-K55A.(none)>
122   -Diego + Renan <renanteruoc@gmail.com>
123   -Eduardo Tourinho Edington <eduardo.edington@serpro.gov.br>
124   -Evandro Jr <evandrojr@gmail.com>
125   -Evandro Junior <evandrojr@gmail.com>
126   -Fabio Teixeira <fabio1079@gmail.com>
127   -Fernanda Lopes <nanda.listas+psl@gmail.com>
128   -Francisco Marcelo A. Lima Júnior <francisco.lima-junior@serpro.gov.br>
129   -Francisco Marcelo de Araujo Lima Junior <79350259591@serpro-1457614.(none)>
130   -Francisco Marcelo de Araújo Lima Júnior <francisco.lima-junior@serpro.gov.br>
131   -Francisco Marcelo de Araújo Lima Júnior <maljunior@gmail.com>
132   -Gabriela Navarro <navarro1703@gmail.com>
133   -Grazieno Pellegrino <grazieno@gmail.com>
134   -Gust <darksshades@hotmail.com>
135   -Hugo Melo <hugo@riseup.net>
136   -Isaac Canan <isaac@intelletto.com.br>
137   -Italo Valcy <italo@dcc.ufba.br>
138   -Jefferson Fernandes + Diego Araujo + Rafael Manzo <jeffs.fernandes@gmail.com>
139   -Jefferson Fernandes + Joao M. M. da Silva <jeffs.fernandes@gmail.com>
140   -Jefferson Fernandes + Joao M. M. Silva <jeffs.fernandes@gmail.com>
141   -João da Silva + Eduardo Morais + Rafael Manzo <rr.manzo@gmail.com>
142   -João da Silva <jaodsilv@linux.ime.usp.br>
143   -João Marco Maciel da Silva + Rafael Manzo + Renan Teruo <jaodsilv@linux.ime.usp.br>
144   -João M. M. da Silva + Alessandro Palmeira + Diego Araújo + Caio Salgado <jaodsilv@linux.ime.usp.br>
145   -João M. M. da Silva + Alessandro Palmeira + Diego Araújo <jaodsilv@linux.ime.usp.br>
146   -Joao M. M. da Silva + Alessandro Palmeira <jaodsilv@linux.ime.usp.br>
147   -João M. M. da Silva + Alessandro Palmeira <jaodsilv@linux.ime.usp.br>
148   -João M. M. da Silva + Alessandro Palmeira + João Machini <jaodsilv@linux.ime.usp.br>
149   -João M. M. da Silva + Caio Salgado + Alessandro Palmeira <jaodsilv@linux.ime.usp.br>
150   -João M. M. da Silva + Caio Salgado <jaodsilv@linux.ime.usp.br>
151   -João M. M. da Silva + Carlos Morais <jaodsilv@linux.ime.usp.br>
152   -João M. M. da Silva + Diego Araújo <diegoamc90@gmail.com>
153   -João M. M. da Silva + Diego Araújo <jaodsilv@linux.ime.usp.br>
154   -João M. M. da Silva + Diego Araújo + Pedro Leal <jaodsilv@linux.ime.usp.br>
155   -João M. M. da Silva <jaodsilv@linux.ime.usp.br>
156   -Joao M. M. da Silva + Jefferson Fernandes <jaodsilv@linux.ime.usp.br>
157   -João M. M. da Silva + Jefferson Fernandes <jaodsilv@linux.ime.usp.br>
158   -João M. M. da Silva + João M. Miranda <jaodsilv@linux.ime.usp.br>
159   -João M. M. da Silva + Paulo Meirelles <jaodsilv@linux.ime.usp.br>
160   -João M. M. da Silva + Pedro Leal <jaodsilv@linux.ime.usp.br>
161   -João M. M. da Silva + Rafael Manzo + Diego Araújo <jaodsilv@linux.ime.usp.br>
162   -João M. M. da Silva + Rafael Manzo <jaodsilv@linux.ime.usp.br>
163   -João M. M. da Silva + Renan Teruo <jaodsilv@linux.ime.usp.br>
164   -João M. M. Silva + Caio Salgado <jaodsilv@linux.ime.usp.br>
165   -João M. M. Silva + Diego Araújo <jaodsilv@linux.ime.usp.br>
166   -Joao M. M. Silva + Jefferson Fernandes <jaodsilv@linux.ime.usp.br>
167   -João M. M. Silva + Paulo Meirelles <jaodsilv@linux.ime.usp.br>
168   -João M. M. Silva + Rafael Manzo <jaodsilv@linux.ime.usp.br>
169   -João M. M. Silva + Renan Teruo <jaodsilv@linux.ime.usp.br>
170   -Joenio Costa <joenio@colivre.coop.br>
171   -Josef Spillner <josef.spillner@tu-dresden.de>
172   -Junior Silva <junior@bajor.localhost.localdomain>
173   -Junior Silva <juniorsilva1001@gmail.com>
174   -Junior Silva <juniorsilva7@juniorsilva-Aspire-5750Z.(none)>
175   -Junior Silva <juniorsilva@colivre.coop.br>
176   -juniorsilva <juniorsilva@QonoS.localhost.localdomain>
177   -Keilla Menezes <keilla@colivre.coop.br>
178   -Larissa Reis <larissa@colivre.coop.br>
179   -Larissa Reis <reiss.larissa@gmail.com>
180   -Leandro Nunes dos Santos <81665687568@serpro-1541727.Home>
181   -Leandro Nunes dos Santos <81665687568@serpro-1541727.(none)>
182   -Leandro Nunes dos Santos <leandronunes@gmail.com>
183   -Leandro Nunes dos Santos <leandro.santos@serpro.gov.br>
184   -LinguÁgil 2010 <linguagil.bahia@gmail.com>
185   -Lucas Melo <lucas@colivre.coop.br>
186   -Lucas Melo <lucaspradomelo@gmail.com>
187   -Luciano <lucianopcbr@gmail.com>
188   -Luis David Aguilar Carlos <ludwig9003@gmail.com>
189   -Luiz Fernando de Freitas Matos <luiz@luizff.matos@gmail.com>
190   -Marcos Ramos <ms.ramos@outlook.com>
191   -Martín Olivera <molivera@solar.org.ar>
192   -Moises Machado <moises@colivre.coop.br>
193   -Naíla Alves <naila@colivre.coop.br>
194   -Nanda Lopes <nanda.listas+psl@gmail.com>
195   -Paulo Meirelles + Alessandro Palmeira + João M. M. da Silva <paulo@softwarelivre.org>
196   -Paulo Meirelles + Alessandro Palmeira <paulo@softwarelivre.org>
197   -Paulo Meirelles + Carlos Morais <paulo@softwarelivre.org>
198   -Paulo Meirelles + Diego Araújo <paulo@softwarelivre.org>
199   -Paulo Meirelles + João M. M. da Silva <paulo@softwarelivre.org>
200   -Paulo Meirelles <paulo@softwarelivre.org>
201   -Paulo Meirelles + Rafael Manzo <paulo@softwarelivre.org>
202   -Rafael Gomes <rafaelgomes@techfree.com.br>
203   -Rafael Manzo + Alessandro Palmeira <rr.manzo@gmail.com>
204   -Rafael Manzo + Daniel Alves <danpaulalves@gmail.com>
205   -Rafael Manzo + Diego Araújo <rr.manzo@gmail.com>
206   -Rafael Manzo + João M. M. Silva <rr.manzo@gmail.com>
207   -Rafael Manzo + Paulo Meirelles <rr.manzo@gmail.com>
208   -Rafael Martins <rmmartins@gmail.com>
209   -Rafael Reggiani Manzo + Caio Salgado + Jefferson Fernandes <rr.manzo@gmail.com>
210   -Rafael Reggiani Manzo + Diego Araujo <diegoamc90@gmail.com>
211   -Rafael Reggiani Manzo + Diego Araujo <rr.manzo@gmail.com>
212   -Rafael Reggiani Manzo + Diego Araújo <rr.manzo@gmail.com>
213   -Rafael Reggiani Manzo + João M. M. da Silva <rr.manzo@gmail.com>
214   -Rafael Reggiani Manzo <rr.manzo@gmail.com>
215   -Raphaël Rousseau <raph@r4f.org>
216   -Raquel Lira <raquel.lira@gmail.com>
217   -Renan Teruo + Caio Salgado <renanteruoc@gmail.com>
218   -Renan Teruoc + Diego Araujo <renanteruoc@gmail.com>
219   -Renan Teruo + Diego Araujo <renanteruoc@gmail.com>
220   -Renan Teruo + Diego Araújo <renanteruoc@gmail.com>
221   -Renan Teruo + Paulo Meirelles <renanteruoc@gmail.com>
222   -Renan Teruo + Rafael Manzo <renanteruoc@gmail.com>
223   -Rodrigo Souto + Ana Losnak + Daniel Bucher + Caio Almeida + Leandro Nunes + Daniela Feitosa + Mariel Zasso <noosfero-br@listas.softwarelivre.org>
224   -Rodrigo Souto <diguliu@gmail.com>
225   -Rodrigo Souto <rodrigo@colivre.coop.br>
226   -Ronny Kursawe <kursawe.ronny@googlemail.com>
227   -root <root@debian.sdr.serpro>
228   -Samuel R. C. Vale <srcvale@holoscopio.com>
229   -Valessio Brito <contato@valessiobrito.com.br>
230   -Valessio Brito <contato@valessiobrito.info>
231   -Valessio Brito <valessio@gmail.com>
232   -vfcosta <vfcosta@gmail.com>
233   -Victor Carvalho <victorhugodf.ac@gmail.com>
234   -Victor Costa <vfcosta@gmail.com>
235   -Victor Hugo Alves de Carvalho <victorhugodf.ac@gmail.com>
236   -Vinicius Cubas Brand <viniciuscb@gmail.com>
237   -Visita <visita@debian.(none)>
238   -Yann Lugrin <yann.lugrin@liquid-concept.ch>
239   -
240   -Ideas, specifications and incentive
241   -===================================
242   -Daniel Tygel <dtygel@fbes.org.br>
243   -Guilherme Rocha <guilherme@gf7.com.br>
244   -Raphael Rousseau <raph@r4f.org>
245   -Théo Bondolfi <move@cooperation.net>
246   -Vicente Aguiar <vicenteaguiar@colivre.coop.br>
247   -
248   -Arts
249   -===================================
250   -Nara Oliveira <narananet@gmail.com>
AUTHORS.md
1   -If you are not listed here, but should be, please write to the noosfero mailing list: http://listas.softwarelivre.org/cgi-bin/mailman/listinfo/noosfero-dev (this list requires subscription to post, but since you are an author of noosfero, that's not a problem).
  1 +If you are not listed here, but should be, please write to the noosfero mailing
  2 +list: http://listas.softwarelivre.org/cgi-bin/mailman/listinfo/noosfero-dev
  3 +(this list requires subscription to post, but since you are an author of
  4 +noosfero, that's not a problem).
2 5  
3 6 Developers
4 7 ==========
5 8  
  9 +Ábner Silva de Oliveira <abner.oliveira@serpro.gov.br>
6 10 Alan Freihof Tygel <alantygel@gmail.com>
  11 +alcampelo <alcampelo@alcampelo.(none)>
7 12 Alessandro Palmeira <alessandro.palmeira@gmail.com>
8 13 Alessandro Palmeira + Caio C. Salgado <alessandro.palmeira@gmail.com>
9 14 Alessandro Palmeira + Caio Salgado <alessandro.palmeira@gmail.com>
... ... @@ -35,9 +40,12 @@ Alessandro Palmeira + João M. M. Silva &lt;alessandro.palmeira@gmail.com&gt;
35 40 Alessandro Palmeira + Paulo Meirelles <alessandro.palmeira@gmail.com>
36 41 Alessandro Palmeira + Paulo Meirelles + João M. M. da Silva <alessandro.palmeira@gmail.com>
37 42 Alessandro Palmeira + Rafael Manzo <alessandro.palmeira@gmail.com>
  43 +Ana Losnak <analosnak@gmail.com>
38 44 Antonio Terceiro + Carlos Morais <terceiro@colivre.coop.br>
39 45 Antonio Terceiro + Paulo Meirelles <terceiro@colivre.coop.br>
40 46 Antonio Terceiro <terceiro@colivre.coop.br>
  47 +Arthur Del Esposte <arthurmde@gmail.com>
  48 +Arthur Del Esposte <arthurmde@yahoo.com.br>
41 49 Aurelio A. Heckert <aurelio@colivre.coop.br>
42 50 Braulio Bhavamitra <brauliobo@gmail.com>
43 51 Bráulio Bhavamitra <brauliobo@gmail.com>
... ... @@ -65,11 +73,14 @@ Caio Salgado + Renan Teruo &lt;caio.salgado@gmail.com&gt;
65 73 Caio Salgado + Renan Teruo + Jefferson Fernandes <jeffs.fernandes@gmail.com>
66 74 Caio Salgado + Renan Teruo <renanteruoc@gmail.com>
67 75 Caio SBA <caio@colivre.coop.br>
  76 +Caio Tiago Oliveira <caiotiago@colivre.coop.br>
  77 +Carlos Andre de Souza <carlos.andre.souza@msn.com>
68 78 Carlos Morais <carlos88morais@gmail.com>
69 79 Carlos Morais + Diego Araújo <diegoamc90@gmail.com>
70 80 Carlos Morais + Eduardo Morais <carlos88morais@gmail.com>
71 81 Carlos Morais + Paulo Meirelles <carlos88morais@gmail.com>
72 82 Carlos Morais + Pedro Leal <carlos88morais@gmail.com>
  83 +Daniela Feitosa <dani@dohko.(none)>
73 84 Daniel Alves + Diego Araújo <danpaulalves@gmail.com>
74 85 Daniel Alves + Diego Araújo <diegoamc90@gmail.com>
75 86 Daniel Alves + Diego Araújo + Guilherme Rojas <danpaulalves@gmail.com>
... ... @@ -78,7 +89,9 @@ Daniel Alves + Diego Araújo + Guilherme Rojas &lt;guilhermehrojas@gmail.com&gt;
78 89 Daniel Alves + Guilherme Rojas <danpaulalves@gmail.com>
79 90 Daniel Alves + Rafael Manzo <rr.manzo@gmail.com>
80 91 Daniela Soares Feitosa <danielafeitosa@colivre.coop.br>
  92 +Daniel Bucher <daniel.bucher88@gmail.com>
81 93 Daniel Cunha <daniel@colivre.coop.br>
  94 +David Carlos <ddavidcarlos1392@gmail.com>
82 95 diegoamc <diegoamc90@gmail.com>
83 96 Diego Araújo + Alessandro Palmeira <diegoamc90@gmail.com>
84 97 Diego Araújo + Alessandro Palmeira + João M. M. da Silva <diegoamc90@gmail.com>
... ... @@ -107,15 +120,25 @@ Diego + Jefferson &lt;diegoamc90@gmail.com&gt;
107 120 Diego Martinez <diegoamc90@gmail.com>
108 121 Diego Martinez <diego@diego-K55A.(none)>
109 122 Diego + Renan <renanteruoc@gmail.com>
  123 +Eduardo Tourinho Edington <eduardo.edington@serpro.gov.br>
  124 +Evandro Jr <evandrojr@gmail.com>
  125 +Evandro Junior <evandrojr@gmail.com>
  126 +Fabio Teixeira <fabio1079@gmail.com>
110 127 Fernanda Lopes <nanda.listas+psl@gmail.com>
111 128 Francisco Marcelo A. Lima Júnior <francisco.lima-junior@serpro.gov.br>
112 129 Francisco Marcelo de Araujo Lima Junior <79350259591@serpro-1457614.(none)>
  130 +Francisco Marcelo de Araújo Lima Júnior <francisco.lima-junior@serpro.gov.br>
  131 +Francisco Marcelo de Araújo Lima Júnior <maljunior@gmail.com>
  132 +Gabriela Navarro <navarro1703@gmail.com>
113 133 Grazieno Pellegrino <grazieno@gmail.com>
  134 +Gust <darksshades@hotmail.com>
  135 +Hugo Melo <hugo@riseup.net>
114 136 Isaac Canan <isaac@intelletto.com.br>
115 137 Italo Valcy <italo@dcc.ufba.br>
116 138 Jefferson Fernandes + Diego Araujo + Rafael Manzo <jeffs.fernandes@gmail.com>
117 139 Jefferson Fernandes + Joao M. M. da Silva <jeffs.fernandes@gmail.com>
118 140 Jefferson Fernandes + Joao M. M. Silva <jeffs.fernandes@gmail.com>
  141 +João da Silva + Eduardo Morais + Rafael Manzo <rr.manzo@gmail.com>
119 142 João da Silva <jaodsilv@linux.ime.usp.br>
120 143 João Marco Maciel da Silva + Rafael Manzo + Renan Teruo <jaodsilv@linux.ime.usp.br>
121 144 João M. M. da Silva + Alessandro Palmeira + Diego Araújo + Caio Salgado <jaodsilv@linux.ime.usp.br>
... ... @@ -146,17 +169,29 @@ João M. M. Silva + Rafael Manzo &lt;jaodsilv@linux.ime.usp.br&gt;
146 169 João M. M. Silva + Renan Teruo <jaodsilv@linux.ime.usp.br>
147 170 Joenio Costa <joenio@colivre.coop.br>
148 171 Josef Spillner <josef.spillner@tu-dresden.de>
  172 +Jose Pedro <1jpsneto@gmail.com>
  173 +Junior Silva <junior@bajor.localhost.localdomain>
  174 +Junior Silva <junior@sedeantigo.colivre.coop.br>
149 175 Junior Silva <juniorsilva1001@gmail.com>
150 176 Junior Silva <juniorsilva7@juniorsilva-Aspire-5750Z.(none)>
  177 +Junior Silva <juniorsilva@colivre.coop.br>
  178 +juniorsilva <juniorsilva@QonoS.localhost.localdomain>
151 179 Keilla Menezes <keilla@colivre.coop.br>
152 180 Larissa Reis <larissa@colivre.coop.br>
153 181 Larissa Reis <reiss.larissa@gmail.com>
  182 +Leandro Alves <leandrosustenido@gmail.com>
  183 +Leandro Nunes dos Santos <81665687568@serpro-1541727.Home>
  184 +Leandro Nunes dos Santos <81665687568@serpro-1541727.(none)>
154 185 Leandro Nunes dos Santos <leandronunes@gmail.com>
155 186 Leandro Nunes dos Santos <leandro.santos@serpro.gov.br>
156 187 LinguÁgil 2010 <linguagil.bahia@gmail.com>
157 188 Lucas Melo <lucas@colivre.coop.br>
158 189 Lucas Melo <lucaspradomelo@gmail.com>
  190 +Luciano <lucianopcbr@gmail.com>
  191 +Luciano Prestes Cavalcanti <lucianopcbr@gmail.com>
159 192 Luis David Aguilar Carlos <ludwig9003@gmail.com>
  193 +Luiz Fernando de Freitas Matos <luiz@luizff.matos@gmail.com>
  194 +Marcos Ramos <ms.ramos@outlook.com>
160 195 Martín Olivera <molivera@solar.org.ar>
161 196 Moises Machado <moises@colivre.coop.br>
162 197 Naíla Alves <naila@colivre.coop.br>
... ... @@ -189,14 +224,19 @@ Renan Teruo + Diego Araujo &lt;renanteruoc@gmail.com&gt;
189 224 Renan Teruo + Diego Araújo <renanteruoc@gmail.com>
190 225 Renan Teruo + Paulo Meirelles <renanteruoc@gmail.com>
191 226 Renan Teruo + Rafael Manzo <renanteruoc@gmail.com>
  227 +Rodrigo Souto + Ana Losnak + Daniel Bucher + Caio Almeida + Leandro Nunes + Daniela Feitosa + Mariel Zasso <noosfero-br@listas.softwarelivre.org>
192 228 Rodrigo Souto <diguliu@gmail.com>
193 229 Rodrigo Souto <rodrigo@colivre.coop.br>
194 230 Ronny Kursawe <kursawe.ronny@googlemail.com>
195 231 root <root@debian.sdr.serpro>
196 232 Samuel R. C. Vale <srcvale@holoscopio.com>
  233 +Valessio Brito <contato@valessiobrito.com.br>
  234 +Valessio Brito <contato@valessiobrito.info>
197 235 Valessio Brito <valessio@gmail.com>
198 236 vfcosta <vfcosta@gmail.com>
  237 +Victor Carvalho <victorhugodf.ac@gmail.com>
199 238 Victor Costa <vfcosta@gmail.com>
  239 +Victor Hugo Alves de Carvalho <victorhugodf.ac@gmail.com>
200 240 Vinicius Cubas Brand <viniciuscb@gmail.com>
201 241 Visita <visita@debian.(none)>
202 242 Yann Lugrin <yann.lugrin@liquid-concept.ch>
... ...
Gemfile
... ... @@ -16,6 +16,8 @@ gem &#39;hpricot&#39;
16 16 gem 'nokogiri'
17 17 gem 'rake', :require => false
18 18 gem 'rest-client'
  19 +gem 'exception_notification'
  20 +gem 'gettext_rails'
19 21  
20 22 # FIXME list here all actual dependencies (i.e. the ones in debian/control),
21 23 # with their GEM names (not the Debian package names)
... ... @@ -31,7 +33,6 @@ group :test do
31 33 end
32 34  
33 35 group :cucumber do
34   - gem 'rake'
35 36 gem 'cucumber-rails', :require => false
36 37 gem 'capybara'
37 38 gem 'cucumber'
... ...
Gemfile.lock
... ... @@ -61,9 +61,21 @@ GEM
61 61 database_cleaner (1.2.0)
62 62 diff-lcs (1.1.3)
63 63 erubis (2.7.0)
64   - eventmachine (0.12.11)
  64 + eventmachine (0.12.10)
  65 + exception_notification (4.0.1)
  66 + actionmailer (>= 3.0.4)
  67 + activesupport (>= 3.0.4)
65 68 fast_gettext (0.6.8)
66 69 ffi (1.0.11)
  70 + gettext (2.2.1)
  71 + locale
  72 + gettext_activerecord (2.1.0)
  73 + activerecord (>= 2.3.2)
  74 + gettext (>= 2.1.0)
  75 + gettext_rails (2.1.0)
  76 + gettext_activerecord (>= 2.1.0)
  77 + locale_rails (>= 2.0.5)
  78 + rails (>= 2.3.2)
67 79 gherkin (2.4.21)
68 80 json (>= 1.4.6)
69 81 hike (1.2.1)
... ... @@ -71,6 +83,9 @@ GEM
71 83 i18n (0.6.0)
72 84 journey (1.0.3)
73 85 json (1.7.3)
  86 + locale (2.0.5)
  87 + locale_rails (2.0.5)
  88 + locale (>= 2.0.5)
74 89 mail (2.4.4)
75 90 i18n (>= 0.4.0)
76 91 mime-types (~> 1.16)
... ... @@ -167,7 +182,9 @@ DEPENDENCIES
167 182 daemons
168 183 dalli
169 184 database_cleaner
  185 + exception_notification
170 186 fast_gettext
  187 + gettext_rails
171 188 hpricot
172 189 mocha
173 190 nokogiri
... ...
Rakefile
1 1 #!/usr/bin/env rake
  2 +
2 3 # Add your own tasks in files placed in lib/tasks ending in .rake,
3 4 # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
4 5  
... ...
app/controllers/admin/categories_controller.rb
... ... @@ -45,9 +45,11 @@ class CategoriesController &lt; AdminController
45 45 if request.post?
46 46 @category.update_attributes!(params[:category])
47 47 @saved = true
  48 + session[:notice] = _("Category %s saved." % @category.name)
48 49 redirect_to :action => 'index'
49 50 end
50 51 rescue Exception => e
  52 + session[:notice] = _('Could not save category.')
51 53 render :action => 'edit'
52 54 end
53 55 end
... ...
app/controllers/admin/features_controller.rb
... ... @@ -51,4 +51,10 @@ class FeaturesController &lt; AdminController
51 51 redirect_to :action => 'manage_fields'
52 52 end
53 53  
  54 + def search_members
  55 + arg = params[:q].downcase
  56 + result = environment.people.find(:all, :conditions => ['LOWER(name) LIKE ? OR identifier LIKE ?', "%#{arg}%", "%#{arg}%"])
  57 + render :text => prepare_to_token_input(result).to_json
  58 + end
  59 +
54 60 end
... ...
app/controllers/application_controller.rb
... ... @@ -7,6 +7,12 @@ class ApplicationController &lt; 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 + before_filter :login_required, :if => :private_environment?
  11 + before_filter :verify_members_whitelist, :if => :user
  12 +
  13 + def verify_members_whitelist
  14 + render_access_denied unless user.is_admin? || environment.in_whitelist?(user)
  15 + end
10 16  
11 17 after_filter :set_csrf_cookie
12 18  
... ... @@ -187,4 +193,8 @@ class ApplicationController &lt; ActionController::Base
187 193 {:results => scope.paginate(paginate_options)}
188 194 end
189 195  
  196 + def private_environment?
  197 + @environment.enabled?(:restrict_to_members)
  198 + end
  199 +
190 200 end
... ...
app/controllers/my_profile/cms_controller.rb
... ... @@ -149,6 +149,7 @@ class CmsController &lt; MyProfileController
149 149 end
150 150  
151 151 @article.profile = profile
  152 + @article.author = user
152 153 @article.last_changed_by = user
153 154 @article.created_by = user
154 155  
... ... @@ -201,7 +202,7 @@ class CmsController &lt; MyProfileController
201 202 :profile => profile,
202 203 :parent => @parent,
203 204 :last_changed_by => user,
204   - :created_by => user,
  205 + :author => user,
205 206 },
206 207 :without_protection => true
207 208 )
... ...
app/controllers/my_profile/memberships_controller.rb
... ... @@ -21,6 +21,9 @@ class MembershipsController &lt; MyProfileController
21 21 @back_to = params[:back_to] || url_for(:action => 'index')
22 22 if request.post? && @community.valid?
23 23 @community = Community.create_after_moderation(user, params[:community].merge({:environment => environment}))
  24 + if @community.new_record?
  25 + session[:notice] = _('Your new community creation request will be evaluated by an administrator. You will be notified.')
  26 + end
24 27 redirect_to @back_to
25 28 return
26 29 end
... ...
app/controllers/my_profile/tasks_controller.rb
... ... @@ -4,6 +4,7 @@ class TasksController &lt; MyProfileController
4 4  
5 5 def index
6 6 @filter = params[:filter_type].blank? ? nil : params[:filter_type]
  7 + @task_types = Task.pending_types_for(profile)
7 8 @tasks = Task.to(profile).without_spam.pending.of(@filter).order_by('created_at', 'asc').paginate(:per_page => Task.per_page, :page => params[:page])
8 9 @failed = params ? params[:failed] : {}
9 10 end
... ...
app/controllers/public/account_controller.rb
... ... @@ -2,7 +2,7 @@ class AccountController &lt; ApplicationController
2 2  
3 3 no_design_blocks
4 4  
5   - before_filter :login_required, :only => [:activation_question, :accept_terms, :activate_enterprise]
  5 + before_filter :login_required, :only => [:activation_question, :accept_terms, :activate_enterprise, :change_password]
6 6 before_filter :redirect_if_logged_in, :only => [:login, :signup]
7 7 before_filter :protect_from_bots, :only => :signup
8 8  
... ... @@ -15,11 +15,23 @@ class AccountController &lt; ApplicationController
15 15  
16 16 def activate
17 17 @user = User.find_by_activation_code(params[:activation_code]) if params[:activation_code]
18   - if @user and @user.activate
19   - @message = _("Your account has been activated, now you can log in!")
20   - check_redirection
21   - session[:join] = params[:join] unless params[:join].blank?
22   - render :action => 'login', :userlogin => @user.login
  18 + if @user
  19 + unless @user.environment.enabled?('admin_must_approve_new_users')
  20 + if @user.activate
  21 + @message = _("Your account has been activated, now you can log in!")
  22 + check_redirection
  23 + session[:join] = params[:join] unless params[:join].blank?
  24 + render :action => 'login', :userlogin => @user.login
  25 + end
  26 + else
  27 + if @user.create_moderate_task
  28 + session[:notice] = _('Thanks for registering. The administrators were notified.')
  29 + @register_pending = true
  30 + @user.activation_code = nil
  31 + @user.save!
  32 + redirect_to :controller => :home
  33 + end
  34 + end
23 35 else
24 36 session[:notice] = _("It looks like you're trying to activate an account. Perhaps have already activated this account?")
25 37 redirect_to :controller => :home
... ... @@ -108,6 +120,7 @@ class AccountController &lt; ApplicationController
108 120 check_join_in_community(@user)
109 121 go_to_signup_initial_page
110 122 else
  123 + session[:notice] = _('Thanks for registering!')
111 124 @register_pending = true
112 125 end
113 126 end
... ...
app/controllers/public/catalog_controller.rb
... ... @@ -11,7 +11,7 @@ class CatalogController &lt; PublicController
11 11 protected
12 12  
13 13 def check_enterprise_and_environment
14   - unless profile.kind_of?(Enterprise) && @profile.environment.enabled?('products_for_enterprises')
  14 + unless profile.enterprise? && @profile.environment.enabled?('products_for_enterprises')
15 15 redirect_to :controller => 'profile', :profile => profile.identifier, :action => 'index'
16 16 end
17 17 end
... ...
app/controllers/public/content_viewer_controller.rb
... ... @@ -74,7 +74,7 @@ class ContentViewerController &lt; ApplicationController
74 74 end
75 75  
76 76 def versions_diff
77   - path = params[:page].join('/')
  77 + path = params[:page]
78 78 @page = profile.articles.find_by_path(path)
79 79 @v1, @v2 = @page.versions.find_by_version(params[:v1]), @page.versions.find_by_version(params[:v2])
80 80 end
... ... @@ -216,6 +216,8 @@ class ContentViewerController &lt; ApplicationController
216 216 if @page.has_posts?
217 217 posts = get_posts(params[:year], params[:month])
218 218  
  219 + posts = posts.includes(:parent, {:profile => [:domains, :environment]}, :author)
  220 +
219 221 #FIXME Need to run this before the pagination because this version of
220 222 # will_paginate returns a will_paginate collection instead of a
221 223 # relation.
... ...
app/helpers/application_helper.rb
... ... @@ -312,13 +312,13 @@ module ApplicationHelper
312 312 raise ArgumentError, 'No partial for object. Is there a partial for any class in the inheritance hierarchy?'
313 313 end
314 314  
315   - def view_for_profile_actions(klass)
316   - raise ArgumentError, 'No profile actions view for this class.' if klass.nil?
317   -
318   - name = klass.name.underscore
319   - return "blocks/profile_info_actions/" + name + '.html.erb' if File.exists?(Rails.root.join('app', 'views', 'blocks', 'profile_info_actions', name + '.html.erb'))
320   -
321   - view_for_profile_actions(klass.superclass)
  315 + def render_profile_actions klass
  316 + name = klass.to_s.underscore
  317 + begin
  318 + render "blocks/profile_info_actions/#{name}"
  319 + rescue ActionView::MissingTemplate
  320 + render_profile_actions klass.superclass
  321 + end
322 322 end
323 323  
324 324 def user
... ... @@ -1095,7 +1095,7 @@ module ApplicationHelper
1095 1095 result
1096 1096 end
1097 1097  
1098   - def manage_link(list, kind)
  1098 + def manage_link(list, kind, title)
1099 1099 if list.present?
1100 1100 link_to_all = nil
1101 1101 if list.count > 5
... ... @@ -1108,19 +1108,19 @@ module ApplicationHelper
1108 1108 if link_to_all
1109 1109 link << link_to_all
1110 1110 end
1111   - render :partial => "shared/manage_link", :locals => {:link => link, :kind => kind.to_s}
  1111 + render :partial => "shared/manage_link", :locals => {:link => link, :kind => kind.to_s, :title => title}
1112 1112 end
1113 1113 end
1114 1114  
1115 1115 def manage_enterprises
1116 1116 return '' unless user && user.environment.enabled?(:display_my_enterprises_on_user_menu)
1117   - manage_link(user.enterprises, :enterprises).to_s
  1117 + manage_link(user.enterprises, :enterprises, _('My enterprises')).to_s
1118 1118 end
1119 1119  
1120 1120 def manage_communities
1121 1121 return '' unless user && user.environment.enabled?(:display_my_communities_on_user_menu)
1122 1122 administered_communities = user.communities.more_popular.select {|c| c.admins.include? user}
1123   - manage_link(administered_communities, :communities).to_s
  1123 + manage_link(administered_communities, :communities, _('My communities')).to_s
1124 1124 end
1125 1125  
1126 1126 def admin_link
... ... @@ -1225,20 +1225,7 @@ module ApplicationHelper
1225 1225 def add_zoom_to_images
1226 1226 stylesheet_link_tag('jquery.fancybox') +
1227 1227 javascript_include_tag('jquery.fancybox.pack') +
1228   - javascript_tag("jQuery(function($) {
1229   - $(window).load( function() {
1230   - $('#article .article-body img').each( function(index) {
1231   - var original = original_image_dimensions($(this).attr('src'));
1232   - if ($(this).width() < original['width'] || $(this).height() < original['height']) {
1233   - $(this).wrap('<div class=\"zoomable-image\" />');
1234   - $(this).parent('.zoomable-image').attr('style', $(this).attr('style'));
1235   - $(this).attr('style', '');
1236   - $(this).after(\'<a href=\"' + $(this).attr('src') + '\" class=\"zoomify-image\"><span class=\"zoomify-text\">%s</span></a>');
1237   - }
1238   - });
1239   - $('.zoomify-image').fancybox();
1240   - });
1241   - });" % _('Zoom in'))
  1228 + javascript_tag("apply_zoom_to_images(#{_('Zoom in').to_json})")
1242 1229 end
1243 1230  
1244 1231 def render_dialog_error_messages(instance_name)
... ... @@ -1373,7 +1360,7 @@ module ApplicationHelper
1373 1360 @message = _("The content here is available to %s's friends only.") % profile.short_name
1374 1361 else
1375 1362 @action = :join
1376   - @message = _('The contents in this community is available to members only.')
  1363 + @message = _('The contents in this profile is available to members only.')
1377 1364 end
1378 1365 @no_design_blocks = true
1379 1366 end
... ... @@ -1415,4 +1402,14 @@ module ApplicationHelper
1415 1402 content_tag('ul', article.versions.map {|v| link_to("r#{v.version}", @page.url.merge(:version => v.version))})
1416 1403 end
1417 1404  
  1405 + def labelled_colorpicker_field(human_name, object_name, method, options = {})
  1406 + options[:id] ||= 'text-field-' + FormsHelper.next_id_number
  1407 + content_tag('label', human_name, :for => options[:id], :class => 'formlabel') +
  1408 + colorpicker_field(object_name, method, options.merge(:class => 'colorpicker_field'))
  1409 + end
  1410 +
  1411 + def colorpicker_field(object_name, method, options = {})
  1412 + text_field(object_name, method, options.merge(:class => 'colorpicker_field'))
  1413 + end
  1414 +
1418 1415 end
... ...
app/helpers/block_helper.rb
... ... @@ -6,19 +6,20 @@ module BlockHelper
6 6 content_tag 'h3', content_tag('span', h(title)), :class => tag_class
7 7 end
8 8  
9   - def highlights_block_config_image_fields(block, image={})
  9 + def highlights_block_config_image_fields(block, image={}, row_number=nil)
10 10 "
11   - <tr class=\"image-data-line\">
  11 + <tr class=\"image-data-line\" data-row-number='#{row_number}'>
12 12 <td>
13 13 #{select_tag 'block[images][][image_id]', content_tag(:option) + option_groups_from_collection_for_select(block.folder_choices, :images, :name, :id, :name, image[:image_id].to_i).html_safe}
14 14 </td>
15 15 <td>#{text_field_tag 'block[images][][address]', image[:address], :class => 'highlight-address', :size => 20}</td>
16 16 <td>#{text_field_tag 'block[images][][position]', image[:position], :class => 'highlight-position', :size => 1}</td>
17   - </tr><tr class=\"image-title\">
  17 + </tr><tr class=\"image-title\" data-row-number='#{row_number}'>
18 18 <td colspan=\"3\"><label>#{
19 19 content_tag('span', _('Title')) +
20 20 text_field_tag('block[images][][title]', image[:title], :class => 'highlight-title', :size => 45)
21 21 }</label></td>
  22 + <td>#{link_to '', '#', :class=>'button icon-button icon-delete delete-highlight', :confirm=>_('Are you sure you want to remove this highlight')}</td>
22 23 </tr>
23 24 "
24 25 end
... ...
app/helpers/blog_helper.rb
... ... @@ -17,13 +17,13 @@ module BlogHelper
17 17 _('Configure blog')
18 18 end
19 19  
20   - def list_posts(articles, format = 'full')
  20 + def list_posts(articles, format = 'full', paginate = true)
21 21 pagination = will_paginate(articles, {
22 22 :param_name => 'npage',
23 23 :previous_label => _('&laquo; Newer posts'),
24 24 :next_label => _('Older posts &raquo;'),
25 25 :params => {:action=>"view_page", :page=>articles.first.parent.path.split('/'), :controller=>"content_viewer"}
26   - }) if articles.present?
  26 + }) if articles.present? && paginate
27 27 content = []
28 28 artic_len = articles.length
29 29 articles.each_with_index{ |art,i|
... ... @@ -45,9 +45,9 @@ module BlogHelper
45 45  
46 46 def display_post(article, format = 'full')
47 47 no_comments = (format == 'full') ? false : true
  48 + title = article_title(article, :no_comments => no_comments)
48 49 html = send("display_#{format}_format", FilePresenter.for(article)).html_safe
49   -
50   - article_title(article, :no_comments => no_comments) + html
  50 + title + html
51 51 end
52 52  
53 53 def display_full_format(article)
... ...
app/helpers/categories_helper.rb
1 1 module CategoriesHelper
2 2  
3   -
4   - COLORS = [
5   - [ N_('Do not display at the menu'), nil ],
6   - [ N_('Orange'), 1],
7   - [ N_('Green'), 2],
8   - [ N_('Purple'), 3],
9   - [ N_('Red'), 4],
10   - [ N_('Dark Green'), 5],
11   - [ N_('Blue Oil'), 6],
12   - [ N_('Blue'), 7],
13   - [ N_('Brown'), 8],
14   - [ N_('Light Green'), 9],
15   - [ N_('Light Blue'), 10],
16   - [ N_('Dark Blue'), 11],
17   - [ N_('Blue Pool'), 12],
18   - [ N_('Beige'), 13],
19   - [ N_('Yellow'), 14],
20   - [ N_('Light Brown'), 15]
21   - ]
22   -
23 3 TYPES = [
24 4 [ _('General Category'), Category.to_s ],
25 5 [ _('Product Category'), ProductCategory.to_s ],
26 6 [ _('Region'), Region.to_s ],
27 7 ]
28 8  
29   - def select_color_for_category
30   - if @category.top_level?
31   - labelled_form_field(_('Display at the menu?'), select('category', 'display_color', CategoriesHelper::COLORS.map {|item| [gettext(item[0]), item[1]] }))
32   - else
33   - ""
34   - end
35   - end
36   -
37   - def display_color_for_category(category)
38   - color = category.display_color
39   - if color.nil?
40   - ""
41   - else
42   - "[" + gettext(CategoriesHelper::COLORS.find {|item| item[1] == color}.first) + "]"
43   - end
44   - end
45   -
46 9 def select_category_type(field)
47 10 value = params[field]
48 11 labelled_form_field(_('Type of category'), select_tag('type', options_for_select(TYPES, value)))
49 12 end
50 13  
  14 + def category_color_style(category)
  15 + return '' if category.nil? or category.display_color.blank?
  16 + 'background-color: #'+category.display_color+';'
  17 + end
  18 +
51 19 #FIXME make this test
52 20 def selected_category_link(cat)
53 21 js_remove = "jQuery('#selected-category-#{cat.id}').remove();"
... ...
app/helpers/content_viewer_helper.rb
... ... @@ -10,7 +10,7 @@ module ContentViewerHelper
10 10 end
11 11  
12 12 def number_of_comments(article)
13   - display_number_of_comments(article.comments.without_spam.count)
  13 + display_number_of_comments(article.comments_count - article.spam_comments_count)
14 14 end
15 15  
16 16 def article_title(article, args = {})
... ... @@ -26,7 +26,7 @@ module ContentViewerHelper
26 26 end
27 27 title << content_tag('span',
28 28 content_tag('span', show_date(article.published_at), :class => 'date') +
29   - content_tag('span', _(", by %s") % link_to(article.author_name, article.author_url), :class => 'author') +
  29 + content_tag('span', _(", by %s") % (article.author ? link_to(article.author_name, article.author_url) : article.author_name), :class => 'author') +
30 30 content_tag('span', comments, :class => 'comments'),
31 31 :class => 'created-at'
32 32 )
... ...
app/helpers/folder_helper.rb
... ... @@ -5,15 +5,17 @@ module FolderHelper
5 5 include ShortFilename
6 6 include ArticleHelper
7 7  
8   - def list_articles(articles, recursive = false)
9   - if !articles.blank?
10   - articles = articles.paginate(
  8 + def list_contents(configure={})
  9 + configure[:recursive] ||= false
  10 + configure[:list_type] ||= :folder
  11 + if !configure[:contents].blank?
  12 + configure[:contents] = configure[:contents].paginate(
11 13 :order => "updated_at DESC",
12 14 :per_page => 10,
13 15 :page => params[:npage]
14 16 )
15 17  
16   - render :file => 'shared/articles_list', :locals => {:articles => articles, :recursive => recursive}
  18 + render :file => 'shared/content_list', :locals => configure
17 19 else
18 20 content_tag('em', _('(empty folder)'))
19 21 end
... ... @@ -23,21 +25,33 @@ module FolderHelper
23 25 articles.select {|article| article.display_to?(user)}
24 26 end
25 27  
26   - def display_article_in_listing(article, recursive = false, level = 0)
27   - article = FilePresenter.for article
28   - article_link = if article.image?
29   - link_to('&nbsp;' * (level * 4) + image_tag(icon_for_article(article)) + short_filename(article.name), article.url.merge(:view => true))
  28 + def display_content_in_listing(configure={})
  29 + recursive = configure[:recursive] || false
  30 + list_type = configure[:list_type] || :folder
  31 + level = configure[:level] || 0
  32 + content = FilePresenter.for configure[:content]
  33 + content_link = if content.image?
  34 + link_to('&nbsp;' * (level * 4) +
  35 + image_tag(icon_for_article(content)) + short_filename(content.name),
  36 + content.url.merge(:view => true)
  37 + )
30 38 else
31   - link_to('&nbsp;' * (level * 4) + short_filename(article.name), article.url.merge(:view => true), :class => icon_for_article(article))
  39 + link_to('&nbsp;' * (level * 4) +
  40 + short_filename(content.name),
  41 + content.url.merge(:view => true), :class => icon_for_article(content)
  42 + )
32 43 end
33 44 result = content_tag(
34 45 'tr',
35   - content_tag('td', article_link )+
36   - content_tag('td', show_date(article.updated_at), :class => 'last-update'),
37   - :class => 'sitemap-item'
  46 + content_tag('td', content_link ) +
  47 + content_tag('td', show_date(content.updated_at), :class => 'last-update'),
  48 + :class => "#{list_type}-item"
38 49 )
39 50 if recursive
40   - result + article.children.map {|item| display_article_in_listing(item, recursive, level + 1) }.join('')
  51 + result + content.children.map {|item|
  52 + display_content_in_listing :content=>item, :recursive=>recursive,
  53 + :list_type=>list_type, :level=>level+1
  54 + }.join("\n")
41 55 else
42 56 result
43 57 end
... ...
app/helpers/token_helper.rb
... ... @@ -18,6 +18,7 @@ module TokenHelper
18 18 options[:on_add] ||= 'null'
19 19 options[:on_delete] ||= 'null'
20 20 options[:on_ready] ||= 'null'
  21 + options[:query_param] ||= 'q'
21 22  
22 23 result = text_field_tag(name, nil, text_field_options.merge(html_options.merge({:id => element_id})))
23 24 result += javascript_tag("jQuery('##{element_id}')
... ... @@ -30,7 +31,7 @@ module TokenHelper
30 31 searchDelay: #{options[:search_delay].to_json},
31 32 preventDuplicates: #{options[:prevent_duplicates].to_json},
32 33 backspaceDeleteItem: #{options[:backspace_delete_item].to_json},
33   - queryParam: #{name.to_json},
  34 + queryParam: #{options[:query_param].to_json},
34 35 tokenLimit: #{options[:token_limit].to_json},
35 36 onResult: #{options[:on_result]},
36 37 onAdd: #{options[:on_add]},
... ... @@ -48,4 +49,4 @@ module TokenHelper
48 49 result
49 50 end
50 51  
51   -end
52 52 \ No newline at end of file
  53 +end
... ...
app/models/article.rb
... ... @@ -40,6 +40,12 @@ class Article &lt; ActiveRecord::Base
40 40 # xss_terminate plugin can't sanitize array fields
41 41 before_save :sanitize_tag_list
42 42  
  43 + before_create do |article|
  44 + if article.author
  45 + article.author_name = article.author.name
  46 + end
  47 + end
  48 +
43 49 belongs_to :profile
44 50 validates_presence_of :profile_id, :name
45 51 validates_presence_of :slug, :path, :if => lambda { |article| !article.name.blank? }
... ... @@ -48,6 +54,7 @@ class Article &lt; ActiveRecord::Base
48 54  
49 55 validates_uniqueness_of :slug, :scope => ['profile_id', 'parent_id'], :message => N_('The title (article name) is already being used by another article, please use another title.'), :if => lambda { |article| !article.slug.blank? }
50 56  
  57 + belongs_to :author, :class_name => 'Person'
51 58 belongs_to :last_changed_by, :class_name => 'Person', :foreign_key => 'last_changed_by_id'
52 59 belongs_to :created_by, :class_name => 'Person', :foreign_key => 'created_by_id'
53 60  
... ... @@ -456,10 +463,10 @@ class Article &lt; ActiveRecord::Base
456 463 ['TextArticle', 'TextileArticle', 'TinyMceArticle']
457 464 end
458 465  
459   - scope :published, :conditions => { :published => true }
460   - scope :folders, lambda {|profile|{:conditions => { :type => profile.folder_types} }}
461   - scope :no_folders, lambda {|profile|{:conditions => ['type NOT IN (?)', profile.folder_types]}}
462   - scope :galleries, :conditions => { :type => 'Gallery' }
  466 + scope :published, :conditions => ['articles.published = ?', true]
  467 + scope :folders, lambda {|profile|{:conditions => ['articles.type IN (?)', profile.folder_types] }}
  468 + scope :no_folders, lambda {|profile|{:conditions => ['articles.type NOT IN (?)', profile.folder_types]}}
  469 + scope :galleries, :conditions => [ "articles.type IN ('Gallery')" ]
463 470 scope :images, :conditions => { :is_image => true }
464 471 scope :text_articles, :conditions => [ 'articles.type IN (?)', text_article_types ]
465 472 scope :with_types, lambda { |types| { :conditions => [ 'articles.type IN (?)', types ] } }
... ... @@ -469,7 +476,7 @@ class Article &lt; ActiveRecord::Base
469 476 scope :more_recent, :order => "created_at DESC"
470 477  
471 478 def self.display_filter(user, profile)
472   - return {:conditions => ['published = ?', true]} if !user
  479 + return {:conditions => ['articles.published = ?', true]} if !user
473 480 {:conditions => [" articles.published = ? OR
474 481 articles.last_changed_by_id = ? OR
475 482 articles.profile_id = ? OR
... ... @@ -496,6 +503,7 @@ class Article &lt; ActiveRecord::Base
496 503 end
497 504  
498 505 def allow_post_content?(user = nil)
  506 + return true if allow_edit_topic?(user)
499 507 user && (user.has_permission?('post_content', profile) || allow_publish_content?(user) && (user == author))
500 508 end
501 509  
... ... @@ -515,9 +523,14 @@ class Article &lt; ActiveRecord::Base
515 523 end
516 524  
517 525 def allow_edit?(user)
  526 + return true if allow_edit_topic?(user)
518 527 allow_post_content?(user) || user && allow_members_to_edit && user.is_member_of?(profile)
519 528 end
520 529  
  530 + def allow_edit_topic?(user)
  531 + self.belongs_to_forum? && (user == author) && user.present? && user.is_member_of?(profile)
  532 + end
  533 +
521 534 def moderate_comments?
522 535 moderate_comments == true
523 536 end
... ... @@ -632,35 +645,36 @@ class Article &lt; ActiveRecord::Base
632 645 can_display_versions? && display_versions
633 646 end
634 647  
635   - def author(version_number = nil)
636   - if version_number
637   - version = self.versions.find_by_version(version_number)
638   - author_id = version.last_changed_by_id if version
639   - else
640   - author_id = self.created_by_id
641   - end
  648 + def get_version(version_number = nil)
  649 + version_number ? versions.find(:first, :order => 'version', :offset => version_number - 1) : versions.earliest
  650 + end
642 651  
643   - environment.people.find_by_id(author_id)
  652 + def author_by_version(version_number = nil)
  653 + version_number ? profile.environment.people.find_by_id(get_version(version_number).author_id) : author
644 654 end
645 655  
646 656 def author_name(version_number = nil)
647   - person = author(version_number)
648   - person ? person.name : (setting[:author_name] || _('Unknown'))
  657 + person = author_by_version(version_number)
  658 + if version_number
  659 + person ? person.name : _('Unknown')
  660 + else
  661 + person ? person.name : (setting[:author_name] || _('Unknown'))
  662 + end
649 663 end
650 664  
651 665 def author_url(version_number = nil)
652   - person = author(version_number)
  666 + person = author_by_version(version_number)
653 667 person ? person.url : nil
654 668 end
655 669  
656 670 def author_id(version_number = nil)
657   - person = author(version_number)
  671 + person = author_by_version(version_number)
658 672 person ? person.id : nil
659 673 end
660 674  
661 675 def version_license(version_number = nil)
662 676 return license if version_number.nil?
663   - profile.environment.licenses.find_by_id(versions.find_by_version(version_number).license_id)
  677 + profile.environment.licenses.find_by_id(get_version(version_number).license_id)
664 678 end
665 679  
666 680 alias :active_record_cache_key :cache_key
... ...
app/models/category.rb
... ... @@ -14,9 +14,6 @@ class Category &lt; ActiveRecord::Base
14 14 validates_uniqueness_of :slug,:scope => [ :environment_id, :parent_id ], :message => N_('{fn} is already being used by another category.').fix_i18n
15 15 belongs_to :environment
16 16  
17   - validates_inclusion_of :display_color, :in => 1..15, :allow_nil => true
18   - validates_uniqueness_of :display_color, :scope => :environment_id, :if => (lambda { |cat| ! cat.display_color.nil? }), :message => N_('{fn} was already assigned to another category.').fix_i18n
19   -
20 17 # Finds all top level categories for a given environment.
21 18 scope :top_level_for, lambda { |environment|
22 19 {:conditions => ['parent_id is null and environment_id = ?', environment.id ]}
... ... @@ -42,6 +39,13 @@ class Category &lt; ActiveRecord::Base
42 39  
43 40 acts_as_having_image
44 41  
  42 + before_save :normalize_display_color
  43 +
  44 + def normalize_display_color
  45 + display_color.gsub!('#', '') if display_color
  46 + display_color = nil if display_color.blank?
  47 + end
  48 +
45 49 scope :from_types, lambda { |types|
46 50 types.select{ |t| t.blank? }.empty? ?
47 51 { :conditions => { :type => types } } :
... ... @@ -101,4 +105,12 @@ class Category &lt; ActiveRecord::Base
101 105 self.children.find(:all, :conditions => {:display_in_menu => true}).empty?
102 106 end
103 107  
  108 + def with_color
  109 + if display_color.blank?
  110 + parent.nil? ? nil : parent.with_color
  111 + else
  112 + self
  113 + end
  114 + end
  115 +
104 116 end
... ...
app/models/comment.rb
... ... @@ -109,14 +109,17 @@ class Comment &lt; ActiveRecord::Base
109 109 include Noosfero::Plugin::HotSpot
110 110  
111 111 include Spammable
  112 + include CacheCounterHelper
112 113  
113 114 def after_spam!
114 115 SpammerLogger.log(ip_address, self)
115 116 Delayed::Job.enqueue(CommentHandler.new(self.id, :marked_as_spam))
  117 + update_cache_counter(:spam_comments_count, source, 1) if source.kind_of?(Article)
116 118 end
117 119  
118 120 def after_ham!
119 121 Delayed::Job.enqueue(CommentHandler.new(self.id, :marked_as_ham))
  122 + update_cache_counter(:spam_comments_count, source, -1) if source.kind_of?(Article)
120 123 end
121 124  
122 125 def verify_and_notify
... ...
app/models/domain.rb
... ... @@ -2,7 +2,7 @@ require &#39;noosfero/multi_tenancy&#39;
2 2  
3 3 class Domain < ActiveRecord::Base
4 4  
5   - attr_accessible :name, :owner
  5 + attr_accessible :name, :owner, :is_default
6 6  
7 7 # relationships
8 8 ###############
... ...
app/models/enterprise.rb
... ... @@ -25,7 +25,10 @@ class Enterprise &lt; Organization
25 25 N_('Organization website'); N_('Historic and current context'); N_('Activities short description'); N_('City'); N_('State'); N_('Country'); N_('ZIP code')
26 26  
27 27 settings_items :organization_website, :historic_and_current_context, :activities_short_description
  28 +
28 29 settings_items :products_per_catalog_page, :type => :integer, :default => 6
  30 + alias_method :products_per_catalog_page_before_type_cast, :products_per_catalog_page
  31 + validates_numericality_of :products_per_catalog_page, :allow_nil => true, :greater_than => 0
29 32  
30 33 extend SetProfileRegionFromCityState::ClassMethods
31 34 set_profile_region_from_city_state
... ...
app/models/environment.rb
... ... @@ -3,7 +3,7 @@
3 3 # domains.
4 4 class Environment < ActiveRecord::Base
5 5  
6   - attr_accessible :name, :is_default, :signup_welcome_text_subject, :signup_welcome_text_body, :terms_of_use, :message_for_disabled_enterprise, :news_amount_by_folder, :default_language, :languages, :description, :organization_approval_method, :enabled_plugins, :enabled_features, :redirection_after_login, :redirection_after_signup, :contact_email, :theme, :reports_lower_bound, :noreply_email, :signup_welcome_screen_body
  6 + attr_accessible :name, :is_default, :signup_welcome_text_subject, :signup_welcome_text_body, :terms_of_use, :message_for_disabled_enterprise, :news_amount_by_folder, :default_language, :languages, :description, :organization_approval_method, :enabled_plugins, :enabled_features, :redirection_after_login, :redirection_after_signup, :contact_email, :theme, :reports_lower_bound, :noreply_email, :signup_welcome_screen_body, :members_whitelist_enabled, :members_whitelist
7 7  
8 8 has_many :users
9 9  
... ... @@ -124,6 +124,7 @@ class Environment &lt; ActiveRecord::Base
124 124 'organizations_are_moderated_by_default' => _("Organizations have moderated publication by default"),
125 125 'enable_organization_url_change' => _("Allow organizations to change their URL"),
126 126 'admin_must_approve_new_communities' => _("Admin must approve creation of communities"),
  127 + 'admin_must_approve_new_users' => _("Admin must approve registration of new users"),
127 128 'show_balloon_with_profile_links_when_clicked' => _('Show a balloon with profile links when a profile image is clicked'),
128 129 'xmpp_chat' => _('XMPP/Jabber based chat'),
129 130 'show_zoom_button_on_article_images' => _('Show a zoom link on all article images'),
... ... @@ -132,7 +133,8 @@ class Environment &lt; ActiveRecord::Base
132 133 'send_welcome_email_to_new_users' => _('Send welcome e-mail to new users'),
133 134 'allow_change_of_redirection_after_login' => _('Allow users to set the page to redirect after login'),
134 135 'display_my_communities_on_user_menu' => _('Display on menu the list of communities the user can manage'),
135   - 'display_my_enterprises_on_user_menu' => _('Display on menu the list of enterprises the user can manage')
  136 + 'display_my_enterprises_on_user_menu' => _('Display on menu the list of enterprises the user can manage'),
  137 + 'restrict_to_members' => _('Show content only to members')
136 138 }
137 139 end
138 140  
... ... @@ -303,6 +305,17 @@ class Environment &lt; ActiveRecord::Base
303 305 settings[:signup_welcome_screen_body].present?
304 306 end
305 307  
  308 + settings_items :members_whitelist_enabled, :type => :boolean, :default => false
  309 + settings_items :members_whitelist, :type => Array, :default => []
  310 +
  311 + def in_whitelist?(person)
  312 + !members_whitelist_enabled || members_whitelist.include?(person.id)
  313 + end
  314 +
  315 + def members_whitelist=(members)
  316 + settings[:members_whitelist] = members.split(',').map(&:to_i)
  317 + end
  318 +
306 319 def news_amount_by_folder=(amount)
307 320 settings[:news_amount_by_folder] = amount.to_i
308 321 end
... ...
app/models/featured_products_block.rb
1 1 class FeaturedProductsBlock < Block
2 2  
  3 + attr_accessible :product_ids, :groups_of, :speed, :reflect
  4 +
3 5 settings_items :product_ids, :type => Array, :default => []
4 6 settings_items :groups_of, :type => :integer, :default => 3
5 7 settings_items :speed, :type => :integer, :default => 1000
... ...
app/models/highlights_block.rb
1 1 class HighlightsBlock < Block
2 2  
3   - attr_accessible :images
  3 + attr_accessible :images, :interval, :shuffle, :navigation
4 4  
5 5 settings_items :images, :type => Array, :default => []
6 6 settings_items :interval, :type => 'integer', :default => 4
... ...
app/models/location_block.rb
1 1 class LocationBlock < Block
2 2  
  3 + attr_accessible :zoom, :map_type
  4 +
3 5 settings_items :zoom, :type => :integer, :default => 4
4 6 settings_items :map_type, :type => :string, :default => 'roadmap'
5 7  
... ...
app/models/moderate_user_registration.rb 0 → 100644
... ... @@ -0,0 +1,59 @@
  1 +class ModerateUserRegistration < Task
  2 +
  3 + settings_items :user_id, :type => String
  4 + settings_items :name, :type => String
  5 + settings_items :author_name, :type => String
  6 + settings_items :email, :type => String
  7 +
  8 + after_create :schedule_spam_checking
  9 +
  10 + alias :environment :target
  11 + alias :environment= :target=
  12 +
  13 + def schedule_spam_checking
  14 + self.delay.check_for_spam
  15 + end
  16 +
  17 + include Noosfero::Plugin::HotSpot
  18 +
  19 + def sender
  20 + "#{name} (#{email})"
  21 + end
  22 +
  23 + def perform
  24 + user=environment.users.find_by_id(user_id)
  25 + user.activate
  26 + end
  27 +
  28 + def title
  29 + _("New user")
  30 + end
  31 +
  32 + def subject
  33 + name
  34 + end
  35 +
  36 + def information
  37 + { :message => _('%{sender} wants to register.'),
  38 + :variables => {:sender => sender} }
  39 + end
  40 +
  41 + def icon
  42 + result = {:type => :defined_image, :src => '/images/icons-app/person-minor.png', :name => name}
  43 + end
  44 +
  45 + def target_notification_description
  46 + _('%{sender} tried to register.') %
  47 + {:sender => sender}
  48 + end
  49 +
  50 + def target_notification_message
  51 + target_notification_description + "\n\n" +
  52 + _('You need to login on %{system} in order to approve or reject this user.') % { :environment => self.environment }
  53 + end
  54 +
  55 + def target_notification_message
  56 + _("User \"%{user}\" just requested to register. You have to approve or reject it through the \"Pending Validations\" section in your control panel.\n") % { :user => self.name }
  57 + end
  58 +
  59 +end
0 60 \ No newline at end of file
... ...
app/models/product_categories_block.rb
... ... @@ -33,7 +33,7 @@ class ProductCategoriesBlock &lt; Block
33 33 end
34 34 end
35 35  
36   - DISPLAY_OPTIONS['catalog_only'] = _('Only on the catalog')
  36 + DISPLAY_OPTIONS = DISPLAY_OPTIONS.merge('catalog_only' => _('Only on the catalog'))
37 37  
38 38 def display
39 39 settings[:display].nil? ? 'catalog_only' : super
... ...
app/models/products_block.rb
... ... @@ -49,17 +49,10 @@ class ProductsBlock &lt; Block
49 49  
50 50 def products(reload = false)
51 51 if product_ids.blank?
52   - products_list = owner.products(reload)
53   - result = []
54   - [4, products_list.size].min.times do
55   - p = products_list.sample
56   - result << p
57   - products_list -= [p]
58   - end
59   - result
  52 + owner.products.order('RANDOM()').limit([4,owner.products.count].min)
60 53 else
61   - product_ids.map {|item| owner.products.find(item) }
62   - end
  54 + owner.products.where(:id => product_ids)
  55 + end.compact
63 56 end
64 57  
65 58 end
... ...
app/models/rss_feed.rb
1 1 class RssFeed < Article
2 2  
3   - attr_accessible :limit, :enabled, :language, :include
  3 + attr_accessible :limit, :enabled, :language, :include, :feed_item_description
4 4  
5 5 def self.type_name
6 6 _('RssFeed')
... ...
app/models/task.rb
... ... @@ -73,10 +73,6 @@ class Task &lt; ActiveRecord::Base
73 73 end
74 74 end
75 75  
76   - def self.all_types
77   - %w[Invitation EnterpriseActivation AddMember Ticket SuggestArticle AddFriend CreateCommunity AbuseComplaint ApproveComment ApproveArticle CreateEnterprise ChangePassword EmailActivation InviteFriend InviteMember]
78   - end
79   -
80 76 # this method finished the task. It calls #perform, which must be overriden
81 77 # by subclasses. At the end a message (as returned by #finish_message) is
82 78 # sent to the requestor with #notify_requestor.
... ... @@ -254,6 +250,10 @@ class Task &lt; ActiveRecord::Base
254 250 { :conditions => [environment_condition, profile_condition].compact.join(' OR ') }
255 251 }
256 252  
  253 + def self.pending_types_for(profile)
  254 + Task.to(profile).pending.select('distinct type').map { |t| [t.class.name, t.title] }
  255 + end
  256 +
257 257 def opened?
258 258 status == Task::Status::ACTIVE || status == Task::Status::HIDDEN
259 259 end
... ...
app/models/user.rb
... ... @@ -5,7 +5,7 @@ require &#39;user_activation_job&#39;
5 5 # Rails generator.
6 6 class User < ActiveRecord::Base
7 7  
8   - attr_accessible :login, :email, :password, :password_confirmation
  8 + attr_accessible :login, :email, :password, :password_confirmation, :activated_at
9 9  
10 10 N_('Password')
11 11 N_('Password confirmation')
... ... @@ -47,8 +47,12 @@ class User &lt; ActiveRecord::Base
47 47  
48 48 user.person = p
49 49 end
50   - if user.environment.enabled?('skip_new_user_email_confirmation')
51   - user.activate
  50 + if user.environment.enabled?('skip_new_user_email_confirmation')
  51 + if user.environment.enabled?('admin_must_approve_new_users')
  52 + create_moderate_task
  53 + else
  54 + user.activate
  55 + end
52 56 end
53 57 end
54 58 after_create :deliver_activation_code
... ... @@ -137,6 +141,15 @@ class User &lt; ActiveRecord::Base
137 141 end
138 142 end
139 143  
  144 + def create_moderate_task
  145 + @task = ModerateUserRegistration.new
  146 + @task.user_id = self.id
  147 + @task.name = self.name
  148 + @task.email = self.email
  149 + @task.target = self.environment
  150 + @task.save
  151 + end
  152 +
140 153 def activated?
141 154 self.activation_code.nil? && !self.activated_at.nil?
142 155 end
... ...
app/presenters/image.rb
... ... @@ -11,4 +11,9 @@ class FilePresenter::Image &lt; FilePresenter
11 11 def short_description
12 12 _('Image (%s)') % content_type.split('/')[1].upcase
13 13 end
  14 +
  15 + #Overwriting method from FilePresenter to allow download of images
  16 + def download?(view = nil)
  17 + view.blank? || view == 'false'
  18 + end
14 19 end
... ...
app/views/account/_signup_form.html.erb
... ... @@ -136,8 +136,6 @@
136 136 <script type="text/javascript">
137 137 jQuery(function($) {
138 138  
139   - $('#signup-form #user_login').css('width', 335 - $('#signup-domain').outerWidth());
140   -
141 139 $('#signup-form input[type=text], #signup-form textarea').each(function() {
142 140 $(this).bind('blur', function() {
143 141 if ($(this).val() == '') {
... ...
app/views/account/signup.html.erb
... ... @@ -2,18 +2,36 @@
2 2 <div id='thanks-for-signing'>
3 3 <% if environment.has_custom_welcome_screen? %>
4 4 <%= environment.settings[:signup_welcome_screen_body].html_safe %>
5   - <% else %>
6   - <h1><%= _("Welcome to %s!") % environment.name %></h1>
7   - <h3><%= _("Thanks for signing up, we're thrilled to have you on our social network!") %></h3>
8   - <p><%= _("Firstly, some tips for getting started:") %></p>
9   - <h4><%= _("Confirm your account!") %></h4>
  5 + <% elsif environment.enabled?('admin_must_approve_new_users')%>
  6 + <h1><%= _("Welcome to %s!") % environment.name %></h1>
  7 + <h3><%= _("Thanks for signing up, we're thrilled to have you on our social network!") %></h3>
  8 + <p><%= _("Firstly, some tips for getting started:") %></p>
  9 + <% unless environment.enabled?('skip_new_user_email_confirmation') %>
  10 + <h4><%= _("Confirm your account and wait for admin approvement!") %></h4>
10 11 <p><%= _("You should receive a welcome email from us shortly. Please take a second to follow the link within to confirm your account.") %></p>
11   - <p><%= _("You won't appear as %s until your account is confirmed.") % link_to(_('user'), {:controller => :search, :action => :people, :filter => 'more_recent'}, :target => '_blank') %></p>
12   - <h4><%= _("What to do next?") %></h4>
13   - <p><%= _("%s. Upload an avatar and let your friends find you easily :)") % link_to(_('Customize your profile'), {:controller => 'doc', :section => 'user', :topic => 'editing-person-info'}, :target => '_blank') %></p>
14   - <p><%= _("Learn the guidelines. Read the %s for more details on how to use this social network!") % link_to(_('Documentation'), {:controller => 'doc'}, :target => '_blank') %></p>
15   - <p><%= _("%s your Gmail, Yahoo and Hotmail contacts!") % link_to(_('Invite and find'), {:controller => 'doc', :section => 'user', :topic => 'invite-contacts'}, :target => '_blank') %></p>
16   - <p><%= _("Start exploring and have fun!") %></p>
  12 + <p><%= _("You won't appear as %s until your account is confirmed and approved.") % link_to(_('user'), {:controller => :search, :action => :people, :filter => 'more_recent'}, :target => '_blank') %></p>
  13 + <% else %>
  14 + <h4><%= _("Wait for admin approvement!") %></h4>
  15 + <p><%= _("The administrators will evaluate your signup request for approvement.") %></p>
  16 + <p><%= _("You won't appear as %s until your account is approved.") % link_to(_('user'), {:controller => :search, :action => :people, :filter => 'more_recent'}, :target => '_blank') %></p>
  17 + <% end %>
  18 + <h4><%= _("What to do next?") %></h4>
  19 + <p><%= _("%s. Upload an avatar and let your friends find you easily :)") % link_to(_('Customize your profile'), {:controller => 'doc', :section => 'user', :topic => 'editing-person-info'}, :target => '_blank') %></p>
  20 + <p><%= _("Learn the guidelines. Read the %s for more details on how to use this social network!") % link_to(_('Documentation'), {:controller => 'doc'}, :target => '_blank') %></p>
  21 + <p><%= _("%s your Gmail, Yahoo and Hotmail contacts!") % link_to(_('Invite and find'), {:controller => 'doc', :section => 'user', :topic => 'invite-contacts'}, :target => '_blank') %></p>
  22 + <p><%= _("Start exploring and have fun!") %></p>
  23 + <% else %>
  24 + <h1><%= _("Welcome to %s!") % environment.name %></h1>
  25 + <h3><%= _("Thanks for signing up, we're thrilled to have you on our social network!") %></h3>
  26 + <p><%= _("Firstly, some tips for getting started:") %></p>
  27 + <h4><%= _("Confirm your account!") %></h4>
  28 + <p><%= _("You should receive a welcome email from us shortly. Please take a second to follow the link within to confirm your account.") %></p>
  29 + <p><%= _("You won't appear as %s until your account is confirmed.") % link_to(_('user'), {:controller => :search, :action => :people, :filter => 'more_recent'}, :target => '_blank') %></p>
  30 + <h4><%= _("What to do next?") %></h4>
  31 + <p><%= _("%s. Upload an avatar and let your friends find you easily :)") % link_to(_('Customize your profile'), {:controller => 'doc', :section => 'user', :topic => 'editing-person-info'}, :target => '_blank') %></p>
  32 + <p><%= _("Learn the guidelines. Read the %s for more details on how to use this social network!") % link_to(_('Documentation'), {:controller => 'doc'}, :target => '_blank') %></p>
  33 + <p><%= _("%s your Gmail, Yahoo and Hotmail contacts!") % link_to(_('Invite and find'), {:controller => 'doc', :section => 'user', :topic => 'invite-contacts'}, :target => '_blank') %></p>
  34 + <p><%= _("Start exploring and have fun!") %></p>
17 35 <% end %>
18 36 </div>
19 37 <% else %>
... ...
app/views/blocks/my_network.html.erb
1 1 <%= block_title(title) %>
2 2  
3   -<%= render :file => 'blocks/my_network/' + owner.class.name.underscore, :locals => { :owner => owner } %>
  3 +<%= render_profile_actions owner.class %>
4 4  
5 5 <ul>
6 6 <li><%= link_to(_('Homepage'), owner.url, :class => 'url') %></li>
... ... @@ -11,5 +11,5 @@
11 11 </ul>
12 12  
13 13 <div class="my-network-actions">
14   - <%= render :file => 'blocks/profile_info_actions/' + owner.class.name.underscore %>
  14 + <%= render 'blocks/profile_info_actions/' + owner.class.name.underscore %>
15 15 </div>
... ...
app/views/blocks/profile_image.html.erb
... ... @@ -23,6 +23,6 @@
23 23 <% end %>
24 24  
25 25 <div class="profile-info-options">
26   - <%= render :file => view_for_profile_actions(block.owner.class) %>
  26 + <%= render_profile_actions block.owner.class %>
27 27 </div>
28 28 </div><!-- end class="vcard" -->
... ...
app/views/blocks/profile_info.html.erb
... ... @@ -40,7 +40,7 @@
40 40 <% end %>
41 41  
42 42 <div class="profile-info-options">
43   - <%= render :file => view_for_profile_actions(block.owner.class) %>
  43 + <%= render_profile_actions block.owner.class %>
44 44 </div>
45 45  
46 46 </div><!-- end class="vcard" -->
... ...
app/views/blocks/profile_info_actions/_community.html.erb 0 → 100644
... ... @@ -0,0 +1,20 @@
  1 +<ul>
  2 + <li>
  3 + <%= render "blocks/profile_info_actions/join_leave_community" %>
  4 + </li>
  5 + <% if logged_in? %>
  6 + <% if profile.enable_contact? %>
  7 + <li>
  8 + <%= link_to content_tag('span', _('Send an e-mail')),
  9 + { :profile => profile.identifier,
  10 + :controller => 'contact',
  11 + :action => 'new' },
  12 + {:class => 'button with-text icon-menu-mail', :title => _('Send an e-mail to the administrators')} %>
  13 + </li>
  14 + <% end %>
  15 +
  16 + <li><%= report_abuse(profile, :button) %></li>
  17 +
  18 + <%= render_environment_features(:profile_actions) %>
  19 + <% end %>
  20 +</ul>
... ...
app/views/blocks/profile_info_actions/_enterprise.html.erb 0 → 100644
... ... @@ -0,0 +1,12 @@
  1 +<ul>
  2 + <%if logged_in? %>
  3 + <%if !user.favorite_enterprises.include?(profile) %>
  4 + <li><%= link_to content_tag('span', _('Add as favorite')), { :profile => user.identifier, :controller => 'favorite_enterprises', :action => 'add', :id => profile.id }, :class => 'button with-text icon-add', :title => _('Add enterprise as favorite') %></li>
  5 + <% end %>
  6 + <% end %>
  7 + <% if profile.enable_contact? %>
  8 + <li> <%= link_to content_tag('span', _('Send an e-mail')), {:profile => profile.identifier, :controller => 'contact', :action => 'new'}, {:id => 'enterprise-contact-button', :class => 'button with-text icon-menu-mail'} %> </li>
  9 + <% end %>
  10 +
  11 + <li><%= report_abuse(profile, :button) %></li>
  12 +</ul>
... ...
app/views/blocks/profile_info_actions/_organization.html.erb 0 → 100644
app/views/blocks/profile_info_actions/_person.html.erb 0 → 100644
... ... @@ -0,0 +1,16 @@
  1 +<ul>
  2 + <%if logged_in? && (user != profile) %>
  3 +
  4 + <% if !user.already_request_friendship?(profile) and !user.is_a_friend?(profile) %>
  5 + <li>
  6 + <%= button(:add, content_tag('span', _('Add friend')), profile.add_url, :class => 'add-friend', :title => _("Add friend"), :style => 'position: relative;') %>
  7 + </li>
  8 + <% end %>
  9 +
  10 + <% if user.is_a_friend?(profile) && profile.enable_contact? %>
  11 + <li> <%= link_to content_tag('span', _('Send an e-mail')), {:profile => profile.identifier, :controller => 'contact', :action => 'new'}, :class => 'button with-text icon-menu-mail' %> </li>
  12 + <% end %>
  13 +
  14 + <li><%= report_abuse(profile, :button) %></li>
  15 + <% end %>
  16 +</ul>
... ...
app/views/blocks/profile_info_actions/community.html.erb
... ... @@ -1,20 +0,0 @@
1   -<ul>
2   - <li>
3   - <%= render "blocks/profile_info_actions/join_leave_community" %>
4   - </li>
5   - <% if logged_in? %>
6   - <% if profile.enable_contact? %>
7   - <li>
8   - <%= link_to content_tag('span', _('Send an e-mail')),
9   - { :profile => profile.identifier,
10   - :controller => 'contact',
11   - :action => 'new' },
12   - {:class => 'button with-text icon-menu-mail', :title => _('Send an e-mail to the administrators')} %>
13   - </li>
14   - <% end %>
15   -
16   - <li><%= report_abuse(profile, :button) %></li>
17   -
18   - <%= render_environment_features(:profile_actions) %>
19   - <% end %>
20   -</ul>
app/views/blocks/profile_info_actions/enterprise.html.erb
... ... @@ -1,12 +0,0 @@
1   -<ul>
2   - <%if logged_in? %>
3   - <%if !user.favorite_enterprises.include?(profile) %>
4   - <li><%= link_to content_tag('span', _('Add as favorite')), { :profile => user.identifier, :controller => 'favorite_enterprises', :action => 'add', :id => profile.id }, :class => 'button with-text icon-add', :title => _('Add enterprise as favorite') %></li>
5   - <% end %>
6   - <% end %>
7   - <% if profile.enable_contact? %>
8   - <li> <%= link_to content_tag('span', _('Send an e-mail')), {:profile => profile.identifier, :controller => 'contact', :action => 'new'}, {:id => 'enterprise-contact-button', :class => 'button with-text icon-menu-mail'} %> </li>
9   - <% end %>
10   -
11   - <li><%= report_abuse(profile, :button) %></li>
12   -</ul>
app/views/blocks/profile_info_actions/organization.html.erb
app/views/blocks/profile_info_actions/person.html.erb
... ... @@ -1,16 +0,0 @@
1   -<ul>
2   - <%if logged_in? && (user != profile) %>
3   -
4   - <% if !user.already_request_friendship?(profile) and !user.is_a_friend?(profile) %>
5   - <li>
6   - <%= button(:add, content_tag('span', _('Add friend')), profile.add_url, :class => 'add-friend', :title => _("Add friend"), :style => 'position: relative;') %>
7   - </li>
8   - <% end %>
9   -
10   - <% if user.is_a_friend?(profile) && profile.enable_contact? %>
11   - <li> <%= link_to content_tag('span', _('Send an e-mail')), {:profile => profile.identifier, :controller => 'contact', :action => 'new'}, :class => 'button with-text icon-menu-mail' %> </li>
12   - <% end %>
13   -
14   - <li><%= report_abuse(profile, :button) %></li>
15   - <% end %>
16   -</ul>
app/views/box_organizer/_highlights_block.html.erb
  1 +<%= javascript_include_tag "highlight_block" %>
  2 +
1 3 <strong><%= _('Highlights') %></strong>
2 4  
3 5 <table class="noborder"><tbody id="highlights-data-table">
4 6 <tr><th><%= _('Image') %></th><th><%= _('Address') %></th><th><%= _('Position') %></th></tr>
5   - <% for image in @block.images do %>
6   - <%= highlights_block_config_image_fields @block, image %>
  7 + <% @block.images.each_with_index do |image, index| %>
  8 + <%= highlights_block_config_image_fields @block, image, index %>
7 9 <% end %>
8 10 </tbody></table>
9 11  
10   -<%= link_to_function(_('New highlight'), nil, :class => 'button icon-add with-text') do |page|
11   - page.insert_html :bottom, 'highlights-data-table', highlights_block_config_image_fields(@block)
12   -end %>
  12 +<table class="hidden highlight-table-row">
  13 + <tbody>
  14 + <%= highlights_block_config_image_fields(@block) %>
  15 + </tbody>
  16 +</table>
  17 +
  18 +<%= link_to(_('New highlight'), '#', :class => 'button icon-add with-text new-highlight-button')%>
13 19  
14 20 <%= labelled_form_field _('Image transition:'), select('block', 'interval', [[_('No automatic transition'), 0]] + [1, 2, 3, 4, 5, 10, 20, 30, 60].map {|item| [n_('Every 1 second', 'Every %d seconds', item) % item, item]}) %>
15 21  
... ...
app/views/categories/_category.html.erb
1 1 <li>
2 2 <div class='treeitem'>
3   - <%= display_color_for_category(category) %>
4   - <%= category.name %>
  3 + <% unless category_color_style(category).empty? %>
  4 + <span class="color_marker" style="<%= category_color_style(category) %>" ></span>
  5 + <% end %>
  6 + <span><%= category.name %></span>
  7 +
5 8 <% if category.children.count > 0 %>
6 9 <div class='button' id="category-loading-<%= category.id %>" style="position: relative;">
7 10 <a href="#" id="show-button-<%= category.id %>" class="show-button" onclick="return false;" data-category="<%= category.id %>"><%= _('Show') %></a>
... ...
app/views/categories/_form.html.erb
  1 +<%= stylesheet_link_tag 'spectrum.css' %>
  2 +<%= javascript_include_tag "spectrum.js" %>
  3 +<%= javascript_include_tag "colorpicker-noosfero.js" %>
  4 +
1 5 <%= error_messages_for 'category' %>
2 6  
3 7 <%= labelled_form_for 'category', :html => { :multipart => true} do |f| %>
... ... @@ -13,12 +17,13 @@
13 17 <% end %>
14 18 <% end %>
15 19  
16   - <%= select_color_for_category if !environment.enabled?('disable_categories_menu') %>
17   -
18 20 <%= required f.text_field('name') %>
19 21  
20 22 <%= labelled_check_box(_('Display in the menu'), 'category[display_in_menu]', '1', @category.display_in_menu) %>
21 23  
  24 + <%= labelled_colorpicker_field(_('Pick a color'), :category, 'display_color' ) unless environment.enabled?('disable_categories_menu')%>
  25 + <span id="color_preview" class = "color_marker" style="<%= category_color_style(@category) %>" ></span>
  26 +
22 27 <%= f.fields_for :image_builder, @category.image do |i| %>
23 28 <%= file_field_or_thumbnail(_('Image:'), @category.image, i) %>
24 29 <% end %>
... ...
app/views/comment/_comment_form.html.erb
... ... @@ -31,7 +31,7 @@ function check_captcha(button, confirm_action) {
31 31 return true;
32 32 <% else %>
33 33 jQuery('#recaptcha-container').show();
34   - jQuery.colorbox({ inline : true, href : '#recaptcha-container', maxWidth : '600px', maxHeight : '300px' });
  34 + jQuery.colorbox({ html: jQuery('#recaptcha-container').html(), maxWidth : '600px', maxHeight : '300px' });
35 35 jQuery('#confirm-captcha').unbind('click');
36 36 jQuery('#confirm-captcha').bind('click', function() {
37 37 jQuery.colorbox.close();
... ...
app/views/content_viewer/article_versions.html.erb
1 1 <div class="article-versions">
2   - <%= button(:back, _('Go back to latest version'), {:action => 'view_page'}) %>
  2 + <%= button(:back, _('Go back to latest version'), @page.url) %>
3 3 </div>
4 4  
5 5 <%= article_title(@page, :no_link => true) %>
6 6  
7 7 <p><%= _('This is the list of all versions of this content. Select a version to see it and then revert to it.') %>.</p>
8 8  
9   -<%= form_tag({:controller => 'content_viewer', :action => 'versions_diff', :profile => profile.identifier, :page => @page.path.split('/')}, :method => 'get') do %>
  9 +<%= form_tag({:controller => 'content_viewer', :action => 'versions_diff', :profile => profile.identifier, :page => @page.path}, :method => 'get') do %>
10 10 <ul id="article-versions">
11 11 <% @versions.each do |v| %>
12 12 <li>
... ...
app/views/content_viewer/blog_page.html.erb
... ... @@ -9,13 +9,15 @@
9 9 </div>
10 10 <hr class="pre-posts"/>
11 11 <div class="blog-posts">
  12 + <% paginate = true %>
12 13 <%=
13 14 posts = @posts
14 15 format = blog.visualization_format
15 16 if inside_block
16 17 posts = blog.posts.paginate(:page=>1, :per_page=>inside_block.posts_per_page)
17 18 format = inside_block.visualization_format
  19 + paginate = false
18 20 end
19   - (blog.empty? ? content_tag('em', _('(no posts)')) : list_posts(posts, format))
  21 + (blog.empty? ? content_tag('em', _('(no posts)')) : list_posts(posts, format, paginate))
20 22 %>
21 23 </div>
... ...
app/views/content_viewer/folder.html.erb
... ... @@ -8,5 +8,5 @@
8 8 <% if folder.children.empty? %>
9 9 <em><%= _('(empty folder)') %></em>
10 10 <% else %>
11   - <%= list_articles(folder.children) %>
  11 + <%= list_contents(:contents=>folder.children) %>
12 12 <% end %>
... ...
app/views/content_viewer/versioned_article.html.erb
... ... @@ -23,7 +23,6 @@
23 23 <p id="no-current-version">
24 24 <%= _('This is not the latest version of this content.') %>
25 25 </p>
26   -</div>
27 26  
28 27 <% version_license = @page.version_license(@version) %>
29 28 <%# This seemingly doubled verification exists because the article-sub-header
... ...
app/views/content_viewer/view_page.html.erb
... ... @@ -40,8 +40,6 @@
40 40 </div>
41 41 <% end %>
42 42  
43   -<%= render :partial => 'shared/disabled_enterprise' %>
44   -
45 43 <% if NOOSFERO_CONF['addthis_enabled'] %>
46 44 <%= render :partial => 'addthis' %>
47 45 <% end %>
... ...
app/views/features/index.html.erb
... ... @@ -37,6 +37,18 @@ Check all the features you want to enable for your environment, uncheck all the
37 37 <%= select_organization_approval_method('environment', 'organization_approval_method') %>
38 38 <hr/>
39 39  
  40 +<h3><%= _('Members Whitelist') %></h3>
  41 + <div class="option">
  42 + <%= check_box :environment, :members_whitelist_enabled %>
  43 + <label><%= _('Enable whitelist') %></label>
  44 + </div>
  45 + <div class="input">
  46 + <div class="info"><%= _('Allow these people to access this environment:') %></div>
  47 + <% tokenized_members = prepare_to_token_input(environment.people.find(:all, :conditions => {:id => environment.members_whitelist})) %>
  48 + <%= token_input_field_tag('environment[members_whitelist]', 'search-members', {:action => 'search_members'}, {:focus => false, :hint_text => _('Type in a search term for a user'), :pre_populate => tokenized_members}) %>
  49 + </div>
  50 +<hr/>
  51 +
40 52 <div>
41 53 <% button_bar do %>
42 54 <%= submit_button('save', _('Save changes')) %>
... ...
app/views/profile/index.html.erb
1   -<%= render :partial => 'shared/disabled_enterprise' %>
2   -
3 1 <h1><%= h profile.name %></h1>
4 2  
5 3 <% if @action %>
... ...
app/views/profile/sitemap.html.erb
1 1 <h1><%= _("%s: site map") % profile.name %></h1>
2 2  
3   -<%= list_articles(available_articles(@articles, user), false) %>
  3 +<%= list_contents :contents=>available_articles(@articles, user), :list_type=>:sitemap %>
... ...
app/views/profile_editor/index.html.erb
... ... @@ -24,7 +24,7 @@
24 24  
25 25 <%= control_panel_button(_('Edit Appearance'), 'design-editor', :controller => 'profile_themes', :action => 'index') %>
26 26  
27   - <%= control_panel_button(_('Edit Header and Footer'), 'header-and-footer', :controller => 'profile_editor', :action => 'header_footer') unless profile.enterprise? && environment.enabled?('disable_header_and_footer') && !user.is_admin?(environment) %>
  27 + <%= control_panel_button(_('Edit Header and Footer'), 'header-and-footer', :controller => 'profile_editor', :action => 'header_footer') if user.is_admin?(environment) || (!profile.enterprise? && !environment.enabled?('disable_header_and_footer')) %>
28 28  
29 29 <%= control_panel_button(_('Manage Content'), 'cms', :controller => 'cms') %>
30 30  
... ...
app/views/shared/_disabled_enterprise.html.erb
... ... @@ -1,10 +0,0 @@
1   -<% if profile.enterprise? && !profile.enabled? && !profile.blocks.select {|b| b.class == DisabledEnterpriseMessageBlock}.any? %>
2   - <div id='profile-disabled'>
3   - <%= environment.message_for_disabled_enterprise %>
4   - <% if profile.blocked? && user && user.is_admin?(profile.environment) %>
5   - <div class='unlock-button'>
6   - <%= button :lock, _('Unblock'), {:controller => 'profile', :action => 'unblock'} %>
7   - </div>
8   - <% end %>
9   - </div>
10   -<% end %>
app/views/shared/_manage_link.html.erb
1 1 <div id=<%= "manage-#{kind}" %> class="manage-groups">
2   - <a href="#" id=<%= "manage-#{kind}-link" %> class="simplemenu-trigger" title="<%= _('Manage %s') % kind %>"><i class=<%= "icon-menu-#{kind.singularize}" %>></i><strong><%= ui_icon('ui-icon-triangle-1-s') + _('My %s') % kind %></strong></a>
  2 + <a href="#" id=<%= "manage-#{kind}-link" %> class="simplemenu-trigger" title="<%= _('Manage %s') % _(kind) %>"><i class=<%= "icon-menu-#{kind.singularize}" %>></i><strong><%= ui_icon('ui-icon-triangle-1-s') + title %></strong></a>
3 3 <ul class="simplemenu-submenu">
4 4 <% link.each do |link| %>
5 5 <li class="simplemenu-item"><%= link %></li>
... ...
app/views/shared/articles_list.html.erb
... ... @@ -1,14 +0,0 @@
1   -<table>
2   -
3   - <tr>
4   - <th><%= _('Title') %></th>
5   - <th><%= _('Last update') %></th>
6   - </tr>
7   - <% articles.each do |article| %>
8   - <% if article.display_to?(user) %>
9   - <%= display_article_in_listing(article, recursive, 0) %>
10   - <% end %>
11   - <% end %>
12   -</table>
13   -
14   -<p><%= pagination_links(articles, {:param_name => 'npage', :page_links => true}) %></p>
app/views/shared/content_list.html.erb 0 → 100644
... ... @@ -0,0 +1,13 @@
  1 +<table class="<%= list_type %>-content">
  2 + <tr>
  3 + <th><%= _('Title') %></th>
  4 + <th><%= _('Last update') %></th>
  5 + </tr>
  6 + <% contents.each do |content| %>
  7 + <% if content.display_to?(user) %>
  8 + <%= display_content_in_listing :content=>content, :list_type=>list_type, :recursive=>recursive %>
  9 + <% end %>
  10 + <% end %>
  11 +</table>
  12 +
  13 +<p><%= pagination_links contents, :param_name => 'npage', :page_links => true %></p>
... ...
app/views/tasks/index.html.erb
... ... @@ -3,10 +3,9 @@
3 3 <h1><%= _("%s's pending tasks") % profile.name %></h1>
4 4 <p>
5 5  
6   -<% type_collection = [[nil, _('All')]] %>
7   -<% type_collection += Task.all_types.sort_by {|klass| klass.constantize.new.title}.map{|s| [s, s.constantize.new.title] } %>
8   -
9   -
  6 +<%
  7 + type_collection = [[nil, _('All')]] + @task_types
  8 +%>
10 9  
11 10 <% if !@failed.blank? %>
12 11 <div id="errorExplanation">
... ... @@ -39,7 +38,7 @@
39 38  
40 39 <ul class='task-list'>
41 40 <p>
42   - <%= labelled_select(_('Filter')+': ', :filter_type, :first, :last, @filter, type_collection, :onchange => 'document.location.href = "?filter_type="+this.value')%>
  41 + <%= labelled_select(_('Filter')+': ', :filter_type, :first, :last, @filter, type_collection, :onchange => "document.location.href = '?filter_type='+this.value") %>
43 42 </p>
44 43 <p>
45 44 <%= labelled_select(_("Set all to: "), 'set-decisions', 'first', 'last', nil, [['',""],['accept',_("Accept")],['reject',_("Reject")],['skip',_("Skip")]], :id => "up-set-all-tasks-to") %>
... ...
config/environment.rb
1 1 # Load the rails application
2 2 require File.expand_path('../application', __FILE__)
3 3  
  4 +#FIXME Necessary hack to avoid the need of downgrading rubygems on rails 2.3.5
  5 +# http://stackoverflow.com/questions/5564251/uninitialized-constant-activesupportdependenciesmutex
  6 +require 'thread'
  7 +
4 8 # Uncomment below to force Rails into production mode when
5 9 # you don't control web/app server and can't set it the proper way
6 10 #ENV['RAILS_ENV'] ||= 'production'
... ...
config/initializers/exception_notification.rb
1 1 unless NOOSFERO_CONF['exception_recipients'].blank?
2   - require 'noosfero.rb'
3   - require 'exception_notification.rb'
4   - ExceptionNotifier.sender_address = "noreply@#{Noosfero.default_hostname}"
5   - ExceptionNotifier.email_prefix = "[Noosfero ERROR] "
6   - ExceptionNotifier.exception_recipients = NOOSFERO_CONF['exception_recipients']
7   - ActionController::Base.send :include, ExceptionNotifiable
  2 + Noosfero::Application.config.middleware.use ExceptionNotification::Rack,
  3 + :email => {
  4 + :sender_address => "noreply@#{Noosfero.default_hostname}",
  5 + :email_prefix => "[Noosfero ERROR] ",
  6 + :exception_recipients => NOOSFERO_CONF['exception_recipients']
  7 + }
8 8 end
... ...
config/initializers/passenger.rb 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +if defined? PhusionPassenger
  2 +
  3 + # from http://russbrooks.com/2010/10/20/rails-cache-memcache-on-passenger-with-smart-spawning
  4 + PhusionPassenger.on_event :starting_worker_process do |forked|
  5 + if forked
  6 + Rails.cache.instance_variable_get(:@data).reset if Rails.cache.class == ActiveSupport::Cache::MemCacheStore
  7 + end
  8 + end
  9 +end
... ...
config/routes.rb
... ... @@ -131,7 +131,7 @@ Noosfero::Application.routes.draw do
131 131 match ':profile/*page/versions', :controller => 'content_viewer', :action => 'article_versions', :profile => /#{Noosfero.identifier_format}/, :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}/, :conditions => { :if => lambda { |env| !Domain.hosting_profile_at(env[:host]) } }
  134 + match ':profile/*page/versions_diff', :controller => 'content_viewer', :action => 'versions_diff', :profile => /#{Noosfero.identifier_format}/, :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
... ...
db/migrate/20140501171906_index_filtered_fields_on_task.rb 0 → 100644
... ... @@ -0,0 +1,17 @@
  1 +class IndexFilteredFieldsOnTask < ActiveRecord::Migration
  2 + def self.up
  3 + add_index :tasks, :requestor_id
  4 + add_index :tasks, :target_id
  5 + add_index :tasks, :target_type
  6 + add_index :tasks, [:target_id, :target_type]
  7 + add_index :tasks, :status
  8 + end
  9 +
  10 + def self.down
  11 + remove_index :tasks, :requestor_id
  12 + remove_index :tasks, :target_id
  13 + remove_index :tasks, :target_type
  14 + remove_index :tasks, [:target_id, :target_type]
  15 + remove_index :tasks, :status
  16 + end
  17 +end
... ...
db/migrate/20140709212646_add_spam_comments_counter_cache_to_articles.rb 0 → 100644
... ... @@ -0,0 +1,12 @@
  1 +class AddSpamCommentsCounterCacheToArticles < ActiveRecord::Migration
  2 + def self.up
  3 + add_column :articles, :spam_comments_count, :integer, :default => 0
  4 + add_column :article_versions, :spam_comments_count, :integer, :default => 0
  5 + execute "update articles set spam_comments_count = (select count(*) from comments where comments.source_id = articles.id and comments.source_type = 'Article' and comments.spam = 't');"
  6 + end
  7 +
  8 + def self.down
  9 + remove_column :articles, :spam_comments_count
  10 + remove_column :article_versions, :spam_comments_count
  11 + end
  12 +end
... ...
db/migrate/20140709224246_create_real_relation_between_article_and_author.rb 0 → 100644
... ... @@ -0,0 +1,14 @@
  1 +class CreateRealRelationBetweenArticleAndAuthor < ActiveRecord::Migration
  2 + def self.up
  3 + add_column :articles, :author_id, :integer
  4 + add_column :article_versions, :author_id, :integer
  5 +
  6 + # Set article's author as the first version's last_changed_by_id.
  7 + execute "update articles set author_id = (select article_versions.last_changed_by_id from article_versions where article_versions.article_id = articles.id and article_versions.version = 1 limit 1)"
  8 + end
  9 +
  10 + def self.down
  11 + remove_column :articles, :author_id
  12 + remove_column :article_versions, :author_id
  13 + end
  14 +end
... ...
db/migrate/20140724134601_fix_yaml_encoding.rb
... ... @@ -6,6 +6,7 @@ class FixYamlEncoding &lt; ActiveRecord::Migration
6 6 fix_encoding(Profile, 'data')
7 7 fix_encoding(ActionTracker::Record, 'params')
8 8 fix_encoding(Article, 'setting')
  9 + fix_encoding(Task, 'data')
9 10 end
10 11  
11 12 def self.down
... ...
db/migrate/20140807134625_change_category_display_color_to_string.rb 0 → 100644
... ... @@ -0,0 +1,36 @@
  1 +class ChangeCategoryDisplayColorToString < ActiveRecord::Migration
  2 +
  3 + COLORS = ['ffa500', '00FF00', 'a020f0', 'ff0000', '006400', '191970', '0000ff', 'a52a2a', '32cd32', 'add8e6', '483d8b', 'b8e9ee', 'f5f5dc', 'ffff00', 'f4a460']
  4 +
  5 + def self.up
  6 + change_table :categories do |t|
  7 + t.string :display_color_tmp, :limit => 6
  8 + end
  9 +
  10 + COLORS.each_with_index do |color, i|
  11 + Category.update_all({:display_color_tmp => color}, {:display_color => i+1})
  12 + end
  13 +
  14 + change_table :categories do |t|
  15 + t.remove :display_color
  16 + t.rename :display_color_tmp, :display_color
  17 + end
  18 + end
  19 +
  20 + def self.down
  21 + puts "WARNING: only old defined colors will be reverted"
  22 +
  23 + change_table :categories do |t|
  24 + t.integer :display_color_tmp
  25 + end
  26 +
  27 + COLORS.each_with_index do |color, i|
  28 + Category.update_all({:display_color_tmp => i+1}, {:display_color => color})
  29 + end
  30 +
  31 + change_table :categories do |t|
  32 + t.remove :display_color
  33 + t.rename :display_color_tmp, :display_color
  34 + end
  35 + end
  36 +end
... ...
db/migrate/20140808185510_update_default_tagging_context.rb 0 → 100644
... ... @@ -0,0 +1,11 @@
  1 +class UpdateDefaultTaggingContext < ActiveRecord::Migration
  2 +
  3 + def self.up
  4 + ActsAsTaggableOn::Tagging.where(:taggable_type => Article, :context => nil).update_all(:context => 'tags')
  5 + end
  6 +
  7 + def self.down
  8 + ActsAsTaggableOn::Tagging.where(:taggable_type => Article, :context => 'tags').update_all(:context => nil)
  9 + end
  10 +
  11 +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 => 20140724134601) do
  14 +ActiveRecord::Schema.define(:version => 20140808185510) do
15 15  
16 16 create_table "abuse_reports", :force => true do |t|
17 17 t.integer "reporter_id"
... ... @@ -96,6 +96,8 @@ ActiveRecord::Schema.define(:version =&gt; 20140724134601) do
96 96 t.integer "image_id"
97 97 t.integer "position"
98 98 t.integer "created_by_id"
  99 + t.integer "spam_comments_count", :default => 0
  100 + t.integer "author_id"
99 101 end
100 102  
101 103 add_index "article_versions", ["article_id"], :name => "index_article_versions_on_article_id"
... ... @@ -142,6 +144,8 @@ ActiveRecord::Schema.define(:version =&gt; 20140724134601) do
142 144 t.integer "image_id"
143 145 t.integer "position"
144 146 t.integer "created_by_id"
  147 + t.integer "spam_comments_count", :default => 0
  148 + t.integer "author_id"
145 149 end
146 150  
147 151 add_index "articles", ["comments_count"], :name => "index_articles_on_comments_count"
... ... @@ -190,19 +194,19 @@ ActiveRecord::Schema.define(:version =&gt; 20140724134601) do
190 194 create_table "categories", :force => true do |t|
191 195 t.string "name"
192 196 t.string "slug"
193   - t.text "path", :default => ""
194   - t.integer "display_color"
  197 + t.text "path", :default => ""
195 198 t.integer "environment_id"
196 199 t.integer "parent_id"
197 200 t.string "type"
198 201 t.float "lat"
199 202 t.float "lng"
200   - t.boolean "display_in_menu", :default => false
201   - t.integer "children_count", :default => 0
202   - t.boolean "accept_products", :default => true
  203 + t.boolean "display_in_menu", :default => false
  204 + t.integer "children_count", :default => 0
  205 + t.boolean "accept_products", :default => true
203 206 t.integer "image_id"
204 207 t.string "acronym"
205 208 t.string "abbreviation"
  209 + t.string "display_color", :limit => 6
206 210 end
207 211  
208 212 create_table "categories_profiles", :id => false, :force => true do |t|
... ... @@ -597,7 +601,12 @@ ActiveRecord::Schema.define(:version =&gt; 20140724134601) do
597 601 t.boolean "spam", :default => false
598 602 end
599 603  
  604 + add_index "tasks", ["requestor_id"], :name => "index_tasks_on_requestor_id"
600 605 add_index "tasks", ["spam"], :name => "index_tasks_on_spam"
  606 + add_index "tasks", ["status"], :name => "index_tasks_on_status"
  607 + add_index "tasks", ["target_id", "target_type"], :name => "index_tasks_on_target_id_and_target_type"
  608 + add_index "tasks", ["target_id"], :name => "index_tasks_on_target_id"
  609 + add_index "tasks", ["target_type"], :name => "index_tasks_on_target_type"
601 610  
602 611 create_table "terms_forum_people", :id => false, :force => true do |t|
603 612 t.integer "forum_id"
... ...
debian/changelog
  1 +noosfero (1.0~rc1) wheezy-test; urgency=low
  2 +
  3 + * First 1.0 release candidate
  4 +
  5 + -- Rodrigo Souto <vagrant@wheezy-base> Fri, 15 Aug 2014 16:35:35 -0300
  6 +
1 7 noosfero (0.99.0~rc20140618202455) wheezy-test; urgency=low
2 8  
3 9 * Another rc with rails3
4 10  
5 11 -- Rodrigo Souto <rodrigo@colivre.coop.br> Wed, 18 Jun 2014 20:25:01 +0000
6 12  
  13 +noosfero (0.47.3) unstable; urgency=low
  14 +
  15 + * Bugfixes release
  16 +
  17 + -- Daniela Soares Feitosa <daniela@colivre.coop.br> Fri, 20 Jun 2014 03:13:29 +0000
  18 +
  19 +noosfero (0.47.2) unstable; urgency=low
  20 +
  21 + * Bugfix release
  22 +
  23 + -- Rodrigo Souto <rodrigo@colivre.coop.br> Fri, 13 Jun 2014 15:19:28 +0000
  24 +
7 25 noosfero (0.47.1) unstable; urgency=low
8 26  
9 27 * Bugfix release
... ...
debian/control
... ... @@ -7,6 +7,7 @@ Build-Depends:
7 7 debhelper (>= 7.0.50~),
8 8 po4a,
9 9 ruby-gettext,
  10 + ruby-gettext-rails,
10 11 ruby-sqlite3,
11 12 rake,
12 13 rails3 (>= 3.2.6-1~),
... ... @@ -32,10 +33,10 @@ Package: noosfero
32 33 Architecture: all
33 34 Depends:
34 35 rails3 (>= 3.2.6-1~),
35   - ruby,
36   - ruby1.9.3,
  36 + ruby (>= 1:1.9.3),
37 37 rake,
38 38 ruby-dalli,
  39 + ruby-exception-notification,
39 40 ruby-fast-gettext,
40 41 ruby-pg,
41 42 ruby-rmagick,
... ...
debian/docs
1   -AUTHORS
  1 +AUTHORS.md
  2 +INSTALL.awstats.md
  3 +INSTALL.chat.md
  4 +INSTALL.email.md
  5 +INSTALL.https.md
  6 +INSTALL.multitenancy.md
  7 +INSTALL.varnish.md
... ...
debian/rules
... ... @@ -29,4 +29,4 @@ override_dh_clean:
29 29  
30 30 override_dh_auto_build:
31 31 dh_auto_build
32   - rake noosfero:translations:compile
  32 + rake noosfero:translations:compile > /dev/null
... ...
features/highlights_block.feature 0 → 100644
... ... @@ -0,0 +1,44 @@
  1 +Feature: Edit Highlight Block
  2 + As a user
  3 + I want to edit the highlight block
  4 +
  5 + Background:
  6 + Given I am on the homepage
  7 + And the following users
  8 + | login | name |
  9 + | jose | Jose Silva |
  10 + And I am logged in as "jose"
  11 +
  12 + @selenium
  13 + Scenario: Add new highlight
  14 + Given I follow "Control panel"
  15 + And I follow "Edit sideboxes"
  16 + And I follow "Add a block"
  17 + And I choose "Highlights"
  18 + And I press "Add"
  19 + And I follow "Edit" within ".highlights-block"#Need to hover the mouse on the box
  20 + And I follow "New highlight"
  21 + And I fill in "block_images__address" with "/"
  22 + And I fill in "block_images__position" with "0"
  23 + And I fill in "block_images__title" with "test highlights"
  24 + And I press "Save"
  25 + And I follow "Edit" within ".highlights-block"
  26 + Then I should see "Title"
  27 +
  28 + @selenium-fixme
  29 + Scenario: Remove one saved highlight
  30 + Given I follow "Control panel"
  31 + And I follow "Edit sideboxes"
  32 + And I follow "Add a block"
  33 + And I choose "Highlights"
  34 + And I press "Add"
  35 + And I follow "Edit" within ".highlights-block"
  36 + And I follow "New highlight"
  37 + And I fill in "block_images__address" with "/"
  38 + And I fill in "block_images__position" with "0"
  39 + And I fill in "block_images__title" with "test highlights"#Need to hover the mouse on the box
  40 + And I press "Save"
  41 + And I follow "Edit" within ".highlights-block"
  42 + And I follow "" within ".delete-highlight"
  43 + And I confirm the browser dialog
  44 + Then I should not see "Title"
0 45 \ No newline at end of file
... ...
features/signup.feature
... ... @@ -298,3 +298,55 @@ Feature: signup
298 298 And wait for the captcha signup time
299 299 And I press "Create my account"
300 300 Then "José da Silva" should be a member of "Free Software"
  301 +
  302 + @selenium
  303 + Scenario: user registration is moderated by admin
  304 + Given feature "admin_must_approve_new_users" is enabled on environment
  305 + And feature "skip_new_user_email_confirmation" is disabled on environment
  306 + And I go to /account/signup
  307 + And I fill in "Username" with "teste"
  308 + And I fill in "Password" with "123456"
  309 + And I fill in "Password confirmation" with "123456"
  310 + And I fill in "e-Mail" with "teste@teste.com"
  311 + And I fill in "Full name" with "Teste da Silva"
  312 + And wait for the captcha signup time
  313 + And I press "Create my account"
  314 + And I go to teste's confirmation URL
  315 + And I am logged in as admin
  316 + And I follow "Control panel"
  317 + And I follow "Tasks"
  318 + And I choose "Accept"
  319 + And I press "Apply!"
  320 + And I follow "Logout"
  321 + And Teste da Silva's account is activated
  322 + And I follow "Login"
  323 + And I fill in "Username / Email" with "teste"
  324 + And I fill in "Password" with "123456"
  325 + And I press "Log in"
  326 + Then I should see "teste"
  327 +
  328 +
  329 + @selenium
  330 + Scenario: user registration is not accepted by the admin
  331 + Given feature "admin_must_approve_new_users" is enabled on environment
  332 + And feature "skip_new_user_email_confirmation" is disabled on environment
  333 + And I go to /account/signup
  334 + And I fill in "Username" with "teste"
  335 + And I fill in "Password" with "123456"
  336 + And I fill in "Password confirmation" with "123456"
  337 + And I fill in "e-Mail" with "teste@teste.com"
  338 + And I fill in "Full name" with "Teste da Silva"
  339 + And wait for the captcha signup time
  340 + And I press "Create my account"
  341 + And I go to teste's confirmation URL
  342 + And I am logged in as admin
  343 + And I follow "Control panel"
  344 + And I follow "Tasks"
  345 + And I choose "Reject"
  346 + And I press "Apply!"
  347 + And I follow "Logout"
  348 + And I follow "Login"
  349 + And I fill in "Username / Email" with "teste"
  350 + And I fill in "Password" with "123456"
  351 + And I press "Log in"
  352 + Then I should not see "teste"
301 353 \ No newline at end of file
... ...
features/step_definitions/web_steps.rb
... ... @@ -11,8 +11,14 @@ require File.expand_path(File.join(File.dirname(__FILE__), &quot;..&quot;, &quot;support&quot;, &quot;pat
11 11  
12 12 module WithinHelpers
13 13 def with_scope(locator)
14   - locator = locator ? first(locator) : locator
15   - locator ? within(locator) { yield } : yield
  14 + if locator
  15 + locator = first(locator) || locator
  16 + within(locator) do
  17 + yield
  18 + end
  19 + else
  20 + yield
  21 + end
16 22 end
17 23 end
18 24 World(WithinHelpers)
... ...
lib/file_presenter.rb
... ... @@ -6,7 +6,9 @@ class FilePresenter
6 6 # one accepts it. That behave allow to give any model to this class,
7 7 # like a Article and have no trouble with that.
8 8 def self.for(f)
9   - return f if f.is_a? FilePresenter
  9 + #FIXME This check after the || is redundant but increases the blog_page
  10 + # speed considerably.
  11 + return f if f.is_a?(FilePresenter ) || (!f.kind_of?(UploadedFile) && !f.kind_of?(Image))
10 12 klass = FilePresenter.subclasses.sort_by {|class_instance|
11 13 class_instance.accepts?(f) || 0
12 14 }.last
... ...
lib/noosfero.rb
... ... @@ -2,8 +2,6 @@
2 2  
3 3 require 'fast_gettext'
4 4 module Noosfero
5   - PROJECT = 'noosfero'
6   - VERSION = '0.99.0~rc20140618202455'
7 5  
8 6 def self.pattern_for_controllers_in_directory(dir)
9 7 disjunction = controllers_in_directory(dir).join('|')
... ... @@ -95,5 +93,6 @@ module Noosfero
95 93  
96 94 end
97 95  
  96 +require 'noosfero/version'
98 97 require 'noosfero/constants'
99 98 require 'noosfero/core_ext'
... ...
lib/noosfero/plugin/routes.rb
1   -plugins_root = Rails.env.test? ? 'plugins' : File.join('config', 'plugins')
  1 +plugins_root = Rails.env.test? ? 'plugins' : '{baseplugins,config/plugins}'
2 2  
3 3 Dir.glob(Rails.root.join(plugins_root, '*', 'controllers')) do |controllers_dir|
4 4 prefixes_by_folder = {'public' => 'plugin',
... ...
lib/noosfero/version.rb 0 → 100644
... ... @@ -0,0 +1,4 @@
  1 +module Noosfero
  2 + PROJECT = 'noosfero'
  3 + VERSION = '1.0~rc1'
  4 +end
... ...
lib/tasks/doc.rake
... ... @@ -137,7 +137,6 @@ namespace :noosfero do
137 137 desc "Translates Noosfero online documentation (does not touch PO files)"
138 138 task :translate => [:link_plugins_textiles, :do_translation]
139 139 task :do_translation => english_xhtml do
140   - require_dependency 'noosfero'
141 140 languages = Noosfero.locales.keys - ['en']
142 141 languages.each do |lang|
143 142 po = "po/#{lang}/noosfero-doc.po"
... ...
lib/tasks/plugins.rake
... ... @@ -7,7 +7,11 @@ namespace :noosfero do
7 7 plugin_migration_dirs = Dir.glob(Rails.root.join('{baseplugins,config/plugins}', '*', 'db', 'migrate'))
8 8  
9 9 task :load_config do
10   - dirs = Dir.glob("{baseplugins,config/plugins}/*/db/migrate")
  10 + dirs = Dir.glob("{baseplugins,config/plugins}/*").uniq do |dir|
  11 + File.basename(dir)
  12 + end.map do |dir|
  13 + File.join(dir, 'db/migrate')
  14 + end
11 15 dirs.each do |dir|
12 16 ActiveRecord::Migrator.migrations_paths << dir
13 17 end
... ...
lib/tasks/release.rake
1 1 # encoding: UTF-8
2 2  
  3 +require 'noosfero/version'
  4 +$version = Noosfero::VERSION
  5 +
3 6 namespace :noosfero do
4 7  
5 8 def pendencies_on_authors
6   - sh "git status | grep 'AUTHORS' > /dev/null" do |ok, res|
  9 + sh "git status | grep 'AUTHORS.md' > /dev/null" do |ok, res|
7 10 return {:ok => !ok, :res => res}
8 11 end
9 12 end
10 13  
11 14 def pendencies_on_repo
12   - sh "git status | grep 'nothing.*commit' > /dev/null" do |ok, res|
  15 + sh "git status | grep 'nothing.*commit' > /dev/null" do |ok, res|
13 16 return {:ok => ok, :res => res}
14 17 end
15 18 end
16 19  
17 20 def pendencies_on_public_errors
18   - sh "git status | grep -e '500.html' -e '503.html' > /dev/null" do |ok, res|
  21 + sh "git status | grep -e '500.html' -e '503.html' > /dev/null" do |ok, res|
19 22 return {:ok => !ok, :res => res}
20 23 end
21 24 end
... ... @@ -40,32 +43,16 @@ namespace :noosfero do
40 43 end
41 44 end
42 45  
43   - def version
44   - require 'noosfero'
45   - Noosfero::VERSION
46   - end
47   -
48 46 desc 'checks if there is already a tag for the current version'
49 47 task :check_tag do
50   - sh "git tag | grep '^#{version}$' >/dev/null" do |ok, res|
  48 + sh "git tag | grep '^#{$version}$' >/dev/null" do |ok, res|
51 49 if ok
52   - raise "******** There is already a tag for version #{version}, cannot continue"
  50 + raise "******** There is already a tag for version #{$version}, cannot continue"
53 51 end
54 52 end
55   - puts "Not found tag for version #{version}, we can go on."
  53 + puts "Not found tag for version #{$version}, we can go on."
56 54 end
57 55  
58   - desc 'checks the version of the Debian package'
59   - task :check_debian_package do
60   - debian_version = `dpkg-parsechangelog | grep Version: | cut -d ' ' -f 2`.strip
61   - unless debian_version =~ /^#{version}/
62   - puts "Version mismatch: Debian version = #{debian_version}, Noosfero upstream version = #{version}"
63   - puts "Run `dch -v #{version}` to add a new changelog entry that upgrades the Debian version"
64   - raise "Version mismatch between noosfero version and debian package version"
65   - end
66   - end
67   -
68   -
69 56 AUTHORS_HEADER = <<EOF
70 57 If you are not listed here, but should be, please write to the noosfero mailing
71 58 list: http://listas.softwarelivre.org/cgi-bin/mailman/listinfo/noosfero-dev
... ... @@ -91,15 +78,15 @@ Arts
91 78 Nara Oliveira <narananet@gmail.com>
92 79 EOF
93 80  
94   - desc 'updates the AUTHORS file'
  81 + desc 'updates the authors file'
95 82 task :authors do
96 83 begin
97   - File.open("AUTHORS", 'w') do |output|
  84 + File.open("AUTHORS.md", 'w') do |output|
98 85 output.puts AUTHORS_HEADER
99 86 output.puts `git log --pretty=format:'%aN <%aE>' | sort | uniq`
100 87 output.puts AUTHORS_FOOTER
101 88 end
102   - commit_changes(['AUTHORS'], 'Updating AUTHORS file') if !pendencies_on_authors[:ok]
  89 + commit_changes(['AUTHORS.md'], 'Updating authors file') if !pendencies_on_authors[:ok]
103 90 rescue Exception => e
104 91 rm_f 'AUTHORS'
105 92 raise e
... ... @@ -131,100 +118,113 @@ EOF
131 118 end
132 119  
133 120 desc "uploads the packages to the repository"
134   - task :upload_packages, :release_kind do |t, args|
135   - release_kind = args[:release_kind] || 'stable'
136   - sh "dput --unchecked #{release_kind} #{Dir['pkg/*.changes'].first}"
  121 + task :upload_packages, :target do |t, args|
  122 + target = args[:target] || 'stable'
  123 + sh "dput --unchecked noosfero-#{target} #{Dir['pkg/*.changes'].first}"
137 124 end
138 125  
139 126 desc 'sets the new version on apropriate files'
140   - task :set_version, :release_kind do |t, args|
  127 + task :set_version, :target do |t, args|
141 128 next if File.exist?("tmp/pending-release")
142   - release_kind = args[:release_kind] || 'stable'
143   -
144   - if release_kind =~ /test/
145   - version_question = "Release candidate of which version: "
146   - if release_kind == 'squeeze-test'
147   - distribution = 'squeeze-test'
148   - elsif release_kind == 'wheezy-test'
149   - distribution = 'wheezy-test'
  129 + target = args[:target]
  130 +
  131 + new_version = $version.dup
  132 +
  133 + if target =~ /-test$/
  134 + if new_version =~ /~rc\d\+/
  135 + new_version.sub!(/\~rc([0-9]+)/) { "~rc#{$1.to_i + 1}" }
  136 + else
  137 + new_version += '~rc1'
150 138 end
151 139 else
152   - version_question = "Version that is being released: "
153   - distribution = 'unstable'
  140 + new_version.sub!(/~rc[0-9]+/, '')
154 141 end
155 142  
156   - version_name = new_version = ask(version_question)
157   -
158   - if release_kind =~ /test/
159   - timestamp = Time.now.strftime('%Y%m%d%H%M%S')
160   - version_name += "~rc#{timestamp}"
161   - end
  143 + puts "Current version: #{$version}"
  144 + ask("Version to release" % new_version, new_version)
162 145 release_message = ask("Release message")
163 146  
164   - sh 'git checkout debian/changelog lib/noosfero.rb'
165   - sh "sed -i \"s/VERSION = '[^']*'/VERSION = '#{version_name}'/\" lib/noosfero.rb"
166   - sh "dch --newversion #{version_name} --distribution #{distribution} --force-distribution '#{release_message}'"
  147 + sh 'git checkout debian/changelog lib/noosfero/version.rb'
  148 + sh "sed -i \"s/VERSION = '[^']*'/VERSION = '#{new_version}'/\" lib/noosfero/version.rb"
  149 + sh "dch --newversion #{new_version} --distribution #{target} --force-distribution '#{release_message}'"
167 150  
168   - sh 'git diff debian/changelog lib/noosfero.rb'
169   - if confirm("Commit version bump to #{version_name} on #{distribution} distribution")
170   - sh 'git add debian/changelog lib/noosfero.rb'
171   - sh "git commit -m 'Bumping version #{version_name}'"
  151 + sh 'git diff debian/changelog lib/noosfero/version.rb'
  152 + if confirm("Commit version bump to #{new_version} on #{target} distribution")
  153 + sh 'git add debian/changelog lib/noosfero/version.rb'
  154 + sh "git commit -m 'Bumping version #{new_version}'"
172 155 sh "touch tmp/pending-release"
173 156 else
174   - sh 'git checkout debian/changelog lib/noosfero.rb'
  157 + sh 'git checkout debian/changelog lib/noosfero/version.rb'
175 158 abort 'Version update not confirmed. Reverting changes and exiting...'
176 159 end
  160 +
  161 + $version = new_version
  162 + end
  163 +
  164 + task :check_release_deps do
  165 + missing = false
  166 + {
  167 + dput: :dput,
  168 + dch: :devscripts,
  169 + }.each do |program, package|
  170 + if ! system("which #{program} >/dev/null 2>&1")
  171 + puts "Program #{program} missing, install the package #{package}"
  172 + missing = true
  173 + end
  174 + end
  175 + abort if missing
177 176 end
178 177  
179 178 desc 'prepares a release tarball'
180   - task :release, :release_kind do |t, args|
181   - release_kind = args[:release_kind] || 'stable'
  179 + task :release, :target do |t, args|
  180 + target = args[:target]
  181 + if ! target
  182 + abort "Usage: rake noosfero:release[TARGET]"
  183 + end
  184 +
  185 + puts "==> Checking required packages"
  186 + Rake::Task['noosfero:check_release_deps'].invoke
182 187  
183 188 puts "==> Updating authors..."
184 189 Rake::Task['noosfero:authors'].invoke
185 190  
186   - Rake::Task['noosfero:set_version'].invoke(release_kind)
187   -
188   - puts "==> Checking tags..."
189   - Rake::Task['noosfero:check_tag'].invoke
190   -
191   - puts "==> Checking debian package version..."
192   - Rake::Task['noosfero:check_debian_package'].invoke
193   -
194 191 puts "==> Checking translations..."
195 192 Rake::Task['noosfero:error-pages:translate'].invoke
196 193 if !pendencies_on_public_errors[:ok]
197 194 commit_changes(['public/500.html', 'public/503.html'], 'Updating public error pages')
198 195 end
199 196  
  197 + Rake::Task['noosfero:set_version'].invoke(target)
  198 +
  199 + puts "==> Checking tags..."
  200 + Rake::Task['noosfero:check_tag'].invoke
  201 +
200 202 puts "==> Checking repository..."
201 203 Rake::Task['noosfero:check_repo'].invoke
202 204  
203 205 puts "==> Preparing debian packages..."
204 206 Rake::Task['noosfero:debian_packages'].invoke
205   - if confirm('Do you want to upload the packages')
206   - puts "==> Uploading debian packages..."
207   - Rake::Task['noosfero:upload_packages'].invoke(release_kind)
208   - end
209 207  
210   - sh "git tag #{version.gsub('~','-')}"
211   - push_tags = confirm('Push new version tag')
212   - if push_tags
  208 + sh "git tag #{$version.gsub('~','-')}"
  209 + if confirm('Push new version tag')
213 210 repository = ask('Repository name', 'origin')
214 211 puts "==> Uploading tags..."
215   - sh "git push #{repository} #{version.gsub('~','-')}"
  212 + sh "git push #{repository} #{$version.gsub('~','-')}"
216 213 end
217 214  
218   - sh "rm tmp/pending-release" if Dir["tmp/pending-release"].first.present?
  215 + if confirm('Do you want to upload the packages')
  216 + puts "==> Uploading debian packages..."
  217 + Rake::Task['noosfero:upload_packages'].invoke(target)
  218 + else
  219 + puts "I: please upload the package manually!"
  220 + end
219 221  
220   - puts "I: please upload the tarball and Debian packages to the website!"
221   - puts "I: please push the tag for version #{version} that was just created!" if !push_tags
222   - puts "I: notify the community about this sparkling new version!"
  222 + rm_f "rm tmp/pending-release"
223 223 end
224 224  
225 225 desc 'Build Debian packages'
226 226 task :debian_packages => :package do
227   - target = "pkg/noosfero-#{Noosfero::VERSION}"
  227 + target = "pkg/noosfero-#{$version}"
228 228  
229 229 # base pre-config
230 230 mkdir "#{target}/tmp"
... ... @@ -240,7 +240,7 @@ EOF
240 240 desc 'Test Debian package'
241 241 task 'debian:test' => :debian_packages do
242 242 Dir.chdir 'pkg' do
243   - rm_rf "noosfero-#{Noosfero::VERSION}"
  243 + rm_rf "noosfero-#{$version}"
244 244 sh 'apt-ftparchive packages . > Packages'
245 245 sh 'apt-ftparchive release . > Release'
246 246 end
... ...
lib/tasks/translation.rake
... ... @@ -5,7 +5,7 @@ namespace :noosfero do
5 5 task :update => ['updatepo', 'noosfero:doc:rebuild']
6 6  
7 7 desc 'Compiles all translations'
8   - task :compile => ['makemo', 'noosfero:doc:translate']
  8 + task :compile => ['makemo', 'environment', 'noosfero:doc:translate']
9 9  
10 10 end
11 11 end
... ...
plugins/community_track/lib/community_track_plugin/track_helper.rb
1 1 module CommunityTrackPlugin::TrackHelper
2 2  
  3 + include CategoriesHelper
  4 +
3 5 def category_class(track)
4 6 'category_' + (track.categories.empty? ? 'not_defined' : track.categories.first.name.to_slug)
5 7 end
... ... @@ -9,4 +11,13 @@ module CommunityTrackPlugin::TrackHelper
9 11 excerpt(lead_stripped, lead_stripped.first(3), track.image ? 180 : 300)
10 12 end
11 13  
  14 + def track_color_style(track)
  15 + category_color_style(track.categories.first.with_color) if !track.categories.empty?
  16 + end
  17 +
  18 + def track_name_color_style(track)
  19 + category = track.categories.empty? ? nil : track.categories.first.with_color
  20 + category ? "color: ##{category.display_color};" : ''
  21 + end
  22 +
12 23 end
... ...
plugins/community_track/test/unit/community_track_plugin/track_helper_test.rb
... ... @@ -52,4 +52,16 @@ class TrackHelperTest &lt; ActiveSupport::TestCase
52 52 assert_equal 186, track_card_lead(@track).length
53 53 end
54 54  
  55 + should 'return category color if its defined' do
  56 + category1 = fast_create(Category, :name => 'education', :display_color => 'fbfbfb')
  57 + @track.categories << category1
  58 + assert_equal 'background-color: #fbfbfb;', track_color_style(@track)
  59 + end
  60 +
  61 + should 'return category color for track name' do
  62 + category1 = fast_create(Category, :name => 'education', :display_color => 'fbfbfb')
  63 + @track.categories << category1
  64 + assert_equal 'color: #fbfbfb;', track_name_color_style(@track)
  65 + end
  66 +
55 67 end
... ...
plugins/community_track/views/blocks/_track_card.html.erb
... ... @@ -2,13 +2,13 @@
2 2 <div class="item_card <%= category_class(track_card) %>">
3 3 <a href="<%= url_for track_card.url %>">
4 4 <div class="track_content">
5   - <div class="title">
  5 + <div class="title" style="<%= track_color_style(track_card) %>">
6 6 <%= track_card.category_name %>
7 7 </div>
8 8 <div class="image">
9 9 <%= image_tag track_card.image.public_filename if track_card.image %>
10 10 </div>
11   - <div class="name">
  11 + <div class="name" style="<%= track_name_color_style(track_card) %>">
12 12 <%= track_card.name %>
13 13 </div>
14 14 <div class="lead">
... ...
plugins/custom_forms/controllers/custom_forms_plugin_myprofile_controller.rb
... ... @@ -65,10 +65,8 @@ class CustomFormsPluginMyprofileController &lt; MyProfileController
65 65  
66 66 def submissions
67 67 @form = CustomFormsPlugin::Form.find(params[:id])
68   - @submissions = @form.submissions
69   -
70   - @sort_by = params[:sort_by]
71   - @submissions = @submissions.sort_by { |s| s.profile.present? ? s.profile.name : s.author_name } if @sort_by == 'author'
  68 + @sort_by = params[:sort_by] == 'author_name' ? 'author_name' : 'created_at'
  69 + @submissions = @form.submissions.order(@sort_by)
72 70  
73 71 respond_to do |format|
74 72 format.html
... ...
plugins/custom_forms/controllers/custom_forms_plugin_profile_controller.rb
... ... @@ -6,40 +6,26 @@ class CustomFormsPluginProfileController &lt; ProfileController
6 6  
7 7 @form = CustomFormsPlugin::Form.find(params[:id])
8 8 if user
9   - @submission ||= CustomFormsPlugin::Submission.find_by_form_id_and_profile_id(@form.id,user.id)
  9 + @submission = CustomFormsPlugin::Submission.find_by_form_id_and_profile_id(@form.id,user.id)
10 10 @submission ||= CustomFormsPlugin::Submission.new(:form => @form, :profile => user)
11 11 else
12   - @submission ||= CustomFormsPlugin::Submission.new(:form => @form)
  12 + @submission = CustomFormsPlugin::Submission.new(:form => @for)
13 13 end
14 14  
15 15 # build the answers
16   - @submission.answers.push(*(answers = build_answers(params[:submission], @form))) if params[:submission]
  16 + @answers = if params[:submission] then @submission.build_answers params[:submission] else @submission.answers end
17 17  
18 18 if request.post?
19 19 begin
20 20 raise 'Submission already present!' if user.present? && CustomFormsPlugin::Submission.find_by_form_id_and_profile_id(@form.id,user.id)
21 21 raise 'Form expired!' if @form.expired?
22 22  
23   - # @submission.answers for some reason has the same answer twice
24   - failed_answers = answers.select {|answer| !answer.valid? }
25   -
26   - if failed_answers.empty?
27   - # Save the submission
28   - ActiveRecord::Base.transaction do
29   - if !user
30   - @submission.author_name = params[:author_name]
31   - @submission.author_email = params[:author_email]
32   - end
33   - @submission.save!
34   - end
35   - else
36   - @submission.errors.clear
37   - failed_answers.each do |answer|
38   - answer.valid?
39   - answer.errors.each do |attribute, msg|
40   - @submission.errors.add(answer.field.id.to_s.to_sym, msg)
41   - end
42   - end
  23 + if !user
  24 + @submission.author_name = params[:author_name]
  25 + @submission.author_email = params[:author_email]
  26 + end
  27 +
  28 + if not @submission.save
43 29 raise 'Submission failed: answers not valid'
44 30 end
45 31 session[:notice] = _('Submission saved')
... ...
plugins/custom_forms/db/migrate/20131107125327_add_admission_to_form.rb
... ... @@ -4,10 +4,7 @@ class AddAdmissionToForm &lt; ActiveRecord::Migration
4 4 t.boolean :for_admission, :default => false
5 5 end
6 6  
7   - CustomFormsPlugin::Form.find_each do |f|
8   - f.for_admission = false
9   - f.save!
10   - end
  7 + execute('update custom_forms_plugin_forms set for_admission = (1<0)')
11 8 end
12 9  
13 10 def self.down
... ...