Commit affef2cf3d8ca5cfecef23accfb78ee2b8e7e50b

Authored by Carlos Purificação
2 parents 4f7106d9 d8741207

Merge remote-tracking branch 'origin/staging' into login-captcha

Conflicts:
	lib/noosfero/api/v1/articles.rb
Showing 1851 changed files with 325492 additions and 98930 deletions   Show diff stats

Too many changes.

To preserve performance only 100 of 1851 files displayed.

.gitlab-ci.yml
1 1 before_script:
2   - - mkdir -p tmp/pids log
  2 + - mkdir -p tmp/{pids,cache} log
3 3 - bundle check || bundle install
4 4 # workaround for plugins with Gemfile
5 5 - perl -pi -e 's/--local //' script/noosfero-plugins
... ...
.gitmodules
1 1 [submodule "plugins/pairwise"]
2 2 path = plugins/pairwise
3   - url = https://gitlab.com/noosfero-plugins/pairwise.git
  3 + url = https://softwarepublico.gov.br/gitlab/noosfero-plugins/pairwise.git
4 4 [submodule "plugins/proposals_discussion"]
5 5 path = plugins/proposals_discussion
6   - url = https://gitlab.com/noosfero-plugins/proposals_discussion.git
  6 + url = https://softwarepublico.gov.br/gitlab/noosfero-plugins/proposals_discussion.git
7 7 [submodule "plugins/gamification"]
8 8 path = plugins/gamification
9   - url = https://gitlab.com/noosfero-plugins/gamification.git
10   -[submodule "plugins/comment_paragraph"]
11   - path = plugins/comment_paragraph
12   - url = https://gitlab.com/noosfero-plugins/comment-paragraph.git
  9 + url = https://softwarepublico.gov.br/gitlab/noosfero-plugins/gamification.git
13 10 [submodule "plugins/notification"]
14 11 path = plugins/notification
15   - url = https://gitlab.com/noosfero-plugins/notification.git
  12 + url = https://softwarepublico.gov.br/gitlab/noosfero-plugins/notification.git
16 13 [submodule "plugins/email_article"]
17 14 path = plugins/email_article
18   - url = https://gitlab.com/noosfero-plugins/email_article.git
  15 + url = https://softwarepublico.gov.br/gitlab/noosfero-plugins/email_article.git
19 16 [submodule "public/proposal-app"]
20 17 path = public/proposal-app
21 18 url = https://gitlab.com/participa/proposal-app.git
22 19 [submodule "plugins/gravatar_provider"]
23 20 path = plugins/gravatar_provider
24   - url = https://gitlab.com/noosfero-plugins/gravatar-provider.git
  21 + url = https://softwarepublico.gov.br/gitlab/noosfero-plugins/gravatar-provider.git
25 22 [submodule "plugins/juventude"]
26 23 path = plugins/juventude
27   - url = https://gitlab.com/noosfero-plugins/juventude.git
  24 + url = https://softwarepublico.gov.br/gitlab/noosfero-plugins/juventude.git
28 25 [submodule "plugins/dialoga"]
29 26 path = plugins/dialoga
30   - url = https://gitlab.com/participa/dialoga-plugin.git
  27 + url = https://softwarepublico.gov.br/gitlab/noosfero-plugins/dialoga-plugin.git
31 28 [submodule "rest-clients/confjuvapp"]
32 29 path = rest-clients/confjuvapp
33   - url = https://gitlab.com/participa/confjuvapp.git
  30 + url = https://softwarepublico.gov.br/gitlab/noosfero-apps/confjuvapp.git
34 31 [submodule "rest-clients/proposal-app"]
35 32 path = rest-clients/proposal-app
36   - url = https://gitlab.com/participa/proposal-app.git
  33 + url = https://softwarepublico.gov.br/gitlab/noosfero-apps/proposal-app.git
  34 +[submodule "plugins/serpro_captcha"]
  35 + path = plugins/serpro_captcha
  36 + url = https://softwarepublico.gov.br/gitlab/noosfero-plugins/serpro_captcha.git
... ...
.travis.yml
  1 +notifications:
  2 + irc:
  3 + channels:
  4 + - "chat.freenode.net#noosfero"
  5 + - "chat.freenode.net#noosfero-br"
  6 + template:
  7 + - "%{repository_slug} %{branch} %{commit} %{commit_subject} - %{result} %{build_url}"
  8 +
1 9 language: ruby
2 10 rvm:
3 11 # for 2.2 support we need to upgrade the pg gem
... ... @@ -28,10 +36,7 @@ before_install:
28 36 cache: bundler
29 37  
30 38 before_script:
31   - - mkdir -p tmp/pids log
32   -# workaround for plugins with Gemfile
33   - - perl -pi -e 's/cat .+ > \$gemfile/echo "source \\"https:\/\/rubygems.org\\"" > \$gemfile && cat \$source\/Gemfile >> \$gemfile/' script/noosfero-plugins
34   - - perl -pi -e 's/--local --quiet/install --jobs=3 --retry=3/' script/noosfero-plugins
  39 + - mkdir -p tmp/{pids,cache} log
35 40 - script/noosfero-plugins disableall
36 41 - bundle exec rake makemo &>/dev/null
37 42 # database
... ... @@ -46,7 +51,7 @@ env:
46 51 - TASK=test:integration
47 52 - TASK=cucumber
48 53 - TASK=selenium
49   - - TASK=test:noosfero_plugins
  54 + - TASK=test:noosfero_plugins BUNDLE_OPTS=install
50 55  
51 56 script:
52 57 - bundle exec rake $TASK
... ...
AUTHORS.md
... ... @@ -11,6 +11,7 @@ Developers
11 11 Ábner Silva de Oliveira <abner.oliveira@serpro.gov.br>
12 12 Alan Freihof Tygel <alantygel@gmail.com>
13 13 Alessandro Palmeira <alessandro.palmeira@gmail.com>
  14 +Alexandre Torres <alexandrekry@gmail.com>
14 15 Alex Campelo <campelo.al1@gmail.com>
15 16 Álvaro Fernando <alvarofernandoms@gmail.com>
16 17 Ana Losnak <analosnak@gmail.com>
... ... @@ -63,6 +64,7 @@ Isaac Canan &lt;isaac@intelletto.com.br&gt;
63 64 Italo Valcy <italo@dcc.ufba.br>
64 65 Jefferson Fernandes <jeffs.fernandes@gmail.com>
65 66 Jérôme Jutteau <j.jutteau@gmail.com>
  67 +Jéssica Cristina <jessica.cris1127@gmail.com>
66 68 João Machini
67 69 João M. M. da Silva <jaodsilv@linux.ime.usp.br>
68 70 Joenio Costa <joenio@colivre.coop.br>
... ... @@ -82,23 +84,27 @@ Luciano Prestes Cavalcanti &lt;lucianopcbr@gmail.com&gt;
82 84 Luis David Aguilar Carlos <ludwig9003@gmail.com>
83 85 Luiz Fernando de Freitas Matos <luiz@luizff.matos@gmail.com>
84 86 Luiz Matos <luizff.matos@gmail.com>
  87 +Marcelo Júnior <maljunior@gmail.com>
85 88 Marcos Ramos <ms.ramos@outlook.com>
86 89 Marcos Ronaldo <marcos.rpj2@gmail.com>
87 90 Mariel Zasso <noosfero-br@listas.softwarelivre.org>
88 91 Martín Olivera <molivera@solar.org.ar>
89 92 Matheus Faria <matheus.sousa.faria@gmail.com>
90 93 Maurilio Atila <cabelotaina@gmail.com>
  94 +Melissa Wen <melissa@colivre.coop.br>
91 95 M for Momo <mo@rtnp.org>
92 96 Michal Čihař <michal@cihar.com>
93   -Michel Felipe <mfelipeof@gmail.com>
  97 +Michel Felipe de Oliveira Ferreira <michel.ferreira@serpro.gov.br>
94 98 Moises Machado <moises@colivre.coop.br>
95 99 Naíla Alves <naila@colivre.coop.br>
96 100 Nanda Lopes <nanda.listas+psl@gmail.com>
97 101 Niemand Jedermann <predatorix@web.de>
  102 +Omar Junior <omarroinuj@gmail.com>
98 103 Parley Martins <parleypachecomartins@gmail.com>
99 104 Paulo Meirelles <paulo@softwarelivre.org>
100 105 Pedro de Lyra <pedrodelyra@gmail.com>
101 106 Pedro Leal
  107 +Phillip Rohmberger <rohmberger@hotmail.de>
102 108 Rafael de Souza Queiroz <querafael@live.com>
103 109 Rafael Gomes <rafaelgomes@techfree.com.br>
104 110 Rafael Martins <rmmartins@gmail.com>
... ... @@ -110,8 +116,10 @@ Renan Costa &lt;renan2727@hotmail.com&gt;
110 116 Renan Teruo <renanteruoc@gmail.com>
111 117 Rodrigo Medeiros <rodrigo.mss01@gmail.com>
112 118 Rodrigo Souto <rodrigo@colivre.coop.br>
  119 +Ronnie Simon <ronniesimonf@gmail.com>
113 120 Ronny Kursawe <kursawe.ronny@googlemail.com>
114 121 Samuel R. C. Vale <srcvale@holoscopio.com>
  122 +Simião Carvalho <simiaosimis@gmail.com>
115 123 Tallys Martins <tallysmartins@yahoo.com.br>
116 124 Thiago Casotti <thiago.casotti@uol.com.br>
117 125 Thiago Kairala <thiagor.kairala@gmail.com>
... ... @@ -122,7 +130,9 @@ TWS &lt;tablettws@gmail.com&gt;
122 130 Valessio Brito <contato@valessiobrito.com.br>
123 131 Victor Costa <vfcosta@gmail.com>
124 132 Victor Hugo Alves de Carvalho <victorhugodf.ac@gmail.com>
  133 +Victor Navarro <victor.matias.navarro@gmail.com>
125 134 Vinicius Cubas Brand <viniciuscb@gmail.com>
  135 +Vitor Barbosa <vitornga15@gmail.com>
126 136 Wilton Rodrigues <braynwilton@gmail.com>
127 137 Yann Lugrin <yann.lugrin@liquid-concept.ch>
128 138  
... ...
Gemfile
... ... @@ -10,8 +10,10 @@ gem &#39;RedCloth&#39;, &#39;~&gt; 4.2.9&#39;
10 10 gem 'will_paginate', '~> 3.0.3'
11 11 gem 'ruby-feedparser', '~> 0.7'
12 12 gem 'daemons', '~> 1.1.5'
13   -gem 'thin', '~> 1.3.1'
  13 +#gem 'thin', '~> 1.3.1'
14 14 gem 'nokogiri', '~> 1.6.0'
  15 +gem 'unicorn', '~> 4.8'
  16 +#gem 'nokogiri', '~> 1.5.5'
15 17 gem 'rake', :require => false
16 18 gem 'rest-client', '~> 1.6.7'
17 19 gem 'exception_notification', '~> 4.0.1'
... ... @@ -30,6 +32,7 @@ gem &#39;kramdown&#39;
30 32 #FIXME Get the Grape Loggin from master yo solve this issue https://github.com/intridea/grape/issues/1059
31 33 #We have to remove this commit referenve code when update the next release of grape_logging. Actualy we are using (1.1.2)
32 34 gem 'grape_logging', :git => 'https://github.com/aceunreal/grape_logging.git', :ref => 'f1755ae'
  35 +#gem 'grape_logging'
33 36 gem 'rack-cors'
34 37 gem 'rack-contrib'
35 38 gem 'liquid', '~> 3.0.3'
... ... @@ -47,6 +50,7 @@ gem &#39;api-pagination&#39;, &#39;~&gt; 4.1.1&#39;
47 50 # asset pipeline
48 51 gem 'uglifier', '>= 1.0.3'
49 52 gem 'sass-rails'
  53 +gem 'sass', '~> 3.1.19'
50 54  
51 55 group :production do
52 56 gem 'dalli', '~> 2.7.0'
... ... @@ -63,7 +67,7 @@ group :cucumber do
63 67 gem 'capybara', '~> 2.1.0'
64 68 gem 'cucumber', '~> 1.0.6'
65 69 gem 'database_cleaner', '~> 1.2.0'
66   - gem 'selenium-webdriver', '~> 2.39.0'
  70 + gem 'selenium-webdriver', '~> 2.47.0'
67 71 end
68 72  
69 73 # Requires custom dependencies
... ...
Gemfile.lock
... ... @@ -73,16 +73,15 @@ GEM
73 73 descendants_tracker (0.0.4)
74 74 thread_safe (~> 0.3, >= 0.3.1)
75 75 diff-lcs (1.2.5)
76   - eita-jrails (0.9.5)
77   - actionpack (~> 3.2, >= 3.1.0)
78   - activesupport (~> 3.2, >= 3.0.0)
  76 + eita-jrails (0.9.8)
  77 + actionpack (>= 3.1.0)
  78 + activesupport (>= 3.0.0)
79 79 equalizer (0.0.11)
80 80 erubis (2.7.0)
81   - eventmachine (1.0.7)
82 81 exception_notification (4.0.1)
83 82 actionmailer (>= 3.0.4)
84 83 activesupport (>= 3.0.4)
85   - execjs (2.5.2)
  84 + execjs (2.6.0)
86 85 fast_gettext (0.6.12)
87 86 ffi (1.9.10)
88 87 gettext (2.2.1)
... ... @@ -90,7 +89,7 @@ GEM
90 89 gherkin (2.4.21)
91 90 json (>= 1.4.6)
92 91 git-version-bump (0.15.1)
93   - grape (0.12.0)
  92 + grape (0.13.0)
94 93 activesupport
95 94 builder
96 95 hashie (>= 2.1.0)
... ... @@ -100,19 +99,20 @@ GEM
100 99 rack-accept
101 100 rack-mount
102 101 virtus (>= 1.0.0)
103   - grape-entity (0.4.5)
  102 + grape-entity (0.4.8)
104 103 activesupport
105 104 multi_json (>= 1.3.2)
106 105 grape-swagger (0.10.2)
107 106 grape (>= 0.8.0)
108 107 grape-entity
109   - hashie (2.1.2)
  108 + hashie (3.4.2)
110 109 hike (1.2.3)
111 110 i18n (0.7.0)
112 111 ice_nine (0.11.1)
113 112 journey (1.0.4)
114 113 json (1.8.3)
115   - kramdown (1.8.0)
  114 + kgio (2.10.0)
  115 + kramdown (1.9.0)
116 116 libv8 (3.16.14.11)
117 117 liquid (3.0.6)
118 118 locale (2.0.9)
... ... @@ -136,9 +136,9 @@ GEM
136 136 rack (1.4.7)
137 137 rack-accept (0.4.5)
138 138 rack (>= 0.4)
139   - rack-cache (1.2)
  139 + rack-cache (1.5.0)
140 140 rack (>= 0.4)
141   - rack-contrib (1.3.0)
  141 + rack-contrib (1.4.0)
142 142 git-version-bump (~> 0.15)
143 143 rack (~> 1.4)
144 144 rack-cors (0.4.0)
... ... @@ -165,6 +165,7 @@ GEM
165 165 rake (>= 0.8.7)
166 166 rdoc (~> 3.4)
167 167 thor (>= 0.14.6, < 2.0)
  168 + raindrops (0.15.0)
168 169 rake (10.4.2)
169 170 rdoc (3.12.2)
170 171 json (~> 1.4)
... ... @@ -191,16 +192,16 @@ GEM
191 192 ruby-feedparser (0.9.3)
192 193 magic
193 194 rubyzip (1.1.7)
194   - sass (3.4.15)
  195 + sass (3.1.21)
195 196 sass-rails (3.2.6)
196 197 railties (~> 3.2.0)
197 198 sass (>= 3.1.10)
198 199 tilt (~> 1.3)
199   - selenium-webdriver (2.39.0)
200   - childprocess (>= 0.2.5)
  200 + selenium-webdriver (2.47.1)
  201 + childprocess (~> 0.5)
201 202 multi_json (~> 1.0)
202 203 rubyzip (~> 1.0)
203   - websocket (~> 1.0.4)
  204 + websocket (~> 1.0)
204 205 sprockets (2.2.3)
205 206 hike (~> 1.2)
206 207 multi_json (~> 1.0)
... ... @@ -212,27 +213,27 @@ GEM
212 213 therubyracer (0.12.2)
213 214 libv8 (~> 3.16.14.0)
214 215 ref
215   - thin (1.3.1)
216   - daemons (>= 1.0.9)
217   - eventmachine (>= 0.12.6)
218   - rack (>= 1.0.0)
219 216 thor (0.19.1)
220 217 thread_safe (0.3.5)
221 218 tilt (1.4.1)
222   - tins (1.5.4)
  219 + tins (1.6.0)
223 220 treetop (1.4.15)
224 221 polyglot
225 222 polyglot (>= 0.3.1)
226   - tzinfo (0.3.44)
227   - uglifier (2.7.1)
  223 + tzinfo (0.3.45)
  224 + uglifier (2.7.2)
228 225 execjs (>= 0.3.0)
229 226 json (>= 1.8.0)
  227 + unicorn (4.9.0)
  228 + kgio (~> 2.6)
  229 + rack
  230 + raindrops (~> 0.7)
230 231 virtus (1.0.5)
231 232 axiom-types (~> 0.1)
232 233 coercible (~> 1.0)
233 234 descendants_tracker (~> 0.0, >= 0.0.3)
234 235 equalizer (~> 0.0, >= 0.0.9)
235   - websocket (1.0.7)
  236 + websocket (1.2.2)
236 237 whenever (0.9.4)
237 238 chronic (>= 0.6.3)
238 239 will_paginate (3.0.7)
... ... @@ -279,11 +280,12 @@ DEPENDENCIES
279 280 rspec-rails (~> 2.14.1)
280 281 ruby-feedparser (~> 0.7)
281 282 rubyzip
  283 + sass (~> 3.1.19)
282 284 sass-rails
283   - selenium-webdriver (~> 2.39.0)
  285 + selenium-webdriver (~> 2.47.0)
284 286 swagger-ui_rails
285 287 therubyracer
286   - thin (~> 1.3.1)
287 288 uglifier (>= 1.0.3)
  289 + unicorn (~> 4.8)
288 290 whenever
289 291 will_paginate (~> 3.0.3)
... ...
app/controllers/application_controller.rb
... ... @@ -9,7 +9,7 @@ class ApplicationController &lt; ActionController::Base
9 9 before_filter :allow_cross_domain_access
10 10  
11 11 before_filter :login_from_cookie
12   - before_filter :login_required, :if => :private_environment?
  12 + before_filter :require_login_for_environment, :if => :private_environment?
13 13  
14 14 before_filter :verify_members_whitelist, :if => [:private_environment?, :user]
15 15 before_filter :log_user
... ... @@ -19,6 +19,10 @@ class ApplicationController &lt; ActionController::Base
19 19 end
20 20 before_filter :redirect_to_current_user
21 21  
  22 + def require_login_for_environment
  23 + login_required
  24 + end
  25 +
22 26 def verify_members_whitelist
23 27 render_access_denied unless user.is_admin? || environment.in_whitelist?(user)
24 28 end
... ...
app/controllers/my_profile/cms_controller.rb
... ... @@ -27,7 +27,7 @@ class CmsController &lt; MyProfileController
27 27  
28 28 helper_method :file_types
29 29  
30   - protect_if :except => [:suggest_an_article, :set_home_page, :edit, :destroy, :publish, :upload_files, :new] do |c, user, profile|
  30 + protect_if :except => [:suggest_an_article, :set_home_page, :edit, :destroy, :publish, :publish_on_portal_community, :publish_on_communities, :search_communities_to_publish, :upload_files, :new] do |c, user, profile|
31 31 user && (user.has_permission?('post_content', profile) || user.has_permission?('publish_content', profile))
32 32 end
33 33  
... ... @@ -93,7 +93,6 @@ class CmsController &lt; MyProfileController
93 93 refuse_blocks
94 94 record_coming
95 95 if request.post?
96   - @article.image = nil if params[:remove_image] == 'true'
97 96 if @article.image.present? && params[:article][:image_builder] &&
98 97 params[:article][:image_builder][:label]
99 98 @article.image.label = params[:article][:image_builder][:label]
... ... @@ -289,7 +288,7 @@ class CmsController &lt; MyProfileController
289 288 task.cancel
290 289 end
291 290 if @failed.blank?
292   - session[:notice] = _("Your publish request was sent successfully")
  291 + session[:notice] = _("You published this content successfully")
293 292 if @back_to
294 293 redirect_to @back_to
295 294 else
... ...
app/controllers/my_profile/profile_editor_controller.rb
... ... @@ -6,10 +6,13 @@ class ProfileEditorController &lt; MyProfileController
6 6 before_filter :access_welcome_page, :only => [:welcome_page]
7 7 before_filter :back_to
8 8 before_filter :forbid_destroy_profile, :only => [:destroy_profile]
  9 + before_filter :check_user_can_edit_header_footer, :only => [:header_footer]
9 10 helper_method :has_welcome_page
10 11  
11 12 def index
12 13 @pending_tasks = Task.to(profile).pending.without_spam.select{|i| user.has_permission?(i.permission, profile)}
  14 + @show_appearance_option = user.is_admin?(environment) || environment.enabled?('enable_appearance')
  15 + @show_header_footer_option = user.is_admin?(environment) || (!profile.enterprise? && !environment.enabled?('disable_header_and_footer'))
13 16 end
14 17  
15 18 helper :profile
... ... @@ -136,6 +139,13 @@ class ProfileEditorController &lt; MyProfileController
136 139 redirect_to_previous_location
137 140 end
138 141  
  142 + def reset_private_token
  143 + profile = environment.profiles.find(params[:id])
  144 + profile.user.generate_private_token!
  145 +
  146 + redirect_to_previous_location
  147 + end
  148 +
139 149 protected
140 150  
141 151 def redirect_to_previous_location
... ... @@ -165,4 +175,9 @@ class ProfileEditorController &lt; MyProfileController
165 175 redirect_to_previous_location
166 176 end
167 177 end
  178 +
  179 + def check_user_can_edit_header_footer
  180 + user_can_not_edit_header_footer = !user.is_admin?(environment) && environment.enabled?('disable_header_and_footer')
  181 + redirect_to back_to if user_can_not_edit_header_footer
  182 + end
168 183 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, :change_password]
  5 + before_filter :login_required, :require_login_for_environment, :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  
... ... @@ -104,10 +104,8 @@ class AccountController &lt; ApplicationController
104 104 @block_bot = !!session[:may_be_a_bot]
105 105 @invitation_code = params[:invitation_code]
106 106 begin
107   - @user = User.new(params[:user])
  107 + @user = User.build(params[:user], params[:profile_data], environment)
108 108 @user.session = session
109   - @user.terms_of_use = environment.terms_of_use
110   - @user.environment = environment
111 109 @terms_of_use = environment.terms_of_use
112 110 @user.person_data = params[:profile_data]
113 111 @user.return_to = session[:return_to]
... ...
app/controllers/public/content_viewer_controller.rb
... ... @@ -12,6 +12,7 @@ class ContentViewerController &lt; ApplicationController
12 12 before_filter :sanitize_params
13 13  
14 14 def view_page
  15 +
15 16 path = get_path(params[:page], params[:format])
16 17  
17 18 @version = params[:version].to_i
... ... @@ -42,7 +43,10 @@ class ContentViewerController &lt; ApplicationController
42 43 end
43 44  
44 45 # At this point the page will be showed
45   - @page.hit unless user_is_a_bot?
  46 +
  47 + unless user_is_a_bot? || already_visited?(@page)
  48 + Noosfero::Scheduler::Defer.later{ @page.hit }
  49 + end
46 50  
47 51 @page = FilePresenter.for @page
48 52  
... ... @@ -276,4 +280,18 @@ class ContentViewerController &lt; ApplicationController
276 280 @comment_order = params[:comment_order].nil? ? 'oldest' : params[:comment_order]
277 281 end
278 282  
  283 + private
  284 +
  285 + def already_visited?(element)
  286 + user_id = if user.nil? then -1 else current_user.id end
  287 + user_id = "#{user_id}_#{element.id}_#{element.class}"
  288 +
  289 + if cookies.signed[:visited] == user_id
  290 + return true
  291 + else
  292 + cookies.permanent.signed[:visited] = user_id
  293 + return false
  294 + end
  295 + end
  296 +
279 297 end
... ...
app/controllers/public/profile_controller.rb
... ... @@ -66,7 +66,10 @@ class ProfileController &lt; PublicController
66 66  
67 67 def members
68 68 if is_cache_expired?(profile.members_cache_key(params))
69   - @members = profile.members_by_name.includes(relations_to_include).paginate(:per_page => members_per_page, :page => params[:npage], :total_entries => profile.members.count)
  69 + sort = (params[:sort] == 'desc') ? params[:sort] : 'asc'
  70 + @profile_admins = profile.admins.includes(relations_to_include).order("name #{sort}").paginate(:per_page => members_per_page, :page => params[:npage])
  71 + @profile_members = profile.members.includes(relations_to_include).order("name #{sort}").paginate(:per_page => members_per_page, :page => params[:npage])
  72 + @profile_members_url = url_for(:controller => 'profile', :action => 'members')
70 73 end
71 74 end
72 75  
... ...
app/controllers/public/search_controller.rb
... ... @@ -180,22 +180,24 @@ class SearchController &lt; PublicController
180 180 end
181 181 end
182 182  
183   - AVAILABLE_SEARCHES = ActiveSupport::OrderedHash[
184   - :articles, _('Contents'),
185   - :people, _('People'),
186   - :communities, _('Communities'),
187   - :enterprises, _('Enterprises'),
188   - :products, _('Products and Services'),
189   - :events, _('Events'),
190   - ]
  183 + def available_searches
  184 + @available_searches ||= ActiveSupport::OrderedHash[
  185 + :articles, _('Contents'),
  186 + :people, _('People'),
  187 + :communities, _('Communities'),
  188 + :enterprises, _('Enterprises'),
  189 + :products, _('Products and Services'),
  190 + :events, _('Events'),
  191 + ]
  192 + end
191 193  
192 194 def load_search_assets
193   - if AVAILABLE_SEARCHES.keys.include?(params[:action].to_sym) && environment.enabled?("disable_asset_#{params[:action]}")
  195 + if available_searches.keys.include?(params[:action].to_sym) && environment.enabled?("disable_asset_#{params[:action]}")
194 196 render_not_found
195 197 return
196 198 end
197 199  
198   - @enabled_searches = AVAILABLE_SEARCHES.select {|key, name| environment.disabled?("disable_asset_#{key}") }
  200 + @enabled_searches = available_searches.select {|key, name| environment.disabled?("disable_asset_#{key}") }
199 201 @searching = {}
200 202 @titles = {}
201 203 @enabled_searches.each do |key, name|
... ... @@ -207,7 +209,7 @@ class SearchController &lt; PublicController
207 209  
208 210 def load_order
209 211 @order = 'more_recent'
210   - if AVAILABLE_SEARCHES.keys.include?(@asset.to_sym)
  212 + if available_searches.keys.include?(@asset.to_sym)
211 213 available_orders = asset_class(@asset)::SEARCH_FILTERS[:order]
212 214 @order = params[:order] if available_orders.include?(params[:order])
213 215 end
... ...
app/controllers/themes_controller.rb
1 1 class ThemesController < ApplicationController
2 2  
3 3 before_filter :login_required
  4 + before_filter :check_user_can_edit_appearance, :only => [:index]
4 5  
5 6 no_design_blocks
6 7  
... ... @@ -39,4 +40,11 @@ class ThemesController &lt; ApplicationController
39 40 redirect_to :action => 'index'
40 41 end
41 42  
  43 + private
  44 +
  45 + def check_user_can_edit_appearance
  46 + user_can_edit_appearance = user.is_admin?(environment) || environment.enabled?('enable_appearance')
  47 + redirect_to request.referer || "/" unless user_can_edit_appearance
  48 + end
  49 +
42 50 end
... ...
app/helpers/action_tracker_helper.rb
... ... @@ -67,19 +67,19 @@ module ActionTrackerHelper
67 67 }
68 68 end
69 69  
70   - def create_product_description
  70 + def create_product_description ta
71 71 _('created the product %{title}') % {
72 72 title: link_to(truncate(ta.get_name), ta.get_url),
73 73 }
74 74 end
75 75  
76   - def update_product_description
  76 + def update_product_description ta
77 77 _('updated the product %{title}') % {
78 78 title: link_to(truncate(ta.get_name), ta.get_url),
79 79 }
80 80 end
81 81  
82   - def remove_product_description
  82 + def remove_product_description ta
83 83 _('removed the product %{title}') % {
84 84 title: truncate(ta.get_name),
85 85 }
... ...
app/helpers/application_helper.rb
... ... @@ -727,10 +727,10 @@ module ApplicationHelper
727 727 javascript_include_tag script if script
728 728 end
729 729  
730   - def file_field_or_thumbnail(label, image, i)
  730 + def file_field_or_thumbnail(label, image, i, removable = true)
731 731 display_form_field label, (
732 732 render :partial => (image && image.valid? ? 'shared/show_thumbnail' : 'shared/change_image'),
733   - :locals => { :i => i, :image => image }
  733 + :locals => { :i => i, :image => image, :removable => removable }
734 734 )
735 735 end
736 736  
... ... @@ -1133,7 +1133,7 @@ module ApplicationHelper
1133 1133 alias :browse_communities_menu :search_communities_menu
1134 1134  
1135 1135 def pagination_links(collection, options={})
1136   - options = {:previous_label => '&laquo; ' + _('Previous'), :next_label => _('Next') + ' &raquo;'}.merge(options)
  1136 + options = {:previous_label => content_tag(:span, '&laquo; ', :class => 'previous-arrow') + _('Previous'), :next_label => _('Next') + content_tag(:span, ' &raquo;', :class => 'next-arrow'), :inner_window => 1, :outer_window => 0 }.merge(options)
1137 1137 will_paginate(collection, options)
1138 1138 end
1139 1139  
... ... @@ -1319,7 +1319,12 @@ module ApplicationHelper
1319 1319 options[:class] = (options[:class] || '') + ' disabled'
1320 1320 content_tag('a', '&nbsp;'+content_tag('span', content), options)
1321 1321 else
1322   - link_to content, url, options
  1322 + if options[:modal]
  1323 + options.delete(:modal)
  1324 + modal_link_to content, url, options
  1325 + else
  1326 + link_to content, url, options
  1327 + end
1323 1328 end
1324 1329 end
1325 1330  
... ...
app/helpers/article_helper.rb
... ... @@ -15,6 +15,13 @@ module ArticleHelper
15 15 topic_creation(@article) +
16 16 content_tag('h4', _('Options')) +
17 17 content_tag('div',
  18 + content_tag('div',
  19 + check_box(:article, :archived) +
  20 + content_tag('span', '&nbsp;', :class => 'access-archived-icon') +
  21 + content_tag('label', _('Read Only'), :for => 'article_archived_true') +
  22 + content_tag('span', _('Archive to avoid create comments, votes, actions in children articles...'), :class => 'access-note'),
  23 + :class => 'access-item'
  24 + ) +
18 25 (article.profile.has_members? ?
19 26 content_tag(
20 27 'div',
... ... @@ -23,13 +30,11 @@ module ArticleHelper
23 30 ) :
24 31 '') +
25 32  
26   - (article.parent && article.parent.forum? && controller.action_name == 'new' ?
27   - hidden_field_tag('article[accept_comments]', 1) :
28 33 content_tag(
29 34 'div',
30 35 check_box(:article, :accept_comments) +
31 36 content_tag('label', (article.parent && article.parent.forum? ? _('This topic is opened for replies') : _('I want to receive comments about this article')), :for => 'article_accept_comments')
32   - )) +
  37 + ) +
33 38  
34 39 content_tag(
35 40 'div',
... ... @@ -65,13 +70,20 @@ module ArticleHelper
65 70 content_tag('div',
66 71 content_tag('div',
67 72 radio_button(:article, :published, true) +
68   - content_tag('label', _('Public (visible to other people)'), :for => 'article_published_true')
  73 + content_tag('span', '&nbsp;', :class => 'access-public-icon') +
  74 + content_tag('label', _('Public'), :for => 'article_published_true') +
  75 + content_tag('span', _('Visible to other people'), :class => 'access-note'),
  76 + :class => 'access-item'
69 77 ) +
70 78 content_tag('div',
71 79 radio_button(:article, :published, false) +
72   - content_tag('label', _('Private'), :for => 'article_published_false', :id => "label_private")
  80 + content_tag('span', '&nbsp;', :class => 'access-private-icon') +
  81 + content_tag('label', _('Private'), :for => 'article_published_false', :id => "label_private") +
  82 + content_tag('span', _('Limit visibility of this article'), :class => 'access-note'),
  83 + :class => 'access-item'
73 84 ) +
74   - privacity_exceptions(article, tokenized_children)
  85 + privacity_exceptions(article, tokenized_children),
  86 + :class => 'access-itens'
75 87 )
76 88 end
77 89  
... ...
app/helpers/blog_helper.rb
... ... @@ -24,10 +24,8 @@ module BlogHelper
24 24 end
25 25  
26 26 def list_posts(articles, conf = { format: 'full', paginate: true })
27   - pagination = will_paginate(articles, {
  27 + pagination = pagination_links(articles, {
28 28 :param_name => 'npage',
29   - :previous_label => _('&laquo; Newer posts'),
30   - :next_label => _('Older posts &raquo;'),
31 29 :params => {:action=>"view_page",
32 30 :page=>articles.first.parent.path.split('/'),
33 31 :controller=>"content_viewer"}
... ...
app/helpers/box_organizer_helper.rb
... ... @@ -5,14 +5,14 @@ module BoxOrganizerHelper
5 5 plugin = @plugins.fetch_first_plugin(:has_block?, block)
6 6  
7 7 theme = Theme.new(environment.theme) # remove this
8   - if File.exists?(File.join(theme.filesystem_path, 'images', block.icon_path))
9   - image_path = File.join(theme.public_path, 'images', block.icon_path)
10   - elsif plugin && File.exists?(File.join(Rails.root, 'public', plugin.public_path, 'images', block.icon_path))
11   - image_path = File.join('/', plugin.public_path, 'images', block.icon_path)
12   - elsif File.exists?(File.join(Rails.root, 'public', 'images', block.icon_path))
13   - image_path = File.join('images', block.icon_path)
  8 + if File.exists?(File.join(theme.filesystem_path, block.icon_path))
  9 + image_path = File.join(theme.public_path, block.icon_path)
  10 + elsif plugin && File.exists?(File.join(Rails.root, 'public', plugin.public_path, block.icon_path))
  11 + image_path = File.join('/', plugin.public_path, block.icon_path)
  12 + elsif File.exists?(File.join(Rails.root, 'public', block.icon_path))
  13 + image_path = block.icon_path
14 14 else
15   - image_path = File.join('images', block.default_icon_path)
  15 + image_path = block.default_icon_path
16 16 end
17 17  
18 18 image_tag(image_path, height: '48', width: '48', class: 'block-type-icon', alt: '' )
... ... @@ -33,7 +33,7 @@ module BoxOrganizerHelper
33 33 images_path = Dir.glob(File.join(Rails.root, 'public', 'images', block.preview_path, '*')) if images_path.empty?
34 34 images_path = images_path.map{|path| path.gsub(File.join(Rails.root, 'public'), '') } unless images_path.empty?
35 35  
36   - images_path = 1.upto(3).map{File.join('images', block.default_preview_path)} if images_path.empty?
  36 + images_path = 1.upto(3).map{block.default_preview_path} if images_path.empty?
37 37  
38 38 content_tag(:ul,
39 39 images_path.map do |preview|
... ...
app/helpers/boxes_helper.rb
... ... @@ -190,7 +190,7 @@ module BoxesHelper
190 190 else
191 191 "before-block-#{block.id}"
192 192 end
193   - if block.nil? || movable?(block)
  193 + if block.nil? or movable?(block)
194 194 url = url_for(:action => 'move_block', :target => id)
195 195 content_tag('div', _('Drop Here'), :id => id, :class => 'block-target' ) + drop_receiving_element(id, :accept => box.acceptable_blocks, :hoverclass => 'block-target-hover', :activeClass => 'block-target-active', :tolerance => 'pointer', :onDrop => "function(ev, ui) { dropBlock('#{url}', '#{_('loading...')}', ev, ui);}")
196 196 else
... ...
app/helpers/cms_helper.rb
... ... @@ -9,11 +9,6 @@ module CmsHelper
9 9 mime_type.gsub('/', '_').gsub('-', '')
10 10 end
11 11  
12   - def pagination_links(collection, options={})
13   - options = {:previous_label => '&laquo; ', :next_label => ' &raquo;', :page_links => false}.merge(options)
14   - will_paginate(collection, options)
15   - end
16   -
17 12 attr_reader :environment
18 13  
19 14 def options_for_article(article, tokenized_children=nil)
... ... @@ -35,7 +30,7 @@ module CmsHelper
35 30 end
36 31  
37 32 def display_spread_button(article)
38   - expirable_button article, :spread, _('Spread this'), {:action => 'publish', :id => article.id}, {:class => 'colorbox'}
  33 + expirable_button article, :spread, _('Spread this'), {:action => 'publish', :id => article.id}, {:modal => true}
39 34 end
40 35  
41 36 def display_delete_button(article)
... ...
app/helpers/folder_helper.rb
... ... @@ -61,7 +61,15 @@ module FolderHelper
61 61 @article = article
62 62  
63 63 visibility_options(article,tokenized_children) +
  64 + content_tag('h4', _('Options')) +
64 65 content_tag('div',
  66 + content_tag('div',
  67 + check_box(:article, :archived) +
  68 + content_tag('span', '&nbsp;', :class => 'access-archived-icon') +
  69 + content_tag('label', _('Read Only'), :for => 'article_archived_true') +
  70 + content_tag('span', _('Archive to avoid votes and create new children articles'), :class => 'access-note'),
  71 + :class => 'access-item'
  72 + ) +
65 73 hidden_field_tag('article[accept_comments]', 0)
66 74 )
67 75 end
... ...
app/helpers/forms_helper.rb
... ... @@ -184,6 +184,7 @@ module FormsHelper
184 184 datepicker_options[:year_suffix] ||= ''
185 185  
186 186 element_id = html_options[:id] || 'datepicker-date'
  187 + value_js_formatted = value.present? ? value.strftime('%Y-%m-%d %H:%S') : nil
187 188 value = value.strftime(format) if value.present?
188 189 method = datepicker_options[:time] ? 'datetimepicker' : 'datepicker'
189 190 result = text_field_tag(name, value, html_options)
... ... @@ -236,7 +237,7 @@ module FormsHelper
236 237 weekHeader: #{datepicker_options[:week_header].to_json},
237 238 yearRange: #{datepicker_options[:year_range].to_json},
238 239 yearSuffix: #{datepicker_options[:year_suffix].to_json}
239   - }).datepicker('setDate', new Date('#{value}'))
  240 + }).datepicker('setDate', new Date('#{value_js_formatted}'))
240 241 </script>
241 242 ".html_safe
242 243 result
... ...
app/helpers/forum_helper.rb
... ... @@ -10,10 +10,8 @@ module ForumHelper
10 10 end
11 11  
12 12 def list_forum_posts(articles)
13   - pagination = will_paginate(articles, {
14   - :param_name => 'npage',
15   - :previous_label => _('&laquo; Newer posts'),
16   - :next_label => _('Older posts &raquo;')
  13 + pagination = pagination_links(articles, {
  14 + :param_name => 'npage'
17 15 })
18 16 content = [content_tag('tr',
19 17 content_tag('th', _('Discussion topic')) +
... ...
app/helpers/language_helper.rb
... ... @@ -4,7 +4,15 @@ module LanguageHelper
4 4 end
5 5  
6 6 def tinymce_language
7   - language.downcase.split('_').first
  7 + lang = language.downcase.split('_').first
  8 + case lang
  9 + when 'pt'
  10 + 'pt_BR'
  11 + when 'fr'
  12 + 'fr_FR'
  13 + else
  14 + lang
  15 + end
8 16 end
9 17  
10 18 def html_language
... ...
app/helpers/search_helper.rb
... ... @@ -5,24 +5,21 @@ module SearchHelper
5 5 BLOCKS_SEARCH_LIMIT = 24
6 6 MULTIPLE_SEARCH_LIMIT = 8
7 7  
8   - FILTERS_TRANSLATIONS = {
9   - :order => _('Order'),
10   - :display => _('Display')
11   - }
12   -
13   - FILTERS_OPTIONS_TRANSLATION = {
14   - :order => {
15   - 'more_popular' => _('More popular'),
16   - 'more_active' => _('More active'),
17   - 'more_recent' => _('More recent'),
18   - 'more_comments' => _('More comments')
19   - },
20   - :display => {
21   - 'map' => _('Map'),
22   - 'full' => _('Full'),
23   - 'compact' => _('Compact')
  8 + def filters_options_translation
  9 + @filters_options_translation ||= {
  10 + :order => {
  11 + 'more_popular' => _('More popular'),
  12 + 'more_active' => _('More active'),
  13 + 'more_recent' => _('More recent'),
  14 + 'more_comments' => _('More comments')
  15 + },
  16 + :display => {
  17 + 'map' => _('Map'),
  18 + 'full' => _('Full'),
  19 + 'compact' => _('Compact')
  20 + }
24 21 }
25   - }
  22 + end
26 23  
27 24 COMMON_PROFILE_LIST_BLOCK = [
28 25 :enterprises,
... ... @@ -100,7 +97,7 @@ module SearchHelper
100 97 if options.size <= 1
101 98 return
102 99 else
103   - options = options.map {|option| [FILTERS_OPTIONS_TRANSLATION[name][option], option]}
  100 + options = options.map {|option| [filters_options_translation[name][option], option]}
104 101 options = options_for_select(options, :selected => (params[name] || default))
105 102 select_tag(name, options)
106 103 end
... ...
app/helpers/tinymce_helper.rb
... ... @@ -3,7 +3,7 @@ module TinymceHelper
3 3  
4 4 def tinymce_js
5 5 output = ''
6   - output += javascript_include_tag 'tinymce/js/tinymce/tinymce.min.js'
  6 + output += javascript_include_tag 'tinymce/js/tinymce/tinymce.js'
7 7 output += javascript_include_tag 'tinymce/js/tinymce/jquery.tinymce.min.js'
8 8 output += javascript_include_tag 'tinymce.js'
9 9 output += include_macro_js_files.to_s
... ...
app/mailers/mailing.rb
1   -require 'mailing_job'
  1 +require_dependency 'mailing_job'
2 2  
3 3 class Mailing < ActiveRecord::Base
4 4  
... ... @@ -40,10 +40,8 @@ class Mailing &lt; ActiveRecord::Base
40 40 begin
41 41 Mailing::Sender.notification(self, recipient.email).deliver
42 42 self.mailing_sents.create(:person => recipient)
43   - rescue Exception
44   - # FIXME should not discard errors silently. An idea is to collect all
45   - # errors and generate a task (notification) for the +source+
46   - # (environment/organization) listing these errors.
  43 + rescue Exception => ex
  44 + Rails.logger.error("#{ex.class.to_s} - #{ex.to_s} at #{__FILE__}:#{__LINE__}")
47 45 end
48 46 end
49 47 end
... ...
app/models/add_friend.rb
... ... @@ -14,8 +14,8 @@ class AddFriend &lt; Task
14 14 alias :friend :target
15 15 alias :friend= :target=
16 16  
17   - validates :requestor, :kind_of => { :kind => Person }
18   - validates :target, :kind_of => { :kind => Person }
  17 + validates :requestor, :kind_of => { :kind => Person }
  18 + validates :target, :kind_of => { :kind => Person }
19 19  
20 20 after_create do |task|
21 21 TaskMailer.invitation_notification(task).deliver unless task.friend
... ...
app/models/add_member.rb
... ... @@ -29,8 +29,10 @@ class AddMember &lt; Task
29 29 end
30 30  
31 31 def information
32   - {:message => _("%{requestor} wants to be a member of '%{organization}'."),
33   - variables: {requestor: requestor.name, organization: organization.name}}
  32 + requestor_email = " (#{requestor.email})" if requestor.may_display_field_to?("email")
  33 +
  34 + {:message => _("%{requestor}%{requestor_email} wants to be a member of '%{organization}'."),
  35 + variables: {requestor: requestor.name, requestor_email: requestor_email, organization: organization.name}}
34 36 end
35 37  
36 38 def accept_details
... ... @@ -46,7 +48,9 @@ class AddMember &lt; Task
46 48 end
47 49  
48 50 def target_notification_description
49   - _("%{requestor} wants to be a member of '%{organization}'.") % {:requestor => requestor.name, :organization => organization.name}
  51 + requestor_email = " (#{requestor.email})" if requestor.may_display_field_to?("email")
  52 +
  53 + _("%{requestor}%{requestor_email} wants to be a member of '%{organization}'.") % {:requestor => requestor.name, :requestor_email => requestor_email, :organization => organization.name}
50 54 end
51 55  
52 56 def target_notification_message
... ...
app/models/approve_article.rb
... ... @@ -138,9 +138,4 @@ class ApproveArticle &lt; Task
138 138 message
139 139 end
140 140  
141   - def request_is_member_of_target
142   - unless requestor.is_member_of?(target)
143   - errors.add(:approve_article, N_('Requestor must be a member of target.'))
144   - end
145   - end
146 141 end
... ...
app/models/article.rb
  1 +
1 2 class Article < ActiveRecord::Base
2 3  
3 4 attr_accessible :name, :body, :abstract, :profile, :tag_list, :parent,
... ... @@ -8,7 +9,7 @@ class Article &lt; ActiveRecord::Base
8 9 :highlighted, :notify_comments, :display_hits, :slug,
9 10 :external_feed_builder, :display_versions, :external_link,
10 11 :author, :published_at, :person_followers, :show_to_followers,
11   - :image_builder, :display_preview
  12 + :image_builder, :display_preview, :archived
12 13  
13 14 acts_as_having_image
14 15  
... ... @@ -28,9 +29,14 @@ class Article &lt; ActiveRecord::Base
28 29 def initialize(*params)
29 30 super
30 31  
31   - if !params.blank? && params.first.has_key?(:profile) && !params.first[:profile].blank?
32   - profile = params.first[:profile]
33   - self.published = false unless profile.public?
  32 + if !params.blank?
  33 + if params.first.has_key?(:profile) && !params.first[:profile].blank?
  34 + profile = params.first[:profile]
  35 + self.published = false unless profile.public_profile
  36 + end
  37 +
  38 + self.published = params.first["published"] if params.first.has_key?("published")
  39 + self.published = params.first[:published] if params.first.has_key?(:published)
34 40 end
35 41  
36 42 end
... ... @@ -152,6 +158,8 @@ class Article &lt; ActiveRecord::Base
152 158 validate :no_self_reference
153 159 validate :no_cyclical_reference, :if => 'parent_id.present?'
154 160  
  161 + validate :parent_archived?
  162 +
155 163 def no_self_reference
156 164 errors.add(:parent_id, _('self-reference is not allowed.')) if id && parent_id == id
157 165 end
... ... @@ -482,6 +490,10 @@ class Article &lt; ActiveRecord::Base
482 490 end
483 491 end
484 492  
  493 + def archived?
  494 + (self.parent && self.parent.archived) || self.archived
  495 + end
  496 +
485 497 def self.folder_types
486 498 ['Folder', 'Blog', 'Forum', 'Gallery']
487 499 end
... ... @@ -628,13 +640,21 @@ class Article &lt; ActiveRecord::Base
628 640 end
629 641  
630 642 def hit
631   - self.class.connection.execute('update articles set hits = hits + 1 where id = %d' % self.id.to_i)
632   - self.hits += 1
  643 + if !archived?
  644 + self.class.connection.execute('update articles set hits = hits + 1 where id = %d' % self.id.to_i)
  645 + self.hits += 1
  646 + end
633 647 end
634 648  
635 649 def self.hit(articles)
636   - Article.where(:id => articles.map(&:id)).update_all('hits = hits + 1')
637   - articles.each { |a| a.hits += 1 }
  650 + ids = []
  651 + articles.each do |article|
  652 + if !article.archived?
  653 + ids << article.id
  654 + article.hits += 1
  655 + end
  656 + end
  657 + Article.where(:id => ids).update_all('hits = hits + 1') if !ids.empty?
638 658 end
639 659  
640 660 def can_display_hits?
... ... @@ -812,7 +832,7 @@ class Article &lt; ActiveRecord::Base
812 832 end
813 833  
814 834 def first_image
815   - img = ( image.present? && { 'src' => image.public_filename } ) ||
  835 + img = ( image.present? && { 'src' => File.join([Noosfero.root, image.public_filename].join) } ) ||
816 836 Nokogiri::HTML.fragment(self.lead.to_s).css('img[src]').first ||
817 837 Nokogiri::HTML.fragment(self.body.to_s).search('img').first
818 838 img.nil? ? '' : img['src']
... ... @@ -848,4 +868,10 @@ class Article &lt; ActiveRecord::Base
848 868 sanitizer.sanitize(text)
849 869 end
850 870  
  871 + def parent_archived?
  872 + if self.parent_id_changed? && self.parent && self.parent.archived?
  873 + errors.add(:parent_folder, N_('is archived!!'))
  874 + end
  875 + end
  876 +
851 877 end
... ...
app/models/block.rb
... ... @@ -151,7 +151,7 @@ class Block &lt; ActiveRecord::Base
151 151  
152 152 def self.icon_path
153 153 basename = self.name.split('::').last.underscore
154   - File.join('blocks', basename, 'icon.png')
  154 + File.join('images', 'blocks', basename, 'icon.png')
155 155 end
156 156  
157 157 def self.pretty_name
... ... @@ -159,7 +159,7 @@ class Block &lt; ActiveRecord::Base
159 159 end
160 160  
161 161 def self.default_icon_path
162   - 'icon_block.png'
  162 + '/images/icon_block.png'
163 163 end
164 164  
165 165 def self.preview_path
... ... @@ -168,7 +168,7 @@ class Block &lt; ActiveRecord::Base
168 168 end
169 169  
170 170 def self.default_preview_path
171   - "block_preview.png"
  171 + "/images/block_preview.png"
172 172 end
173 173  
174 174 # Returns the content to be used for this block.
... ...
app/models/comment.rb
... ... @@ -34,7 +34,9 @@ class Comment &lt; ActiveRecord::Base
34 34 rec.errors.add(:name, _('{fn} can only be informed for unauthenticated authors').fix_i18n)
35 35 end
36 36 end
37   -
  37 +
  38 + validate :article_archived?
  39 +
38 40 acts_as_having_settings
39 41  
40 42 xss_terminate :only => [ :body, :title, :name ], :on => 'validation'
... ... @@ -210,4 +212,14 @@ class Comment &lt; ActiveRecord::Base
210 212 user.present? && user == author
211 213 end
212 214  
  215 + def archived?
  216 + self.article.archived? if self.article.present? && self.article.respond_to?(:archived?)
  217 + end
  218 +
  219 + protected
  220 +
  221 + def article_archived?
  222 + errors.add(:article, N_('associated with this comment is achived!')) if archived?
  223 + end
  224 +
213 225 end
... ...
app/models/community.rb
1 1 class Community < Organization
2 2  
3   - attr_accessible :accessor_id, :accessor_type, :role_id, :resource_id, :resource_type, :address_reference, :district, :tag_list, :language
  3 + attr_accessible :accessor_id, :accessor_type, :role_id, :resource_id, :resource_type
  4 + attr_accessible :address_reference, :district, :tag_list, :language, :description
4 5 after_destroy :check_invite_member_for_destroy
5 6  
6 7 def self.type_name
... ...
app/models/create_community.rb
... ... @@ -9,11 +9,15 @@ class CreateCommunity &lt; Task
9 9 alias :environment :target
10 10 alias :environment= :target=
11 11  
  12 + attr_accessible :environment, :requestor, :target
  13 + attr_accessible :reject_explanation, :template_id
  14 +
12 15 acts_as_having_image
13 16  
14   - DATA_FIELDS = Community.fields + ['name', 'closed']
  17 + DATA_FIELDS = Community.fields + ['name', 'closed', 'description']
15 18 DATA_FIELDS.each do |field|
16 19 settings_items field.to_sym
  20 + attr_accessible field.to_sym
17 21 end
18 22  
19 23 def validate
... ...
app/models/environment.rb
... ... @@ -160,7 +160,9 @@ class Environment &lt; ActiveRecord::Base
160 160 'allow_change_of_redirection_after_login' => _('Allow users to set the page to redirect after login'),
161 161 'display_my_communities_on_user_menu' => _('Display on menu the list of communities the user can manage'),
162 162 'display_my_enterprises_on_user_menu' => _('Display on menu the list of enterprises the user can manage'),
163   - 'restrict_to_members' => _('Show content only to members')
  163 + 'restrict_to_members' => _('Show content only to members'),
  164 +
  165 + 'enable_appearance' => _('Enable appearance editing by users'),
164 166 }
165 167 end
166 168  
... ... @@ -443,6 +445,7 @@ class Environment &lt; ActiveRecord::Base
443 445 show_balloon_with_profile_links_when_clicked
444 446 show_zoom_button_on_article_images
445 447 use_portal_community
  448 + enable_appearance
446 449 )
447 450  
448 451 before_create :enable_default_features
... ...
app/models/event.rb
... ... @@ -119,7 +119,7 @@ class Event &lt; Article
119 119 end
120 120  
121 121 alias_method :article_lead, :lead
122   - def lead
  122 + def lead(length = nil)
123 123 self.class.action_view.render 'content_viewer/event_lead', event: self
124 124 end
125 125  
... ...
app/models/favorite_enterprises_block.rb
... ... @@ -16,7 +16,7 @@ class FavoriteEnterprisesBlock &lt; ProfileListBlock
16 16 owner = self.owner
17 17 return '' unless owner.kind_of?(Person)
18 18 proc do
19   - link_to _('View all'), :profile => owner.identifier, :controller => 'profile', :action => 'favorite_enterprises'
  19 + link_to _('enterprises|View all'), {:profile => owner.identifier, :controller => 'profile', :action => 'favorite_enterprises'}, :class => 'view-all'
20 20 end
21 21 end
22 22  
... ...
app/models/folder.rb
... ... @@ -65,4 +65,8 @@ class Folder &lt; Article
65 65 !self.has_posts? || self.gallery?
66 66 end
67 67  
  68 + def archived?
  69 + self.archived
  70 + end
  71 +
68 72 end
... ...
app/models/highlights_block.rb
... ... @@ -12,7 +12,9 @@ class HighlightsBlock &lt; Block
12 12 block.images.each do |i|
13 13 i[:image_id] = i[:image_id].to_i
14 14 i[:position] = i[:position].to_i
15   - i[:address] = Noosfero.root + i[:address] unless Noosfero.root.nil?
  15 + if !Noosfero.root.nil? and !i[:address].start_with?(Noosfero.root + '/')
  16 + i[:address] = Noosfero.root + i[:address]
  17 + end
16 18 begin
17 19 file = UploadedFile.find(i[:image_id])
18 20 i[:image_src] = file.public_filename
... ...
app/models/image.rb
... ... @@ -23,7 +23,8 @@ class Image &lt; ActiveRecord::Base
23 23  
24 24 postgresql_attachment_fu
25 25  
26   - attr_accessible :uploaded_data, :label
  26 + attr_accessible :uploaded_data, :label, :remove_image
  27 + attr_accessor :remove_image
27 28  
28 29 def current_data
29 30 File.file?(full_filename) ? File.read(full_filename) : nil
... ...
app/models/person.rb
... ... @@ -90,6 +90,7 @@ class Person &lt; Profile
90 90 #Article followers relation
91 91 has_many :article_followers, :dependent => :destroy
92 92 has_many :following_articles, :class_name => 'Article', :through => :article_followers, :source => :article
  93 + has_many :comments, :foreign_key => :author_id
93 94  
94 95 has_many :friendships, :dependent => :destroy
95 96 has_many :friends, :class_name => 'Person', :through => :friendships
... ...
app/models/profile.rb
... ... @@ -1019,7 +1019,8 @@ private :generate_url, :url_options
1019 1019  
1020 1020 def members_cache_key(params = {})
1021 1021 page = params[:npage] || '1'
1022   - cache_key + '-members-page-' + page
  1022 + sort = (params[:sort] == 'desc') ? params[:sort] : 'asc'
  1023 + cache_key + '-members-page-' + page + '-' + sort
1023 1024 end
1024 1025  
1025 1026 def more_recent_label
... ...
app/models/profile_activity.rb
... ... @@ -16,6 +16,7 @@ class ProfileActivity &lt; ActiveRecord::Base
16 16  
17 17 def self.update_activity activity
18 18 profile_activity = ProfileActivity.where(activity_id: activity.id, activity_type: activity.class.base_class.name).first
  19 + return unless profile_activity
19 20 profile_activity.send :copy_timestamps
20 21 profile_activity.save!
21 22 profile_activity
... ...
app/models/rss_feed.rb
... ... @@ -14,7 +14,7 @@ class RssFeed &lt; Article
14 14  
15 15 # store setting in body
16 16 serialize :body, Hash
17   -
  17 +
18 18 def body
19 19 self[:body] ||= {}
20 20 end
... ... @@ -89,6 +89,14 @@ class RssFeed &lt; Article
89 89 )
90 90 end
91 91  
  92 + def published?
  93 + if self.parent
  94 + self.parent.published?
  95 + else
  96 + self.published
  97 + end
  98 + end
  99 +
92 100 def self.short_description
93 101 _('RSS Feed')
94 102 end
... ...
app/models/task.rb
... ... @@ -156,28 +156,6 @@ class Task &lt; ActiveRecord::Base
156 156 end
157 157 end
158 158  
159   - def requestor_is_of_kind(klass, message = nil)
160   - error_message = message ||= _('Task requestor must be '+klass.to_s.downcase)
161   - group = klass.to_s.downcase.pluralize
162   - if environment.respond_to?(group) and requestor_id
163   - requestor = requestor ||= environment.send(klass.to_s.downcase.pluralize).find_by_id(requestor_id)
164   - end
165   - unless requestor.class == klass
166   - errors.add(error_message)
167   - end
168   - end
169   -
170   - def target_is_of_kind(klass, message = nil)
171   - error_message = message ||= _('Task target must be '+klass.to_s.downcase)
172   - group = klass.to_s.downcase.pluralize
173   - if environment.respond_to?(group) and target_id
174   - target = target ||= environment.send(klass.to_s.downcase.pluralize).find_by_id(target_id)
175   - end
176   - unless target.class == klass
177   - errors.add(error_message)
178   - end
179   - end
180   -
181 159 def close(status, closed_by)
182 160 self.status = status
183 161 self.end_date = Time.now
... ...
app/models/textile_article.rb
... ... @@ -12,7 +12,7 @@ class TextileArticle &lt; TextArticle
12 12 convert_to_html(body)
13 13 end
14 14  
15   - def lead
  15 + def lead(length = nil)
16 16 if abstract.blank?
17 17 super
18 18 else
... ...
app/models/theme.rb
... ... @@ -18,7 +18,6 @@ class Theme
18 18 Rails.root.join('public', relative_themes_dir)
19 19 end
20 20  
21   - #FIXME make this test
22 21 def relative_themes_dir
23 22 File.join('designs', 'themes')
24 23 end
... ... @@ -99,12 +98,10 @@ class Theme
99 98 config['public'] = value
100 99 end
101 100  
102   - #FIXME make this test
103 101 def public_path
104 102 File.join('/', self.class.relative_themes_dir, self.id)
105 103 end
106 104  
107   - #FIXME make this test
108 105 def filesystem_path
109 106 File.join(self.class.system_themes_dir, self.id)
110 107 end
... ...
app/models/user.rb
... ... @@ -127,6 +127,7 @@ class User &lt; ActiveRecord::Base
127 127 validates_uniqueness_of :email, :case_sensitive => false, :scope => :environment_id
128 128 before_save :encrypt_password
129 129 before_save :normalize_email, if: proc{ |u| u.email.present? }
  130 + before_save :generate_private_token_if_not_exist
130 131 validates_format_of :email, :with => Noosfero::Constants::EMAIL_FORMAT, :if => (lambda {|user| !user.email.blank?})
131 132  
132 133 validates_inclusion_of :terms_accepted, :in => [ '1' ], :if => lambda { |u| ! u.terms_of_use.blank? }, :message => N_('{fn} must be checked in order to signup.').fix_i18n
... ... @@ -142,19 +143,34 @@ class User &lt; ActiveRecord::Base
142 143  
143 144 u = self.has_login?(login, login, environment.id)
144 145 u = u.first if u.is_a?(ActiveRecord::Relation)
145   - u && u.authenticated?(password) ? u : nil
  146 +
  147 + if u && u.authenticated?(password)
  148 + u.generate_private_token_if_not_exist
  149 + return u
  150 + end
  151 + return nil
146 152 end
147 153  
148 154 def register_login
149 155 self.update_attribute :last_login_at, Time.now
150 156 end
151 157  
152   - def generate_private_token!
  158 + def generate_private_token
153 159 self.private_token = SecureRandom.hex
154 160 self.private_token_generated_at = DateTime.now
  161 + end
  162 +
  163 + def generate_private_token!
  164 + self.generate_private_token
155 165 save(:validate => false)
156 166 end
157 167  
  168 + def generate_private_token_if_not_exist
  169 + unless self.private_token
  170 + self.generate_private_token
  171 + end
  172 + end
  173 +
158 174 TOKEN_VALIDITY = 2.weeks
159 175 def private_token_expired?
160 176 self.private_token.nil? || (self.private_token_generated_at + TOKEN_VALIDITY < DateTime.now)
... ... @@ -407,6 +423,12 @@ class User &lt; ActiveRecord::Base
407 423 @is_password_required = false
408 424 end
409 425  
  426 + def resend_activation_code
  427 + return if self.activated?
  428 + update_attribute(:activation_code, make_activation_code)
  429 + self.deliver_activation_code
  430 + end
  431 +
410 432 protected
411 433  
412 434 def normalize_email
... ...
app/views/api/index.html.erb
1 1 <h1>EndPoints</h1>
2 2  
3 3 <div style="float: right">
4   -<%= s_('api-playground|Try the %s') % link_to('API Playground', '/api/playground') %>
  4 + <%= s_('api-playground|Try the %s') % link_to('API Playground', {:controller => 'api', :action => 'playground'}) %>
5 5 </div>
6 6  
7 7 <%= endpoints.map do |endpoint|
... ...
app/views/api/playground.html.erb
1 1 <h1>API Playground</h1>
2 2  
3 3 <script>
  4 +<% prefix = Noosfero::API::API.prefix %>
  5 +var prefix = <%= prefix.to_json %>;
4 6 var endpoints = <%=
5 7 endpoints.map do |endpoint|
6 8 app = endpoint.options[:app].to_s
... ... @@ -13,8 +15,8 @@ endpoints.map do |endpoint|
13 15 end
14 16 end
15 17 end.flatten.compact.sort{|a,b|
16   - a[:path]=='/api/v1/login' ? -1 :
17   - b[:path]=='/api/v1/login' ? 1 :
  18 + a[:path]=="#{prefix}/v1/login" ? -1 :
  19 + b[:path]=="#{prefix}/v1/login" ? 1 :
18 20 a[:path] <=> b[:path]
19 21 }.to_json %>;
20 22 </script>
... ... @@ -33,4 +35,4 @@ end.flatten.compact.sort{|a,b|
33 35 </div>
34 36 <pre id="api-response" class="empty"></pre>
35 37  
36   -<script src="/javascripts/api-playground.js"></script>
  38 +<%= javascript_include_tag 'api-playground' %>
... ...
app/views/blocks/highlights.html.erb
... ... @@ -4,7 +4,7 @@
4 4 <div class='highlights-container'>
5 5 <% block.featured_images.each do |img| %>
6 6 <a href="<%= img[:address] %>" title="<%= img[:title] %>" class="highlights-image-link">
7   - <%= content_tag :img, nil, :src => img[:image_src], :alt => img[:title] %>
  7 + <%= image_tag [Noosfero.root, img[:image_src]].join, alt: img[:title] %>
8 8 <p class="highlights-label"><%= img[:title] %></p>
9 9 </a>
10 10 <% end %>
... ...
app/views/cms/_archived_warning.html.erb 0 → 100644
... ... @@ -0,0 +1,8 @@
  1 +<% if !article.errors.any? %>
  2 + <div class="text-warning">
  3 + <p>
  4 + <i class="icon"></i>
  5 + <%= _("Archived article! It's read-only") %>
  6 + </p>
  7 + </div>
  8 +<% end %>
... ...
app/views/cms/_blog.html.erb
... ... @@ -55,14 +55,12 @@
55 55  
56 56 <%= labelled_form_field(_('Description:'), text_area(:article, :body, :rows => 10, :class => 'mceEditor')) %>
57 57  
58   -<%= f.fields_for :image_builder, @article.image do |i| %>
59   - <%= file_field_or_thumbnail(_('Cover image:'), @article.image, i)%>
60   - <%= _("Max size: %s (.jpg, .gif, .png)")% Image.max_size.to_humanreadable %>
61   -<% end %>
62   -
63   -<% unless @article.image.nil? %>
64   - <%= labelled_check_box(_('Remove cover image'),'remove_image',true,false)%>
65   -<% end %>
  58 +<div id="blog-image-builder">
  59 + <%= f.fields_for :image_builder, @article.image do |i| %>
  60 + <%= file_field_or_thumbnail(_('Cover image:'), @article.image, i)%>
  61 + <%= _("Max size: %s (.jpg, .gif, .png)")% Image.max_size.to_humanreadable %>
  62 + <% end %>
  63 +</div>
66 64  
67 65 <%= labelled_form_field(_('How to display posts:'), f.select(:visualization_format, [
68 66 [ _('Full post'), 'full'],
... ...
app/views/cms/_forum.html.erb
... ... @@ -10,7 +10,7 @@
10 10  
11 11 <%= render :partial => 'general_fields' %>
12 12  
13   -<%= labelled_form_field(_('Description:'), text_area(:article, :body, :cols => 64, :rows => 10)) %>
  13 +<%= labelled_form_field(_('Description:'), text_area(:article, :body, :class => 'mceEditor', :cols => 64, :rows => 10)) %>
14 14  
15 15 <%= labelled_form_field(_('Posts per page:'), f.select(:posts_per_page, Forum.posts_per_page_options)) %>
16 16  
... ...
app/views/cms/_published_media_items.html.erb
... ... @@ -4,7 +4,7 @@
4 4 <div class='section-title'>
5 5 <h3><%= header %></h3>
6 6 <% if @recent_files[key].total_pages > 1 %>
7   - <%= link_to(_('View all'), {:controller => 'cms', :action => 'view_all_media', :profile => profile.identifier, :key => key}, :class => 'view-all colorbox', 'data-key' => key) %>
  7 + <%= modal_link_to(_('View all'), {:controller => 'cms', :action => 'view_all_media', :profile => profile.identifier, :key => key}, { :class => 'view-all', 'data-key' => key }) %>
8 8 <% end %>
9 9 </div>
10 10 <%= render :partial => "cms/media_panel/list_published_media_items", :locals => { key: key, show_pagination_links: false } %>
... ...
app/views/cms/_view_items.html.erb
... ... @@ -13,6 +13,7 @@
13 13 <%= time_ago_in_words article.updated_at %>
14 14 </td>
15 15 <td class="article-controls">
  16 + <%= @plugins.dispatch(:extra_content_actions, article).collect { |content| instance_exec(&content) }.join("") %>
16 17 <%= expirable_button article, :edit, _('Edit'), {:action => 'edit', :id => article.id} if !remove_content_button(:edit, article) %>
17 18 <%= button_without_text :eyes, _('Public view'), article.view_url %>
18 19 <%= display_spread_button(article) unless remove_content_button(:spread, article) %>
... ...
app/views/cms/edit.html.erb
1 1 <%= error_messages_for 'article' %>
2 2  
  3 +<% if @article.archived? %>
  4 + <%= render :partial => 'archived_warning', :locals => {:article => @article} %>
  5 +<% end %>
3 6 <div class='<%= (@article.display_media_panel? ? 'with_media_panel' : 'no_media_panel') %>'>
4 7 <%= labelled_form_for 'article', :html => { :multipart => true, :class => @type } do |f| %>
5 8  
... ... @@ -9,6 +12,7 @@
9 12  
10 13 <%= hidden_field_tag('success_back_to', @success_back_to) %>
11 14  
  15 +
12 16 <%= render :partial => partial_for_class(@article.class), :locals => { :f => f } %>
13 17  
14 18 <% if environment.is_portal_community?(profile) %>
... ...
app/views/cms/media_panel/_image.html.erb
1 1 <div class="item image" data-item="span" title="<%= @file.name %>">
2 2 <span>
3   - <img src="<%= @file.public_filename(:uploaded) %>"/>
  3 + <%= image_tag(@file.public_filename(:uploaded)) %>
4 4 </span>
5 5 <div class="controls image-controls">
6 6 <a class="button icon-add add-to-text" href="#"><span><%= _('Add to the text') %></span></a>
... ...
app/views/content_viewer/_article_toolbar.html.erb
... ... @@ -18,7 +18,7 @@
18 18  
19 19 <% if @page.allow_spread?(user) && !remove_content_button(:spread, @page) %>
20 20 <% url = profile.admin_url.merge({ :controller => 'cms', :action => 'publish', :id => @page.id }) %>
21   - <%= expirable_button @page, :spread, content_tag( 'span', _('Spread this') ), url, {:class => 'colorbox'} if url %>
  21 + <%= expirable_button @page, :spread, content_tag( 'span', _('Spread this') ), url, {:modal => true} if url %>
22 22 <% end %>
23 23  
24 24 <% if !@page.gallery? && (@page.allow_create?(user) || (@page.parent && @page.parent.allow_create?(user))) %>
... ... @@ -29,7 +29,9 @@
29 29 <%= expirable_button @page, :locale, content, url %>
30 30 <% end %>
31 31  
32   - <%= modal_button(:new, label_for_new_article(@page), profile.admin_url.merge(:controller => 'cms', :action => 'new', :parent_id => (@page.folder? ? @page : @page.parent))) unless remove_content_button(:new, @page) %>
  32 + <% if !@page.archived? %>
  33 + <%= modal_button(:new, label_for_new_article(@page), profile.admin_url.merge(:controller => 'cms', :action => 'new', :parent_id => (@page.folder? ? @page : @page.parent))) unless remove_content_button(:new, @page) %>
  34 + <% end %>
33 35  
34 36 <% content = content_tag('span', label_for_clone_article(@page)) %>
35 37 <% url = profile.admin_url.merge({ :controller => 'cms', :action => 'new', :id => @page.id, :clone => true, :parent_id => (@page.folder? ? @page : @page.parent), :type => @page.class}) %>
... ... @@ -64,6 +66,9 @@
64 66 <% end %>
65 67 <%= button_without_text(:feed, _('RSS feed'), @page.feed.url, :class => 'blog-feed-link') if @page.has_posts? && @page.feed %>
66 68 <%= @plugins.dispatch(:article_header_extra_contents, @page).collect { |content| instance_exec(&content) }.join("") %>
  69 + <% if @page.archived? %>
  70 + <%= render :partial => 'cms/archived_warning', :locals => {:article => @page} %>
  71 + <% end %>
67 72 <%= render :partial => 'article_title', :locals => {:no_link => true} %>
68 73 <%= article_translations(@page) %>
69 74 </div>
... ...
app/views/content_viewer/_publishing_info.html.erb
... ... @@ -16,7 +16,7 @@
16 16 <div id='article-sub-header'>
17 17 <% if @page.display_hits? %>
18 18 <div id="article-hits">
19   - <%= n_('Viewed one time', 'Viewed %{num} times', @page.hits) % { :num => @page.hits } %>
  19 + <%= n_('Viewed one time %{desc}', 'Viewed %{num} times %{desc}', @page.hits) % { :num => @page.hits, :desc => @page.archived? ? '<b>'+_('(Not countable anymore)')+'</b>' : '' } %>
20 20 </div>
21 21 <% end %>
22 22  
... ...
app/views/content_viewer/view_page.html.erb
... ... @@ -31,7 +31,7 @@
31 31 <% cache(@page.cache_key(params, user, language)) do %>
32 32 <div class="<%="article-body article-body-" + @page.css_class_name %>">
33 33 <% options = @page.image? ? {:gallery_view => true} : {} %>
34   - <% if @page.image.present? && !@page.event? %>
  34 + <% if @page.image.present? && !@page.event? && !@page.blog? %>
35 35 <div class="article-body-img">
36 36 <%= image_tag(@page.image.public_filename) %>
37 37 <p><%= @page.image.label%></p>
... ... @@ -85,7 +85,7 @@
85 85 <% end %>
86 86 </ul>
87 87  
88   - <% if @page.accept_comments? %>
  88 + <% if !@page.archived? || @page.accept_comments? %>
89 89 <div id='page-comment-form' class='page-comment-form'><%= render :partial => 'comment/comment_form', :locals =>{:url => {:controller => :comment, :action => :create}, :display_link => true, :cancel_triggers_hide => true}%></div>
90 90 <% end %>
91 91 </div><!-- end class="comments" -->
... ...
app/views/mailing/sender/notification.html.erb
... ... @@ -3,7 +3,7 @@
3 3 <head>
4 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
5 5 </head>
6   - <body>
  6 + <body style="margin: 0">
7 7 <%= word_wrap(@message) %>
8 8 <p>
9 9 --<br/>
... ...
app/views/profile/_create_product.html.erb
... ... @@ -3,7 +3,7 @@
3 3 </div>
4 4 <div class='profile-activity-description'>
5 5 <p class='profile-activity-text'><%= link_to activity.user.short_name(nil), activity.user.url %> <%= describe activity %></p>
6   - <p class='profile-activity-time'><%= time_ago_as_sentence activity.created_at %></p>
  6 + <p class='profile-activity-time'><%= time_ago_in_words activity.created_at %></p>
7 7  
8 8 <div class='profile-wall-actions'>
9 9 <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %>
... ...
app/views/profile/_favorite_enterprise.html.erb
... ... @@ -5,7 +5,7 @@
5 5 <p class='profile-activity-text'>
6 6 <%= link_to activity.user.short_name(nil), activity.user.url %> <%= describe activity %>
7 7 </p>
8   - <p class='profile-activity-time'><%= time_ago_as_sentence activity.created_at %></p>
  8 + <p class='profile-activity-time'><%= time_ago_in_words activity.created_at %></p>
9 9  
10 10 <div class='profile-wall-actions'>
11 11 <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %>
... ...
app/views/profile/_profile_members_list.html.erb 0 → 100644
... ... @@ -0,0 +1,16 @@
  1 +<div id="profile-members-sort-options">
  2 + <%= label_tag("sort-#{role}", _("Sort by:")) %>
  3 + <%= select_tag("sort-#{role}",
  4 + options_for_select([
  5 + [_("Name A-Z"), 'asc'],
  6 + [_("Name Z-A"), 'desc'],
  7 + ], :selected => params[:sort])
  8 + ) %>
  9 +</div>
  10 +<ul class="profile-list-<%= role %>" >
  11 + <% users.each do |u| %>
  12 + <%= profile_image_link(u) %>
  13 + <% end %>
  14 +</ul>
  15 +
  16 +<%= pagination_links users, :param_name => 'npage' %>
... ...
app/views/profile/_remove_product.html.erb
... ... @@ -2,7 +2,7 @@
2 2 </div>
3 3 <div class='profile-activity-description'>
4 4 <p class='profile-activity-text'><%= link_to activity.user.short_name(nil), activity.user.url %> <%= describe activity %></p>
5   - <p class='profile-activity-time'><%= time_ago_as_sentence activity.created_at %></p>
  5 + <p class='profile-activity-time'><%= time_ago_in_words activity.created_at %></p>
6 6  
7 7 <div class='profile-wall-actions'>
8 8 <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %>
... ...
app/views/profile/_update_product.html.erb
... ... @@ -3,7 +3,7 @@
3 3 </div>
4 4 <div class='profile-activity-description'>
5 5 <p class='profile-activity-text'><%= link_to activity.user.short_name(nil), activity.user.url %> <%= describe activity %></p>
6   - <p class='profile-activity-time'><%= time_ago_as_sentence activity.created_at %></p>
  6 + <p class='profile-activity-time'><%= time_ago_in_words activity.created_at %></p>
7 7  
8 8 <div class='profile-wall-actions'>
9 9 <%= link_to_function(_('Remove'), 'remove_item_wall(this, \'%s\', \'%s\', \'%s\'); return false ;' % [".profile-activity-item", url_for(:profile => params[:profile], :action => :remove_activity, :activity_id => activity.id, :view => params[:view]), _('Are you sure you want to remove this activity and all its replies?')]) if logged_in? && current_person == @profile %>
... ...
app/views/profile/members.html.erb
1 1 <div class="common-profile-list-block">
2 2  
3   -<h1><%= _("%s's members") % profile.name %></h1>
  3 +<h1><%= _("Members (%d)") % @profile_members.total_entries %></h1>
  4 +<h2 class="community-name"><%= profile.name %></h2>
4 5  
5 6 <% cache_timeout(profile.members_cache_key(params), 4.hours) do %>
6   - <ul class='profile-list'>
7   - <!--
8   - @todo Highlight visual for invited members
9   - of a community
10   - -->
11   - <% @members.each do |member| %>
12   - <%= profile_image_link(member) %>
13   - <% end %>
14   - </ul>
  7 + <div class="profile-members-tabs-container">
  8 + <% tabs = [] %>
  9 +
  10 + <% div_members = content_tag :div, :class => "profile-members" do
  11 + render :partial => 'profile_members_list',
  12 + :locals => {
  13 + :users => @profile_members,
  14 + :role => "members"
  15 + }
  16 + end %>
  17 +
  18 + <% tabs << {:title => _("%d Members") % @profile_members.total_entries,
  19 + :id => "members-tab",
  20 + :content => div_members
  21 + } %>
15 22  
16   - <div id='pagination-profiles'>
17   - <%= pagination_links @members, :param_name => 'npage' %>
18   - </div>
  23 + <% div_admins = content_tag :div, :class => "profile-admins" do
  24 + render :partial => 'profile_members_list',
  25 + :locals => {
  26 + :users => @profile_admins,
  27 + :role => "admins"
  28 + }
  29 + end %>
  30 +
  31 + <% tabs << {:title => _("%d Administrators") % @profile_admins.total_entries,
  32 + :id => "admins-tab",
  33 + :content => div_admins
  34 + } %>
  35 +
  36 + <%= render_tabs(tabs) %>
  37 + </div><!-- end of class="profile-members-tabs-container" -->
19 38 <% end %>
20 39  
21 40 <% button_bar do %>
... ... @@ -30,4 +49,7 @@
30 49 <% end %>
31 50 <% end %>
32 51  
33   -</div><!-- fim class="common-profile-list-block" -->
  52 +<%= hidden_field_tag "profile_url", @profile_members_url %>
  53 +</div><!-- end of class="common-profile-list-block" -->
  54 +
  55 +<%= javascript_include_tag "members_page.js" %>
... ...
app/views/profile_editor/_person.html.erb
... ... @@ -18,6 +18,14 @@
18 18  
19 19 <%= @plugins.dispatch(:profile_info_extra_contents).collect { |content| instance_exec(&content) }.join("") %>
20 20  
  21 + <div class="formfieldline">
  22 + <%= label_tag("private_token", _("Private Token")) %>
  23 + <div class="formfield type-text">
  24 + <%= text_field_tag("a", @profile.user.private_token, :size => 30) %>
  25 + </div>
  26 + </div>
  27 + <%= link_to("Reset token", {:controller => :profile_editor, :action => :reset_private_token, :id => @profile.id}, :class => "button with-text") %>
  28 +
21 29 <%= render :partial => 'person_form', :locals => {:f => f} %>
22 30  
23 31 <%= render :partial => 'person_form_custom_fields', :locals => {:f => f} %>
... ...
app/views/profile_editor/index.html.erb
... ... @@ -22,13 +22,13 @@
22 22  
23 23 <%= control_panel_button(_('Edit sideboxes'), 'blocks', :controller => 'profile_design', :action => 'index') %>
24 24  
25   - <%= control_panel_button(_('Edit Appearance'), 'design-editor', :controller => 'profile_themes', :action => 'index') %>
  25 + <%= control_panel_button(_('Edit Appearance'), 'design-editor', :controller => 'profile_themes', :action => 'index') if @show_appearance_option %>
26 26  
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')) %>
  27 + <%= control_panel_button(_('Edit Header and Footer'), 'header-and-footer', :controller => 'profile_editor', :action => 'header_footer') if @show_header_footer_option %>
28 28  
29 29 <%= control_panel_button(_('Manage Content'), 'cms', :controller => 'cms') %>
30 30  
31   - <%= control_panel_button(_('Manage Roles'), 'roles', :controller => 'profile_roles') %>
  31 + <%= control_panel_button(_('Manage Roles'), 'roles', :controller => 'profile_roles') if profile.organization? %>
32 32  
33 33 <% unless profile.enterprise? %>
34 34 <%= case profile.blogs.count
... ...
app/views/search/_article_last_change.html.erb
... ... @@ -2,7 +2,7 @@
2 2  
3 3 <div class="search-article-author-changes">
4 4 <% if article.last_changed_by and article.last_changed_by != article.profile %>
5   - <span><%= _('by %{name} at %{date}') % {:name => link_to(article.last_changed_by.name, article.last_changed_by.url),
  5 + <span><%= _('Updated by %{name} at %{date}') % {:name => link_to(article.last_changed_by.name, article.last_changed_by.url),
6 6 :date => show_date(article.updated_at) } %></span>
7 7 <% else %>
8 8 <span><%= _('Last update: %s.') % show_date(article.updated_at) %></span>
... ...
app/views/shared/_change_image.html.erb
1 1 <%= i.file_field( :uploaded_data, { :onchange => 'updateImg(this.value)' } ) %>
2 2 <%= labelled_form_field(_("Image Label:"), i.text_field(:label)) %>
3   -<%= button_to_function(:cancel,_('Cancel'),"jQuery('#change-image-link').show(); jQuery('#change-image').html('')", :id => 'cancel-change-image-link', :style => 'display: none')%>
  3 +<%= button_to_function(:cancel,_('Cancel'),"jQuery('#change-image-link').show(); jQuery('#change-image').hide()", :id => 'cancel-change-image-link', :style => 'display: none')%>
... ...
app/views/shared/_show_thumbnail.html.erb
1   - <%= image_tag(image.public_filename(:thumb)) %>
  1 +<%= image_tag(image.public_filename(:thumb)) %>
2 2  
3   - <br/>
  3 +<br/>
4 4  
5   - <%= button_to_function(:photos, _('Change image'), 'display_change_image()', :id => 'change-image-link' ) %>
  5 +<%= button_to_function(:photos, _('Change image'), 'display_change_image()', :id => 'change-image-link' ) %>
6 6  
7   - <script>
8   - function display_change_image() {
9   - var content = "<%= j(render :partial => 'shared/change_image', :locals => { :i => i, :image => image }) %>";
10   - jQuery('#change-image').html(content);
11   - jQuery('#change-image-link').hide();
12   - jQuery('#cancel-change-image-link').show();
13   - }
14   - </script>
  7 +<script>
  8 + function display_change_image() {
  9 + jQuery('#change-image').show();
  10 + jQuery('#change-image-link').hide();
  11 + jQuery('#cancel-change-image-link').show();
  12 + }
  13 +</script>
15 14  
16   - <div id='change-image'> </div> <br/>
  15 +<br/>
  16 +<div id='change-image' style='display:none'>
  17 + <%= render :partial => 'shared/change_image', :locals => { :i => i, :image => image } %>
  18 +</div>
  19 +<br/>
  20 +
  21 +<% if image.present? && removable %>
  22 + <div id='image-builder-remove-checkbox'>
  23 + <%= labelled_form_field(_('Remove image'), i.check_box(:remove_image, {}, true, false))%>
  24 + </div>
  25 +<% end %>
... ...
app/views/shared/logged_in/xmpp_chat.html.erb
1   - <%= javascript_include_tag 'strophejs-1.1.3/strophe.min', 'jquery.emoticon', '../designs/icons/pidgin/emoticons.js', 'ba-linkify', 'jquery.ba-hashchange', 'jquery.sound', 'chat', 'perfect-scrollbar.min.js', 'perfect-scrollbar.with-mousewheel.min.js', 'jquery.timeago.js', :cache => 'cache/chat' %>
2   - <%= stylesheet_link_tag 'perfect-scrollbar.min.css' %>
  1 + <%= javascript_include_tag 'strophejs-1.1.3/strophe.min', 'jquery.emoticon', '../designs/icons/pidgin/emoticons.js', 'ba-linkify', 'jquery.ba-hashchange', 'jquery.sound', 'chat', 'vendor/perfect-scrollbar.min.js', 'vendor/perfect-scrollbar.with-mousewheel.min.js', 'jquery.timeago.js', :cache => 'cache/chat' %>
  2 + <%= stylesheet_link_tag 'vendor/perfect-scrollbar.min.css' %>
3 3  
4 4 <% extend ChatHelper %>
5 5  
... ...
app/views/users/_users_list.html.erb
... ... @@ -11,11 +11,13 @@
11 11 </colgroup>
12 12 <tr>
13 13 <th><%= _('Member') %></th>
  14 + <th><%= _('Email') %></th>
14 15 <th><%= _('Actions') %></th>
15 16 </tr>
16 17 <% @collection.each do |p| %>
17 18 <tr title="<%= p.name %>">
18 19 <td><%= link_to_profile p.short_name, p.identifier, :title => p.name %> </td>
  20 + <td><%= link_to_profile p.email, p.identifier, :title => p.email %> </td>
19 21 <td class='actions'>
20 22 <div class="members-buttons-cell">
21 23 <% if p.is_admin? %>
... ...
config.ru
... ... @@ -2,10 +2,6 @@
2 2  
3 3 require ::File.expand_path('../config/environment', __FILE__)
4 4  
5   -#use Rails::Rack::LogTailer
6   -#use Rails::Rack::Static
7   -#run ActionController::Dispatcher.new
8   -
9 5 use Rack::Cors do
10 6 allow do
11 7 origins '*'
... ... @@ -14,7 +10,13 @@ use Rack::Cors do
14 10 end
15 11  
16 12 rails_app = Rack::Builder.new do
17   - run Noosfero::Application
  13 + if ENV['RAILS_RELATIVE_URL_ROOT']
  14 + map ENV['RAILS_RELATIVE_URL_ROOT'] do
  15 + run Noosfero::Application
  16 + end
  17 + else
  18 + run Noosfero::Application
  19 + end
18 20 end
19 21  
20 22 run Rack::Cascade.new([
... ...
config/docker/dev/Dockerfile 0 → 100644
... ... @@ -0,0 +1,16 @@
  1 +# Noosfero development environment
  2 +#
  3 +# VERSION 0.0.1
  4 +
  5 +FROM debian:wheezy
  6 +MAINTAINER Noosfero Development Team <noosfero-dev@listas.softwarelivre.org>
  7 +
  8 +LABEL Description="This dockerfile builds a noosfero development environment."
  9 +WORKDIR /src/noosfero
  10 +
  11 +RUN apt-get update && apt-get install -y sudo git
  12 +RUN git clone --depth 1 https://gitlab.com/noosfero/noosfero.git .
  13 +
  14 +RUN sh script/quick-start --skip-translations
  15 +
  16 +EXPOSE 3000
... ...
config/environments/development.rb
... ... @@ -28,11 +28,10 @@ Noosfero::Application.configure do
28 28 # with SQLite, MySQL, and PostgreSQL)
29 29 config.active_record.auto_explain_threshold_in_seconds = 0.5
30 30  
31   - # Do not compress assets
32 31 config.assets.compress = false
33   -
34   - # Expands the lines which load the assets
35   - config.assets.debug = true
  32 + config.assets.digest = false
  33 + # we have a lot of assets
  34 + config.assets.debug = false
36 35  
37 36 config.consider_all_requests_local = true
38 37  
... ...
config/environments/production.rb
... ... @@ -44,7 +44,7 @@ Noosfero::Application.configure do
44 44 # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
45 45  
46 46 # Use a different cache store in production
47   - config.cache_store = :dalli_store, "localhost"
  47 + config.cache_store = :dalli_store, "127.0.0.1:11211"
48 48  
49 49 # Enable serving of images, stylesheets, and javascripts from an asset server
50 50 # config.action_controller.asset_host = "http://assets.example.com"
... ...
config/initializers/eager_load.rb
... ... @@ -1 +0,0 @@
1   -#Rails.application.eager_load! if ActiveRecord::Base.connection.table_exists? 'categories'
config/initializers/session.rb
1 1 require File.join(Rails.root,'app/models/session')
2 2  
3 3 ActionDispatch::Reloader.to_prepare do
  4 + require_relative '../../app/models/session'
4 5 ActiveRecord::SessionStore.session_class = Session
5 6 end
6 7  
... ...
config/schedule.rb
... ... @@ -28,3 +28,15 @@ end
28 28 every 30.days do
29 29 runner "ProfileSuggestion.generate_all_profile_suggestions"
30 30 end
  31 +
  32 +# Loads "schedule.rb" files from plugins
  33 +#
  34 +# Allows Noosfero's plugins schedule jobs using `whenever` Ruby gem the same
  35 +# way we do here, just create the file "config/schedule.rb" into the plugin
  36 +# root directory and write jobs using the same syntax used here (see example in
  37 +# the `newsletter` plugin)
  38 +
  39 +Dir.glob("config/plugins/*/config/schedule.rb").each do |filename|
  40 + filecontent = IO.read(filename)
  41 + instance_eval(Whenever::NumericSeconds.process_string(filecontent), filename)
  42 +end
... ...
config/thin.yml.dist
... ... @@ -1,13 +0,0 @@
1   ----
2   -pid: tmp/pids/thin.pid
3   -address: 127.0.0.1
4   -user: noosfero
5   -timeout: 30
6   -port: 50000
7   -log: log/thin.log
8   -max_conns: 1024
9   -servers: 1
10   -max_persistent_conns: 512
11   -environment: production
12   -daemonize: true
13   -chdir: /usr/share/noosfero
config/unicorn.rb.dist 0 → 100644
... ... @@ -0,0 +1,5 @@
  1 +listen "127.0.0.1:3000"
  2 +
  3 +worker_processes 1
  4 +
  5 +# vim: ft=ruby
... ...
db/migrate/20151112135709_add_archived_to_articles.rb 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +class AddArchivedToArticles < ActiveRecord::Migration
  2 + def up
  3 + add_column :articles, :archived, :boolean, :default => false
  4 + end
  5 +
  6 + def down
  7 + remove_column :articles, :archived
  8 + end
  9 +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 => 20150812133432) do
  14 +ActiveRecord::Schema.define(:version => 20150918005035) do
15 15  
16 16 create_table "abuse_reports", :force => true do |t|
17 17 t.integer "reporter_id"
... ... @@ -110,6 +110,7 @@ ActiveRecord::Schema.define(:version =&gt; 20150812133432) do
110 110 t.integer "spam_comments_count", :default => 0
111 111 t.integer "author_id"
112 112 t.integer "created_by_id"
  113 + t.integer "followers_count"
113 114 end
114 115  
115 116 add_index "article_versions", ["article_id"], :name => "index_article_versions_on_article_id"
... ... @@ -165,6 +166,7 @@ ActiveRecord::Schema.define(:version =&gt; 20150812133432) do
165 166 t.boolean "show_to_followers", :default => true
166 167 t.integer "sash_id"
167 168 t.integer "level", :default => 0
  169 + t.integer "followers_count", :default => 0
168 170 end
169 171  
170 172 add_index "articles", ["comments_count"], :name => "index_articles_on_comments_count"
... ... @@ -422,6 +424,7 @@ ActiveRecord::Schema.define(:version =&gt; 20150812133432) do
422 424 t.string "owner_type"
423 425 t.datetime "created_at", :null => false
424 426 t.datetime "updated_at", :null => false
  427 + t.string "title"
425 428 end
426 429  
427 430 create_table "images", :force => true do |t|
... ... @@ -694,6 +697,20 @@ ActiveRecord::Schema.define(:version =&gt; 20150812133432) do
694 697 add_index "proposals_discussion_plugin_proposal_evaluations", ["evaluator_id"], :name => "index_proposals_discussion_plugin_proposal_evaluator_id"
695 698 add_index "proposals_discussion_plugin_proposal_evaluations", ["proposal_task_id"], :name => "index_proposals_discussion_plugin_proposal_task_id"
696 699  
  700 + create_table "proposals_discussion_plugin_ranking_items", :force => true do |t|
  701 + t.integer "position"
  702 + t.string "abstract"
  703 + t.integer "votes_for"
  704 + t.integer "votes_against"
  705 + t.integer "hits"
  706 + t.decimal "effective_support"
  707 + t.integer "proposal_id"
  708 + t.datetime "created_at", :null => false
  709 + t.datetime "updated_at", :null => false
  710 + end
  711 +
  712 + add_index "proposals_discussion_plugin_ranking_items", ["proposal_id"], :name => "index_proposals_discussion_plugin_ranking_proposal_id"
  713 +
697 714 create_table "proposals_discussion_plugin_task_categories", :id => false, :force => true do |t|
698 715 t.integer "task_id"
699 716 t.integer "category_id"
... ...
debian/apache2/conf.d/noosfero-cluster.conf
... ... @@ -1,8 +0,0 @@
1   -<Proxy balancer://noosfero>
2   - Include /etc/noosfero/apache/cluster.conf
3   - Order Allow,Deny
4   - Allow from All
5   -</Proxy>
6   -
7   -# vim: ft=apache
8   -
debian/apache2/virtualhost.conf
... ... @@ -15,7 +15,11 @@ RewriteRule ^/$ /index.html [QSA]
15 15 RewriteRule ^([^.]+)$ $1.html [QSA]
16 16  
17 17 RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
18   -RewriteRule ^.*$ balancer://noosfero%{REQUEST_URI} [P,QSA,L]
  18 +RewriteRule ^.*$ http://127.0.0.1:50000%{REQUEST_URI} [P,QSA,L]
  19 +<Proxy http://127.0.0.1:50000>
  20 + Order Allow,Deny
  21 + Allow from All
  22 +</Proxy>
19 23  
20 24 ErrorDocument 503 /503.html
21 25  
... ...
debian/changelog
  1 +noosfero (1.3) wheezy-test; urgency=low
  2 +
  3 + * Noosfero 1.3 final release
  4 +
  5 + -- Antonio Terceiro <terceiro@colivre.coop.br> Fri, 06 Nov 2015 09:19:34 -0300
  6 +
  7 +noosfero (1.3~rc3) wheezy-test; urgency=low
  8 +
  9 + * Noosfero 1.3 RC3
  10 +
  11 + -- Antonio Terceiro <terceiro@colivre.coop.br> Wed, 04 Nov 2015 12:44:22 -0300
  12 +
  13 +noosfero (1.3~rc2) wheezy-test; urgency=low
  14 +
  15 + * Noosfero 1.3 RC2
  16 +
  17 + -- Antonio Terceiro <terceiro@softwarelivre.org> Fri, 30 Oct 2015 15:57:14 -0300
  18 +
  19 +noosfero (1.3~rc1) wheezy-test; urgency=medium
  20 +
  21 + * Noosfero 1.3 RC1
  22 +
  23 + -- Antonio Terceiro <terceiro@colivre.coop.br> Fri, 09 Oct 2015 10:24:13 -0300
  24 +
1 25 noosfero (1.2) wheezy; urgency=low
2 26  
3 27 * Noosfero 1.2
... ...
debian/control
... ... @@ -49,12 +49,17 @@ Depends: adduser,
49 49 ruby-feedparser,
50 50 ruby-feedparser (>= 0.7-3~),
51 51 ruby-gettext,
  52 + ruby-grape,
  53 + ruby-grape-entity,
  54 + ruby-grape-logging,
52 55 ruby-memcache-client,
53 56 ruby-minitest,
54 57 ruby-nokogiri,
55 58 ruby-pg,
56 59 ruby-progressbar,
57 60 ruby-rack (>= 1.4.5-2~),
  61 + ruby-rack-contrib,
  62 + ruby-rack-cors,
58 63 ruby-rails-autolink,
59 64 ruby-redcloth,
60 65 ruby-rest-client,
... ... @@ -65,7 +70,7 @@ Depends: adduser,
65 70 ruby-whenever,
66 71 ruby-will-paginate (>= 2.3.12-1~),
67 72 tango-icon-theme,
68   - thin,
  73 + unicorn (>= 4.8),
69 74 ${misc:Depends}
70 75 Recommends: postgresql, postgresql-client
71 76 Description: free web-based platform for social networks
... ...
debian/noosfero-apache.install
1   -debian/apache2/conf.d/noosfero-cluster.conf etc/apache2/conf.d
2 1 debian/apache2/virtualhost.conf etc/noosfero/apache
3 2 debian/update-noosfero-apache usr/sbin
... ...
debian/noosfero.install
... ... @@ -19,7 +19,7 @@ debian/noosfero-check-dbconfig usr/sbin
19 19 debian/noosfero-console usr/sbin
20 20 debian/noosfero-runner usr/sbin
21 21 debian/noosfero.yml etc/noosfero
22   -debian/thin.yml etc/noosfero
  22 +debian/unicorn.rb etc/noosfero
23 23 doc usr/share/noosfero
24 24 doc/noosfero usr/share/noosfero/doc
25 25 etc/init.d/noosfero etc/init.d
... ...
debian/noosfero.links
1 1 var/tmp/noosfero usr/share/noosfero/tmp
2 2 var/log/noosfero usr/share/noosfero/log
3 3 etc/noosfero/database.yml usr/share/noosfero/config/database.yml
4   -etc/noosfero/thin.yml usr/share/noosfero/config/thin.yml
  4 +etc/noosfero/unicorn.rb usr/share/noosfero/config/unicorn.rb
5 5 etc/noosfero/plugins usr/share/noosfero/config/plugins
6 6 etc/noosfero/noosfero.yml usr/share/noosfero/config/noosfero.yml
7 7 etc/noosfero/local.rb usr/share/noosfero/config/local.rb
... ...
debian/noosfero.postinst
... ... @@ -10,23 +10,23 @@ makedir() {
10 10 }
11 11  
12 12  
13   -# migrate mongrel configuration to thin
14   -mongrel_config=/etc/noosfero/mongrel_cluster.yml
  13 +# migrate thin configuration to unicorn
  14 +unicorn_config=/etc/noosfero/unicorn.rb
15 15 thin_config=/etc/noosfero/thin.yml
16   -mongrel_orig_sha1=602c642c03f79349969c08330112a6f29d4c32aa
17   -if [ -r $mongrel_config ]; then
18   - mongrel_sha1=$(sha1sum $mongrel_config | awk '{print $1}')
19   - if [ "$mongrel_sha1" != "$mongrel_orig_sha1" ]; then
20   - port=$(awk '{ if ($1 == "port:") { print($2) } }' $mongrel_config)
21   - servers=$(awk '{ if ($1 == "servers:") { print($2) } }' $mongrel_config)
  16 +thin_orig_sha1=47cee6728a7896a13f4d66544086ab88b02e89a7
  17 +if [ -r $thin_config ]; then
  18 + thin_sha1=$(sha1sum $thin_config | awk '{print $1}')
  19 + if [ "$thin_sha1" != "$thin_orig_sha1" ]; then
  20 + port=$(awk '{ if ($1 == "port:") { print($2) } }' $thin_config)
  21 + servers=$(awk '{ if ($1 == "servers:") { print($2) } }' $thin_config)
22 22 if test -n "$port" && test "$port" -ne 50000 || test -n "$servers" && test "$servers" -ne 1 ; then
23   - # mongrel configuration was changed; update thin configuration
  23 + # thin configuration was changed; update unicorn configuration
24 24 # accordingly
25   - sed -i -e "s/port: .*/port: $port/" $thin_config
26   - sed -i -e "s/servers: .*/servers: $servers/" $thin_config
  25 + sed -i -e "s/listen.*/listen '127.0.0.1:$port'/" $unicorn_config
  26 + sed -i -e "s/worker_processes.*/worker_processes $servers/" $unicorn_config
27 27 fi
28 28 fi
29   - mv $mongrel_config $mongrel_config.bak
  29 + mv $thin_config $thin_config.bak
30 30 fi
31 31  
32 32 # create user noosfero in a portable way, while creating the log directory.
... ...
debian/thin.yml
... ... @@ -1,13 +0,0 @@
1   ----
2   -pid: tmp/pids/thin.pid
3   -address: 127.0.0.1
4   -user: noosfero
5   -timeout: 0
6   -port: 50000
7   -log: log/thin.log
8   -max_conns: 1024
9   -servers: 1
10   -max_persistent_conns: 512
11   -environment: production
12   -daemonize: true
13   -chdir: /usr/share/noosfero
debian/unicorn.rb 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +listen "127.0.0.1:50000"
  2 +
  3 +worker_processes `nproc`.to_i
... ...
debian/update-noosfero-apache
... ... @@ -2,20 +2,9 @@
2 2  
3 3 set -e
4 4  
5   -# automatically update configuration, but if package noosfero is also installed
  5 +# automatically update configuration, but only if package noosfero is also
  6 +# installed
6 7 if test -x /usr/share/noosfero/script/apacheconf; then
7   - datadir="/etc/noosfero/apache"
8   - mongrel_file="$datadir/mongrel.conf"
9   - cluster_file="$datadir/cluster.conf"
10   - if test -e "$cluster_file"; then
11   - echo "Overwriting $cluster_file ..."
12   - fi
13   - /usr/share/noosfero/script/apacheconf thin > "$cluster_file"
14   - if test -e "$mongrel_file"; then
15   - echo "Moving existing $mongrel_file away ..."
16   - mv "$mongrel_file" "$mongrel_file".bak
17   - (cd $datadir && ln -sf cluster.conf mongrel.conf)
18   - fi
19 8  
20 9 apache_site='/etc/apache2/sites-available/noosfero'
21 10 if ! test -e "$apache_site"; then
... ...
enable_participa_plugins
... ... @@ -1,32 +0,0 @@
1   -./script/noosfero-plugins disableall
2   -./script/noosfero-plugins enable breadcrumbs
3   -./script/noosfero-plugins enable comment_paragraph
4   -./script/noosfero-plugins enable container_block
5   -./script/noosfero-plugins enable dspace
6   -./script/noosfero-plugins enable oauth_client
7   -./script/noosfero-plugins enable piwik
8   -./script/noosfero-plugins enable relevant_content
9   -./script/noosfero-plugins enable sub_organizations
10   -./script/noosfero-plugins enable ckeditor_content
11   -./script/noosfero-plugins enable community_block
12   -./script/noosfero-plugins enable context_content
13   -./script/noosfero-plugins enable email_article
14   -./script/noosfero-plugins enable oauth_provider
15   -./script/noosfero-plugins enable proposals_discussion
16   -./script/noosfero-plugins enable require_auth_to_comment
17   -./script/noosfero-plugins enable video
18   -./script/noosfero-plugins enable comment_classification
19   -./script/noosfero-plugins enable community_hub
20   -./script/noosfero-plugins enable custom_forms
21   -./script/noosfero-plugins enable import_data
22   -./script/noosfero-plugins enable pairwise
23   -./script/noosfero-plugins enable site_tour
24   -./script/noosfero-plugins enable vote
25   -./script/noosfero-plugins enable comment_group
26   -./script/noosfero-plugins enable community_track
27   -./script/noosfero-plugins enable display_content
28   -./script/noosfero-plugins enable mark_comment_as_read
29   -./script/noosfero-plugins enable pg_search
30   -./script/noosfero-plugins enable recent_content
31   -./script/noosfero-plugins enable statistics
32   -./script/noosfero-plugins enable work_assignment