Commit 14c2d322aff60f054b3f2d672286081e35496609
Exists in
master
and in
29 other branches
Merge branch 'master_colivre' into ActionItem2823_merge
Showing
120 changed files
with
1333 additions
and
482 deletions
Show diff stats
Too many changes.
To preserve performance only 100 of 120 files displayed.
COPYRIGHT
... | ... | @@ -4,8 +4,9 @@ Copyright (c) 2007-2009, |
4 | 4 | Cáritas Brasileira <http://www.caritasbrasileira.org/> |
5 | 5 | Copyright (c) 2007-2009, |
6 | 6 | Ynternet.org Foundation <http://www.ynternet.org/> |
7 | -Copyright (c) 2008-2009, | |
7 | +Copyright (c) 2008-2013, | |
8 | 8 | Colivre <http://www.colivre.coop.br/> |
9 | +Copyright (c) the Noosfero contributors. See AUTHORS | |
9 | 10 | |
10 | 11 | This program is free software: you can redistribute it and/or modify |
11 | 12 | it under the terms of the GNU Affero General Public License as published by | ... | ... |
HACKING
... | ... | @@ -52,3 +52,12 @@ If you write such script for your own OS, *please* share it with us at the |
52 | 52 | development mailing list so that we can include it in the official repository. |
53 | 53 | This way other people using the same OS will have to put less effort to develop |
54 | 54 | Noosfero. |
55 | + | |
56 | +== Submitting your changes back | |
57 | + | |
58 | +For now please read: | |
59 | + | |
60 | +- Coding conventions | |
61 | + http://noosfero.org/Development/CodingConventions | |
62 | +- Patch guidelines | |
63 | + http://noosfero.org/Development/PatchGuidelines | ... | ... |
HACKING.rails235
... | ... | @@ -1,13 +0,0 @@ |
1 | -This is a draft of how to create a environment to Rails 2.3.5 to Noosfero | |
2 | -development. | |
3 | - | |
4 | -Install dependencies: | |
5 | - | |
6 | -gem install rails -v 2.3.5 | |
7 | -gem install i18n | |
8 | -gem install will_paginate -v 2.3.12 | |
9 | -gem install cucumber | |
10 | - | |
11 | -Creating initial environment: | |
12 | - | |
13 | -rake db:schema:load |
README
1 | -noosfero - a web-based social platform | |
1 | +Noosfero - a web-based social platform | |
2 | 2 | ====================================== |
3 | 3 | |
4 | -:: About the project | |
4 | +http://www.noosfero.org/ | |
5 | 5 | |
6 | -Homepage: http://www.noosfero.org/ | |
6 | +Documentation | |
7 | +------------- | |
7 | 8 | |
8 | -:: Authors and copyright | |
9 | +The following documentation is available: | |
9 | 10 | |
10 | -Authors: see file AUTHORS | |
11 | -Copyright information: see file COPYRIGHT | |
12 | -Full license text; see file COPYING | |
11 | +File Purpose | |
12 | +~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
13 | +INSTALL install instructions | |
14 | +INSTALL.awstats install instructions - access statistics service | |
15 | +INSTALL.chat install instructions - chat service | |
16 | +INSTALL.email install instructions - email service | |
17 | +INSTALL.multitenancy install instructions - multiple sites | |
18 | +INSTALL.varnish install instructions - varnish HTTP caching (recommended) | |
19 | +HACKING development instruction | |
20 | +RELEASING instructions for doing releases | |
21 | +doc/noosfero/* user documentation (available through the app itself) | |
22 | + | |
23 | + | |
24 | +Authors and copyright | |
25 | +--------------------- | |
26 | + | |
27 | +Authorship and copyright information is available in the files listed below. | |
28 | + | |
29 | +File Purpose | |
30 | +~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
31 | +AUTHORS list of authors (updated at each release) | |
32 | +COPYRIGHT Copyright statement for the project | |
33 | +COPYING Full text of the project license | ... | ... |
app/controllers/my_profile/cms_controller.rb
... | ... | @@ -267,7 +267,10 @@ class CmsController < MyProfileController |
267 | 267 | @back_to = params[:back_to] || request.referer || url_for(profile.public_profile_url) |
268 | 268 | @task = SuggestArticle.new(params[:task]) |
269 | 269 | if request.post? |
270 | - @task.target = profile | |
270 | + @task.target = profile | |
271 | + @task.ip_address = request.remote_ip | |
272 | + @task.user_agent = request.user_agent | |
273 | + @task.referrer = request.referrer | |
271 | 274 | if verify_recaptcha(:model => @task, :message => _('Please type the words correctly')) && @task.save |
272 | 275 | session[:notice] = _('Thanks for your suggestion. The community administrators were notified.') |
273 | 276 | redirect_to @back_to | ... | ... |
app/controllers/my_profile/profile_editor_controller.rb
... | ... | @@ -4,7 +4,7 @@ class ProfileEditorController < MyProfileController |
4 | 4 | protect 'destroy_profile', :profile, :only => [:destroy_profile] |
5 | 5 | |
6 | 6 | def index |
7 | - @pending_tasks = Task.to(profile).pending.select{|i| user.has_permission?(i.permission, profile)} | |
7 | + @pending_tasks = Task.to(profile).pending.without_spam.select{|i| user.has_permission?(i.permission, profile)} | |
8 | 8 | end |
9 | 9 | |
10 | 10 | helper :profile | ... | ... |
app/controllers/my_profile/spam_controller.rb
... | ... | @@ -14,9 +14,15 @@ class SpamController < MyProfileController |
14 | 14 | if params[:remove_comment] |
15 | 15 | profile.comments_received.find(params[:remove_comment]).destroy |
16 | 16 | end |
17 | + if params[:remove_task] | |
18 | + Task.to(profile).find_by_id(params[:remove_task]).destroy | |
19 | + end | |
17 | 20 | if params[:mark_comment_as_ham] |
18 | 21 | profile.comments_received.find(params[:mark_comment_as_ham]).ham! |
19 | 22 | end |
23 | + if params[:mark_task_as_ham] && (t = Task.to(profile).find_by_id(params[:mark_task_as_ham])) | |
24 | + t.ham! | |
25 | + end | |
20 | 26 | if request.xhr? |
21 | 27 | json_response(true) |
22 | 28 | else |
... | ... | @@ -28,7 +34,8 @@ class SpamController < MyProfileController |
28 | 34 | return |
29 | 35 | end |
30 | 36 | |
31 | - @spam = profile.comments_received.spam.paginate({:page => params[:page]}) | |
37 | + @comment_spam = profile.comments_received.spam.paginate({:page => params[:comments_page]}) | |
38 | + @task_spam = Task.to(profile).spam.paginate({:page => params[:tasks_page]}) | |
32 | 39 | end |
33 | 40 | |
34 | 41 | protected | ... | ... |
app/controllers/my_profile/tasks_controller.rb
... | ... | @@ -4,12 +4,12 @@ class TasksController < MyProfileController |
4 | 4 | |
5 | 5 | def index |
6 | 6 | @filter = params[:filter_type].blank? ? nil : params[:filter_type] |
7 | - @tasks = Task.to(profile).pending.of(@filter).order_by('created_at', 'asc').paginate(:per_page => Task.per_page, :page => params[:page]) | |
7 | + @tasks = Task.to(profile).without_spam.pending.of(@filter).order_by('created_at', 'asc').paginate(:per_page => Task.per_page, :page => params[:page]) | |
8 | 8 | @failed = params ? params[:failed] : {} |
9 | 9 | end |
10 | 10 | |
11 | 11 | def processed |
12 | - @tasks = Task.to(profile).closed.sort_by(&:created_at) | |
12 | + @tasks = Task.to(profile).without_spam.closed.sort_by(&:created_at) | |
13 | 13 | end |
14 | 14 | |
15 | 15 | VALID_DECISIONS = [ 'finish', 'cancel', 'skip' ] |
... | ... | @@ -57,7 +57,7 @@ class TasksController < MyProfileController |
57 | 57 | end |
58 | 58 | |
59 | 59 | def list_requested |
60 | - @tasks = Task.find_all_by_requestor_id(profile.id) | |
60 | + @tasks = Task.without_spam.find_all_by_requestor_id(profile.id) | |
61 | 61 | end |
62 | 62 | |
63 | 63 | def ticket_details | ... | ... |
app/controllers/public/content_viewer_controller.rb
... | ... | @@ -53,7 +53,9 @@ class ContentViewerController < ApplicationController |
53 | 53 | # At this point the page will be showed |
54 | 54 | @page.hit |
55 | 55 | |
56 | - unless @page.mime_type == 'text/html' || (@page.image? && params[:view]) | |
56 | + @page = FilePresenter.for @page | |
57 | + | |
58 | + unless @page.mime_type == 'text/html' || params[:view] | |
57 | 59 | headers['Content-Type'] = @page.mime_type |
58 | 60 | data = @page.data |
59 | 61 | ... | ... |
app/helpers/application_helper.rb
... | ... | @@ -558,6 +558,9 @@ module ApplicationHelper |
558 | 558 | # displays a link to the profile homepage with its image (as generated by |
559 | 559 | # #profile_image) and its name below it. |
560 | 560 | def profile_image_link( profile, size=:portrait, tag='li', extra_info = nil ) |
561 | + if content = @plugins.dispatch_first(:profile_image_link, profile, size, tag, extra_info) | |
562 | + return instance_eval(&content) | |
563 | + end | |
561 | 564 | name = profile.short_name |
562 | 565 | if profile.person? |
563 | 566 | url = url_for(profile.check_friendship_url) |
... | ... | @@ -574,16 +577,16 @@ module ApplicationHelper |
574 | 577 | extra_info = extra_info.nil? ? '' : content_tag( 'span', extra_info, :class => 'extra_info' ) |
575 | 578 | links = links_for_balloon(profile) |
576 | 579 | content_tag('div', content_tag(tag, |
577 | - (environment.enabled?(:show_balloon_with_profile_links_when_clicked) ? link_to( content_tag( 'span', _('Profile links')), '#', :onclick => "toggleSubmenu(this, '#{profile.short_name}', #{links.to_json}); return false", :class => "menu-submenu-trigger #{trigger_class}", :url => url) : "") + | |
578 | - link_to( | |
579 | - content_tag( 'span', profile_image( profile, size ), :class => 'profile-image' ) + | |
580 | - content_tag( 'span', h(name), :class => ( profile.class == Person ? 'fn' : 'org' ) ) + | |
581 | - extra_info + profile_sex_icon( profile ) + profile_cat_icons( profile ), | |
582 | - profile.url, | |
583 | - :class => 'profile_link url', | |
584 | - :help => _('Click on this icon to go to the <b>%s</b>\'s home page') % profile.name, | |
585 | - :title => profile.name ), | |
586 | - :class => 'vcard'), :class => 'common-profile-list-block') | |
580 | + (environment.enabled?(:show_balloon_with_profile_links_when_clicked) ? link_to( content_tag( 'span', _('Profile links')), '#', :onclick => "toggleSubmenu(this, '#{profile.short_name}', #{links.to_json}); return false", :class => "menu-submenu-trigger #{trigger_class}", :url => url) : "") + | |
581 | + link_to( | |
582 | + content_tag( 'span', profile_image( profile, size ), :class => 'profile-image' ) + | |
583 | + content_tag( 'span', h(name), :class => ( profile.class == Person ? 'fn' : 'org' ) ) + | |
584 | + extra_info + profile_sex_icon( profile ) + profile_cat_icons( profile ), | |
585 | + profile.url, | |
586 | + :class => 'profile_link url', | |
587 | + :help => _('Click on this icon to go to the <b>%s</b>\'s home page') % profile.name, | |
588 | + :title => profile.name ), | |
589 | + :class => 'vcard'), :class => 'common-profile-list-block') | |
587 | 590 | end |
588 | 591 | |
589 | 592 | def gravatar_url_for(email, options = {}) |
... | ... | @@ -1113,15 +1116,34 @@ module ApplicationHelper |
1113 | 1116 | result |
1114 | 1117 | end |
1115 | 1118 | |
1116 | - def manage_enterprises | |
1117 | - if user && !user.enterprises.empty? | |
1118 | - enterprises_link = user.enterprises.map do |enterprise| | |
1119 | - link_to(content_tag('strong', [_('<span>Manage</span> %s') % enterprise.short_name(25)]), @environment.top_url + "/myprofile/#{enterprise.identifier}", :class => "icon-menu-"+enterprise.class.identification.underscore, :title => [_('Manage %s') % enterprise.short_name]) | |
1119 | + def manage_link(list, kind) | |
1120 | + if list.present? | |
1121 | + link_to_all = nil | |
1122 | + if list.count > 5 | |
1123 | + list = list.first(5) | |
1124 | + link_to_all = link_to(content_tag('strong', _('See all')), :controller => 'memberships', :profile => current_user.login) | |
1125 | + end | |
1126 | + link = list.map do |element| | |
1127 | + link_to(content_tag('strong', [_('<span>Manage</span> %s') % element.short_name(25)]), @environment.top_url + "/myprofile/#{element.identifier}", :class => "icon-menu-"+element.class.identification.underscore, :title => [_('Manage %s') % element.short_name]) | |
1120 | 1128 | end |
1121 | - render :partial => 'shared/manage_enterprises', :locals => {:enterprises_link => enterprises_link} | |
1129 | + if link_to_all | |
1130 | + link << link_to_all | |
1131 | + end | |
1132 | + render :partial => "shared/manage_link", :locals => {:link => link, :kind => kind.to_s} | |
1122 | 1133 | end |
1123 | 1134 | end |
1124 | 1135 | |
1136 | + def manage_enterprises | |
1137 | + return if not user | |
1138 | + manage_link(user.enterprises, :enterprises) | |
1139 | + end | |
1140 | + | |
1141 | + def manage_communities | |
1142 | + return if not user | |
1143 | + administered_communities = user.communities.more_popular.select {|c| c.admins.include? user} | |
1144 | + manage_link(administered_communities, :communities) | |
1145 | + end | |
1146 | + | |
1125 | 1147 | def usermenu_logged_in |
1126 | 1148 | pending_tasks_count = '' |
1127 | 1149 | count = user ? Task.to(user).pending.count : -1 |
... | ... | @@ -1133,6 +1155,7 @@ module ApplicationHelper |
1133 | 1155 | render_environment_features(:usermenu) + |
1134 | 1156 | link_to('<i class="icon-menu-admin"></i><strong>' + _('Administration') + '</strong>', @environment.top_url + '/admin', :id => "controlpanel", :title => _("Configure the environment"), :class => 'admin-link', :style => 'display: none') + |
1135 | 1157 | manage_enterprises.to_s + |
1158 | + manage_communities.to_s + | |
1136 | 1159 | link_to('<i class="icon-menu-ctrl-panel"></i><strong>' + _('Control panel') + '</strong>', @environment.top_url + '/myprofile/{login}', :id => "controlpanel", :title => _("Configure your personal account and content")) + |
1137 | 1160 | pending_tasks_count + |
1138 | 1161 | link_to('<i class="icon-menu-logout"></i><strong>' + _('Logout') + '</strong>', { :controller => 'account', :action => 'logout'} , :id => "logout", :title => _("Leave the system")) | ... | ... |
app/helpers/blog_helper.rb
... | ... | @@ -42,7 +42,7 @@ module BlogHelper |
42 | 42 | |
43 | 43 | def display_post(article, format = 'full') |
44 | 44 | no_comments = (format == 'full') ? false : true |
45 | - html = send("display_#{format}_format", article).html_safe | |
45 | + html = send("display_#{format}_format", FilePresenter.for(article)).html_safe | |
46 | 46 | |
47 | 47 | article_title(article, :no_comments => no_comments) + html |
48 | 48 | end | ... | ... |
app/helpers/cms_helper.rb
... | ... | @@ -33,7 +33,7 @@ module CmsHelper |
33 | 33 | link_to article_name, {:action => 'view', :id => article.id}, :class => icon_for_article(article) |
34 | 34 | else |
35 | 35 | if article.image? |
36 | - image_tag(icon_for_article(article)) + link_to(article_name, article.url) | |
36 | + image_tag(icon_for_article(article)) + link_to(article_name, article.url) | |
37 | 37 | else |
38 | 38 | link_to article_name, article.url, :class => icon_for_article(article) |
39 | 39 | end | ... | ... |
app/helpers/content_viewer_helper.rb
... | ... | @@ -17,7 +17,7 @@ module ContentViewerHelper |
17 | 17 | title = article.display_title if article.kind_of?(UploadedFile) && article.image? |
18 | 18 | title = article.title if title.blank? |
19 | 19 | title = content_tag('h1', h(title), :class => 'title') |
20 | - if article.belongs_to_blog? | |
20 | + if article.belongs_to_blog? || article.belongs_to_forum? | |
21 | 21 | unless args[:no_link] |
22 | 22 | title = content_tag('h1', link_to(article.name, article.url), :class => 'title') |
23 | 23 | end | ... | ... |
app/helpers/folder_helper.rb
... | ... | @@ -21,6 +21,7 @@ module FolderHelper |
21 | 21 | end |
22 | 22 | |
23 | 23 | def display_article_in_listing(article, recursive = false, level = 0) |
24 | + article = FilePresenter.for article | |
24 | 25 | article_link = if article.image? |
25 | 26 | link_to(' ' * (level * 4) + image_tag(icon_for_article(article)) + short_filename(article.name), article.url.merge(:view => true)) |
26 | 27 | else |
... | ... | @@ -40,12 +41,15 @@ module FolderHelper |
40 | 41 | end |
41 | 42 | |
42 | 43 | def icon_for_article(article) |
43 | - icon = article.class.icon_name(article) | |
44 | + article = FilePresenter.for article | |
45 | + icon = article.respond_to?(:icon_name) ? | |
46 | + article.icon_name : | |
47 | + article.class.icon_name(article) | |
44 | 48 | if (icon =~ /\//) |
45 | 49 | icon |
46 | 50 | else |
47 | - klasses = 'icon icon-' + icon | |
48 | - if article.kind_of?(UploadedFile) | |
51 | + klasses = 'icon ' + [icon].flatten.map{|name| 'icon-'+name}.join(' ') | |
52 | + if article.kind_of?(UploadedFile) || article.kind_of?(FilePresenter) | |
49 | 53 | klasses += ' icon-upload-file' |
50 | 54 | end |
51 | 55 | klasses | ... | ... |
app/models/article.rb
... | ... | @@ -154,8 +154,12 @@ class Article < ActiveRecord::Base |
154 | 154 | end |
155 | 155 | end |
156 | 156 | |
157 | + def css_class_list | |
158 | + [self.class.name.underscore.dasherize] | |
159 | + end | |
160 | + | |
157 | 161 | def css_class_name |
158 | - self.class.name.underscore.dasherize | |
162 | + [css_class_list].flatten.compact.join(' ') | |
159 | 163 | end |
160 | 164 | |
161 | 165 | def pending_categorizations |
... | ... | @@ -310,6 +314,10 @@ class Article < ActiveRecord::Base |
310 | 314 | def belongs_to_blog? |
311 | 315 | self.parent and self.parent.blog? |
312 | 316 | end |
317 | + | |
318 | + def belongs_to_forum? | |
319 | + self.parent and self.parent.forum? | |
320 | + end | |
313 | 321 | |
314 | 322 | def info_from_last_update |
315 | 323 | last_comment = comments.last |
... | ... | @@ -325,7 +333,7 @@ class Article < ActiveRecord::Base |
325 | 333 | end |
326 | 334 | |
327 | 335 | def view_url |
328 | - @view_url ||= image? ? url.merge(:view => true) : url | |
336 | + @view_url ||= is_a?(UploadedFile) ? url.merge(:view => true) : url | |
329 | 337 | end |
330 | 338 | |
331 | 339 | def comment_url_structure(comment, action = :edit) | ... | ... |
app/models/article_block.rb
... | ... | @@ -12,7 +12,7 @@ class ArticleBlock < Block |
12 | 12 | block = self |
13 | 13 | lambda do |
14 | 14 | block_title(block.title) + |
15 | - (block.article ? article_to_html(block.article, | |
15 | + (block.article ? article_to_html(FilePresenter.for(block.article), | |
16 | 16 | :gallery_view => false, |
17 | 17 | :inside_block => block, # For Blogs and folders |
18 | 18 | :format => block.visualization_format # For Articles and contents | ... | ... |
app/models/comment.rb
... | ... | @@ -16,9 +16,7 @@ class Comment < ActiveRecord::Base |
16 | 16 | has_many :children, :class_name => 'Comment', :foreign_key => 'reply_of_id', :dependent => :destroy |
17 | 17 | belongs_to :reply_of, :class_name => 'Comment', :foreign_key => 'reply_of_id' |
18 | 18 | |
19 | - named_scope :without_spam, :conditions => ['spam IS NULL OR spam = ?', false] | |
20 | 19 | named_scope :without_reply, :conditions => ['reply_of_id IS NULL'] |
21 | - named_scope :spam, :conditions => ['spam = ?', true] | |
22 | 20 | |
23 | 21 | # unauthenticated authors: |
24 | 22 | validates_presence_of :name, :if => (lambda { |record| !record.email.blank? }) |
... | ... | @@ -108,6 +106,17 @@ class Comment < ActiveRecord::Base |
108 | 106 | |
109 | 107 | include Noosfero::Plugin::HotSpot |
110 | 108 | |
109 | + include Spammable | |
110 | + | |
111 | + def after_spam! | |
112 | + SpammerLogger.log(ip_address, self) | |
113 | + Delayed::Job.enqueue(CommentHandler.new(self.id, :marked_as_spam)) | |
114 | + end | |
115 | + | |
116 | + def after_ham! | |
117 | + Delayed::Job.enqueue(CommentHandler.new(self.id, :marked_as_ham)) | |
118 | + end | |
119 | + | |
111 | 120 | def verify_and_notify |
112 | 121 | check_for_spam |
113 | 122 | unless spam? |
... | ... | @@ -115,10 +124,6 @@ class Comment < ActiveRecord::Base |
115 | 124 | end |
116 | 125 | end |
117 | 126 | |
118 | - def check_for_spam | |
119 | - plugins.dispatch(:check_comment_for_spam, self) | |
120 | - end | |
121 | - | |
122 | 127 | def notify_by_mail |
123 | 128 | if source.kind_of?(Article) && article.notify_comments? |
124 | 129 | if !notification_emails.empty? |
... | ... | @@ -205,37 +210,6 @@ class Comment < ActiveRecord::Base |
205 | 210 | @rejected = true |
206 | 211 | end |
207 | 212 | |
208 | - def spam? | |
209 | - !spam.nil? && spam | |
210 | - end | |
211 | - | |
212 | - def ham? | |
213 | - !spam.nil? && !spam | |
214 | - end | |
215 | - | |
216 | - def spam! | |
217 | - self.spam = true | |
218 | - self.save! | |
219 | - SpammerLogger.log(ip_address, self) | |
220 | - Delayed::Job.enqueue(CommentHandler.new(self.id, :marked_as_spam)) | |
221 | - self | |
222 | - end | |
223 | - | |
224 | - def ham! | |
225 | - self.spam = false | |
226 | - self.save! | |
227 | - Delayed::Job.enqueue(CommentHandler.new(self.id, :marked_as_ham)) | |
228 | - self | |
229 | - end | |
230 | - | |
231 | - def marked_as_spam | |
232 | - plugins.dispatch(:comment_marked_as_spam, self) | |
233 | - end | |
234 | - | |
235 | - def marked_as_ham | |
236 | - plugins.dispatch(:comment_marked_as_ham, self) | |
237 | - end | |
238 | - | |
239 | 213 | def need_moderation? |
240 | 214 | article.moderate_comments? && (author.nil? || article.author != author) |
241 | 215 | end | ... | ... |
app/models/spammer_logger.rb
... | ... | @@ -6,6 +6,8 @@ class SpammerLogger < Logger |
6 | 6 | if object |
7 | 7 | if object.kind_of?(Comment) |
8 | 8 | @logger << "[#{Time.now.strftime('%F %T %z')}] Comment-id: #{object.id} IP: #{spammer_ip}\n" |
9 | + elsif object.kind_of?(SuggestArticle) | |
10 | + @logger << "[#{Time.now.strftime('%F %T %z')}] SuggestArticle-id: #{object.id} IP: #{spammer_ip}\n" | |
9 | 11 | end |
10 | 12 | else |
11 | 13 | @logger << "[#{Time.now.strftime('%F %T %z')}] IP: #{spammer_ip}\n" | ... | ... |
app/models/suggest_article.rb
... | ... | @@ -11,6 +11,17 @@ class SuggestArticle < Task |
11 | 11 | settings_items :source, :type => String |
12 | 12 | settings_items :source_name, :type => String |
13 | 13 | settings_items :highlighted, :type => :boolean, :default => false |
14 | + settings_items :ip_address, :type => String | |
15 | + settings_items :user_agent, :type => String | |
16 | + settings_items :referrer, :type => String | |
17 | + | |
18 | + after_create :schedule_spam_checking | |
19 | + | |
20 | + def schedule_spam_checking | |
21 | + self.delay.check_for_spam | |
22 | + end | |
23 | + | |
24 | + include Noosfero::Plugin::HotSpot | |
14 | 25 | |
15 | 26 | def sender |
16 | 27 | "#{name} (#{email})" |
... | ... | @@ -61,4 +72,12 @@ class SuggestArticle < Task |
61 | 72 | _('You need to login on %{system} in order to approve or reject this article.') % { :system => target.environment.name } |
62 | 73 | end |
63 | 74 | |
75 | + def after_spam! | |
76 | + SpammerLogger.log(ip_address, self) | |
77 | + self.delay.marked_as_spam | |
78 | + end | |
79 | + | |
80 | + def after_ham! | |
81 | + self.delay.marked_as_ham | |
82 | + end | |
64 | 83 | end | ... | ... |
app/models/task.rb
... | ... | @@ -235,6 +235,8 @@ class Task < ActiveRecord::Base |
235 | 235 | end |
236 | 236 | end |
237 | 237 | |
238 | + include Spammable | |
239 | + | |
238 | 240 | protected |
239 | 241 | |
240 | 242 | # This method must be overrided in subclasses, and its implementation must do |
... | ... | @@ -275,6 +277,7 @@ class Task < ActiveRecord::Base |
275 | 277 | named_scope :of, lambda { |type| conditions = type ? "type LIKE '#{type}'" : "1=1"; {:conditions => [conditions]} } |
276 | 278 | named_scope :order_by, lambda { |attribute, ord| {:order => "#{attribute} #{ord}"} } |
277 | 279 | |
280 | + | |
278 | 281 | named_scope :to, lambda { |profile| |
279 | 282 | environment_condition = nil |
280 | 283 | if profile.person? | ... | ... |
app/models/uploaded_file.rb
... | ... | @@ -60,12 +60,20 @@ class UploadedFile < Article |
60 | 60 | |
61 | 61 | postgresql_attachment_fu |
62 | 62 | |
63 | + # Use this method only to get the generic icon for this kind of content. | |
64 | + # If you want the specific icon for a file type or the iconified version | |
65 | + # of an image, use FilePresenter.for(uploaded_file).icon_name | |
63 | 66 | def self.icon_name(article = nil) |
64 | - if article | |
65 | - article.image? ? article.public_filename(:icon) : (article.mime_type ? article.mime_type.gsub(/[\/+.]/, '-') : 'upload-file') | |
66 | - else | |
67 | - 'upload-file' | |
67 | + unless article.nil? | |
68 | + warn = ('='*80) + "\n" + | |
69 | + 'The method `UploadedFile.icon_name(obj)` is deprecated. ' + | |
70 | + 'You must to encapsulate UploadedFile with `FilePresenter.for()`.' + | |
71 | + "\n" + ('='*80) | |
72 | + raise NoMethodError, warn if ENV['RAILS_ENV'] == 'test' | |
73 | + Rails.logger.warn warn if Rails.logger | |
74 | + puts warn if ENV['RAILS_ENV'] == 'development' | |
68 | 75 | end |
76 | + 'upload-file' | |
69 | 77 | end |
70 | 78 | |
71 | 79 | def mime_type |
... | ... | @@ -91,40 +99,27 @@ class UploadedFile < Article |
91 | 99 | end |
92 | 100 | |
93 | 101 | def to_html(options = {}) |
102 | + warn = ('='*80) + "\n" + | |
103 | + 'The method `UploadedFile#to_html()` is deprecated. ' + | |
104 | + 'You must to encapsulate UploadedFile with `FilePresenter.for()`.' + | |
105 | + "\n" + ('='*80) | |
106 | + raise NoMethodError, warn if ENV['RAILS_ENV'] == 'test' | |
107 | + Rails.logger.warn warn if Rails.logger | |
108 | + puts warn if ENV['RAILS_ENV'] == 'development' | |
94 | 109 | article = self |
95 | 110 | if image? |
96 | 111 | lambda do |
97 | - if article.gallery? && options[:gallery_view] | |
98 | - images = article.parent.images | |
99 | - current_index = images.index(article) | |
100 | - total_of_images = images.count | |
101 | - | |
102 | - link_to_previous = if current_index >= 1 | |
103 | - link_to(_('« Previous'), images[current_index - 1].view_url, :class => 'left') | |
104 | - else | |
105 | - content_tag('span', _('« Previous'), :class => 'left') | |
106 | - end | |
107 | - | |
108 | - link_to_next = if current_index < total_of_images - 1 | |
109 | - link_to(_('Next »'), images[current_index + 1].view_url, :class => 'right') | |
110 | - else | |
111 | - content_tag('span', _('Next »'), :class => 'right') | |
112 | - end | |
113 | - | |
114 | - content_tag( | |
115 | - 'div', | |
116 | - link_to_previous + (content_tag('span', _('image %d of %d'), :class => 'total-of-images') % [current_index + 1, total_of_images]).html_safe + link_to_next, | |
117 | - :class => 'gallery-navigation' | |
118 | - ) | |
119 | - end.to_s + | |
120 | - image_tag(article.public_filename(:display), :class => article.css_class_name, :style => 'max-width: 100%') + | |
121 | - content_tag('p', article.abstract, :class => 'uploaded-file-description') | |
122 | - | |
112 | + image_tag(article.public_filename(:display), | |
113 | + :class => article.css_class_name, | |
114 | + :style => 'max-width: 100%') + | |
115 | + content_tag('div', article.abstract, :class => 'uploaded-file-description') | |
123 | 116 | end |
124 | 117 | else |
125 | 118 | lambda do |
126 | - content_tag('ul', content_tag('li', link_to(article.name, article.url, :class => article.css_class_name))) + | |
127 | - content_tag('p', article.abstract, :class => 'uploaded-file-description') | |
119 | + content_tag('div', | |
120 | + link_to(article.name, article.url), | |
121 | + :class => article.css_class_name) + | |
122 | + content_tag('div', article.abstract, :class => 'uploaded-file-description') | |
128 | 123 | end |
129 | 124 | end |
130 | 125 | end | ... | ... |
... | ... | @@ -0,0 +1,14 @@ |
1 | +class FilePresenter::Image < FilePresenter | |
2 | + def self.accepts?(f) | |
3 | + return nil unless f.respond_to? :image? | |
4 | + f.image? ? 10 : nil | |
5 | + end | |
6 | + | |
7 | + def icon_name | |
8 | + public_filename :icon | |
9 | + end | |
10 | + | |
11 | + def short_description | |
12 | + _('Image (%s)') % content_type.split('/')[1].upcase | |
13 | + end | |
14 | +end | ... | ... |
app/views/cms/view.rhtml
... | ... | @@ -40,13 +40,16 @@ |
40 | 40 | </tr> |
41 | 41 | <% end %> |
42 | 42 | |
43 | - <% @articles.each do |article| %> | |
43 | + <% @articles.each do |article| article = FilePresenter.for article %> | |
44 | 44 | <tr title="<%= article.title%>" > |
45 | - <td> | |
45 | + <td class="article-name"> | |
46 | 46 | <%= link_to_article(article) %> |
47 | 47 | </td> |
48 | - <td> | |
49 | - <%= article.class.short_description %> | |
48 | + <% short_description = article.respond_to?(:short_description) ? | |
49 | + article.short_description : | |
50 | + article.class.short_description %> | |
51 | + <td class="article-mime" title=<%= short_description.to_json %>> | |
52 | + <%= short_description %> | |
50 | 53 | </td> |
51 | 54 | <td class="article-controls"> |
52 | 55 | <%= expirable_button article, :edit, _('Edit'), {:action => 'edit', :id => article.id} if !remove_content_button(:edit) %> | ... | ... |
... | ... | @@ -0,0 +1,9 @@ |
1 | +<span class="download-link"> | |
2 | + <span>Download</span> | |
3 | + <strong><%= link_to generic.filename, generic.public_filename %></strong> | |
4 | +</span> | |
5 | + | |
6 | +<div class="uploaded-file-description <%= 'empty' if generic.abstract.blank? %>"> | |
7 | + <%= generic.abstract %> | |
8 | +</div> | |
9 | + | ... | ... |
... | ... | @@ -0,0 +1,36 @@ |
1 | +<% if image.gallery? && options[:gallery_view] %> | |
2 | +<% | |
3 | + images = image.parent.images | |
4 | + current_index = images.index(image.encapsulated_file) | |
5 | + total_of_images = images.count | |
6 | + link_to_previous = if current_index >= 1 | |
7 | + link_to(_('« Previous'), images[current_index - 1].view_url, :class => 'previous') | |
8 | + else | |
9 | + content_tag('span', _('« Previous'), :class => 'previous') | |
10 | + end | |
11 | + | |
12 | + link_to_next = if current_index < total_of_images - 1 | |
13 | + link_to(_('Next »'), images[current_index + 1].view_url, :class => 'next') | |
14 | + else | |
15 | + content_tag('span', _('Next »'), :class => 'next') | |
16 | + end | |
17 | +%> | |
18 | + | |
19 | +<div class="gallery-navigation"> | |
20 | + <%= link_to_previous %> | |
21 | + <span class="total-of-images"> | |
22 | + <%= _('image %d of %d') % [current_index + 1, total_of_images] %> | |
23 | + </span> | |
24 | + <%= link_to_next %> | |
25 | +</div> | |
26 | + | |
27 | +<% end %> | |
28 | + | |
29 | +<%# image_tag(article.public_filename(:display), :class => article.css_class_name, :style => 'max-width: 100%') %> | |
30 | + | |
31 | +<img src="<%=image.public_filename(:display)%>" class="<%=image.css_class_name%>"> | |
32 | + | |
33 | +<div class="uploaded-file-description <%= 'empty' if image.abstract.blank? %>"> | |
34 | + <%= image.abstract %> | |
35 | +</div> | |
36 | + | ... | ... |
app/views/shared/_manage_enterprises.rhtml
... | ... | @@ -1,8 +0,0 @@ |
1 | -<div id='manage-enterprises'> | |
2 | - <a href="#" id='manage-enterprises-link' class='simplemenu-trigger' title='<%= _('Manage enterprises') %>'><i class="icon-menu-enterprise"></i><strong><%= ui_icon('ui-icon-triangle-1-s') + _('My enterprises') %></strong></a> | |
3 | - <ul class='simplemenu-submenu'> | |
4 | - <% enterprises_link.each do |link| %> | |
5 | - <li class='simplemenu-item'><%= link %></li> | |
6 | - <% end %> | |
7 | - </ul> | |
8 | -</div> |
... | ... | @@ -0,0 +1,8 @@ |
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> | |
3 | + <ul class="simplemenu-submenu"> | |
4 | + <% link.each do |link| %> | |
5 | + <li class="simplemenu-item"><%= link %></li> | |
6 | + <% end %> | |
7 | + </ul> | |
8 | +</div> | ... | ... |
... | ... | @@ -0,0 +1,11 @@ |
1 | +<%# FIXME should not need to replicate the article structure like this to be able to use the same formatting as the comments listing %> | |
2 | +<div id='article'> | |
3 | + <div class="comments" id="comments_list"> | |
4 | + <ul class="article-comments-list"> | |
5 | + <%= render :partial => 'comment/comment', :collection => @comment_spam %> | |
6 | + </ul> | |
7 | + </div> | |
8 | +</div> | |
9 | + | |
10 | +<%= pagination_links @comment_spam, :param_name => :comments_page %> | |
11 | + | ... | ... |
... | ... | @@ -0,0 +1,21 @@ |
1 | +<% render :layout => 'task', :locals => { :task => task } do %> | |
2 | + <% content_for :extra_buttons do %> | |
3 | + <%= button_to_function('down', _('Show details'), "toggleDetails(this, '#{_('Hide details')}', '#{_('Show details')}')" ) %> | |
4 | + <% end %> | |
5 | + | |
6 | + <% content_for :extra_content do %> | |
7 | + <ul class="suggest-article-details" style="display: none"> | |
8 | + <li><strong><%=_('Sent by')%></strong>: <%=task.name%> </li> | |
9 | + <li><strong><%=_('Email')%></strong>: <%=task.email%> </li> | |
10 | + <li><strong><%=_('Source')%></strong>: <%=task.source_name%> </li> | |
11 | + <li><strong><%=_('Source URL')%></strong>: <%=task.source%> </li> | |
12 | + <li><strong><%=_('Folder')%></strong>: <%=(a = Article.find_by_id(task.article_parent_id))?a.name : '<em>' + s_('Folder|none') + '</em>'%> </li> | |
13 | + <li><strong><%=_('Lead')%></strong>: <%=task.article_abstract.blank? ? '<em>' + s_('Abstract|empty') + '</em>' : task.article_abstract%> </li> | |
14 | + <li><strong><%=_('Body')%></strong>: | |
15 | + <div class='suggest-article-body'> | |
16 | + <%= task.article_body %> | |
17 | + </div> | |
18 | + </li> | |
19 | + </ul> | |
20 | + <% end %> | |
21 | +<% end %> | ... | ... |
... | ... | @@ -0,0 +1,18 @@ |
1 | +<div class="task_box" id="task-<%= task.id %>"> | |
2 | + <%= render :partial => 'tasks/task_icon', :locals => {:task => task} %> | |
3 | + <%= render :partial => 'tasks/task_title', :locals => {:task => task} %> | |
4 | + <div class="task-information"> | |
5 | + <%= task_information(task) %> | |
6 | + </div> | |
7 | + | |
8 | + <%= yield %> <% # ??? %> | |
9 | + | |
10 | + <% button_bar do %> | |
11 | + <%= button_to_function('new', _('Mark as NOT SPAM'), 'removeTaskBox(this, %s, "%s", "")' % [url_for(:mark_task_as_ham => task.id).to_json, "task-#{task.id}"]) %> | |
12 | + <%= yield :extra_buttons %> | |
13 | + <%= button_to_function('delete', _('Remove'), 'removeTaskBox(this, %s, "%s", %s)' % [url_for(:profile => params[:profile], :remove_task => task.id).to_json, "task-#{task.id}", _('Are you sure you want to remove this article suggestion?').to_json]) %> | |
14 | + | |
15 | + <% end %> | |
16 | + | |
17 | + <%= yield :extra_content %> | |
18 | +</div> | ... | ... |
app/views/spam/index.rhtml
1 | +<%= stylesheet('tasks') %> | |
2 | + | |
1 | 3 | <h1><%= _('Manage SPAM') %></h1> |
2 | 4 | |
5 | +<% no_tabs = @comment_spam.blank? && @task_spam.blank? %> | |
6 | + | |
7 | +<%= _('There are no spams to review.') if no_tabs %> | |
8 | + | |
3 | 9 | <% button_bar do %> |
4 | 10 | <%= button :back, _('Back to control panel'), :controller => :profile_editor %> |
5 | 11 | <% end %> |
6 | 12 | |
7 | 13 | <%# FIXME should not need to replicate the article structure like this to be able to use the same formatting as the comments listing %> |
8 | -<div id='article'> | |
9 | - <div class="comments" id="comments_list"> | |
10 | - <ul class="article-comments-list"> | |
11 | - <%= render :partial => 'comment/comment', :collection => @spam %> | |
12 | - </ul> | |
13 | - </div> | |
14 | -</div> | |
15 | 14 | |
16 | -<%= pagination_links @spam %> | |
15 | +<% tabs = [] %> | |
16 | +<% tabs << {:title => _('Comment Spam'), :id => 'comment-spam', | |
17 | + :content => (render :partial => 'comment_spam')} if @comment_spam.present? %> | |
18 | +<% tabs << {:title => _('Task Spam'), :id => 'task-spam', | |
19 | + :content => (render :partial => 'task_spam') } if @task_spam.present? %> | |
20 | +<%= render_tabs(tabs) %> | |
17 | 21 | |
18 | -<% button_bar do %> | |
19 | - <%= button :back, _('Back to control panel'), :controller => :profile_editor %> | |
22 | +<% unless no_tabs %> | |
23 | + <% button_bar do %> | |
24 | + <%= button :back, _('Back to control panel'), :controller => :profile_editor %> | |
25 | + <% end %> | |
20 | 26 | <% end %> |
27 | + | |
28 | +<%= javascript_include_tag 'spam' %> | ... | ... |
app/views/tasks/_task.rhtml
1 | 1 | <div class="task_box" id="task-<%= task.id %>"> |
2 | 2 | |
3 | - <div class="task_icon"> | |
4 | - <% | |
5 | - icon_info = task.icon | |
6 | - if icon_info[:type] == :profile_image | |
7 | - icon = profile_image(icon_info[:profile], :minor) | |
8 | - elsif icon_info[:type] == :defined_image | |
9 | - icon = "<img src='#{icon_info[:src]}' alt='#{icon_info[:name]}' />" | |
10 | - end | |
11 | - %> | |
12 | - <%= | |
13 | - if icon_info[:url] | |
14 | - link_to(icon, icon_info[:url]) | |
15 | - else | |
16 | - icon | |
17 | - end | |
18 | - %> | |
19 | - | |
20 | - </div> | |
3 | + <%= render :partial => 'task_icon', :locals => {:task => task} %> | |
21 | 4 | |
22 | 5 | <div class="task_decisions"> |
23 | 6 | <%= |
... | ... | @@ -39,9 +22,7 @@ |
39 | 22 | %> |
40 | 23 | </div><!-- class="task_decisions" --> |
41 | 24 | |
42 | - <strong class="task_title"> | |
43 | - <%= task.title %> | |
44 | - </strong> | |
25 | + <%= render :partial => 'task_title', :locals => {:task => task} %> | |
45 | 26 | |
46 | 27 | <div class="task_information"> |
47 | 28 | <%= task_information(task) %> | ... | ... |
... | ... | @@ -0,0 +1,16 @@ |
1 | +<% | |
2 | + icon_info = task.icon | |
3 | + if icon_info[:type] == :profile_image | |
4 | + icon = profile_image(icon_info[:profile], :minor) | |
5 | + elsif icon_info[:type] == :defined_image | |
6 | + icon = "<img src='#{icon_info[:src]}' alt='#{icon_info[:name]}' />" | |
7 | + end | |
8 | + | |
9 | + if icon_info[:url] | |
10 | + icon = link_to(icon, icon_info[:url]) | |
11 | + end | |
12 | +%> | |
13 | + | |
14 | +<div class="task_icon"> | |
15 | + <%= icon %> | |
16 | +</div> | ... | ... |
config/initializers/plugins.rb
... | ... | @@ -0,0 +1,13 @@ |
1 | +class AddSpamToTask < ActiveRecord::Migration | |
2 | + def self.up | |
3 | + change_table :tasks do |t| | |
4 | + t.boolean :spam, :default => false | |
5 | + end | |
6 | + Task.update_all ["spam = ?", false] | |
7 | + add_index :tasks, [:spam] | |
8 | + end | |
9 | + | |
10 | + def self.down | |
11 | + remove_column :tasks, :spam | |
12 | + end | |
13 | +end | ... | ... |
db/schema.rb
... | ... | @@ -9,7 +9,7 @@ |
9 | 9 | # |
10 | 10 | # It's strongly recommended to check this file into your version control system. |
11 | 11 | |
12 | -ActiveRecord::Schema.define(:version => 20130711213046) do | |
12 | +ActiveRecord::Schema.define(:version => 20131011164400) do | |
13 | 13 | |
14 | 14 | create_table "abuse_reports", :force => true do |t| |
15 | 15 | t.integer "reporter_id" |
... | ... | @@ -547,8 +547,11 @@ ActiveRecord::Schema.define(:version => 20130711213046) do |
547 | 547 | t.datetime "created_at" |
548 | 548 | t.string "target_type" |
549 | 549 | t.integer "image_id" |
550 | + t.boolean "spam", :default => false | |
550 | 551 | end |
551 | 552 | |
553 | + add_index "tasks", ["spam"], :name => "index_tasks_on_spam" | |
554 | + | |
552 | 555 | create_table "thumbnails", :force => true do |t| |
553 | 556 | t.integer "size" |
554 | 557 | t.string "content_type" | ... | ... |
... | ... | @@ -0,0 +1,107 @@ |
1 | +# All file presenters must extends `FilePresenter` not only to ensure the | |
2 | +# same interface, but also to make `FilePresenter.for(file)` to work. | |
3 | +class FilePresenter | |
4 | + | |
5 | + # Will return a encapsulated `UploadedFile` or the same object if no | |
6 | + # one accepts it. That behave allow to give any model to this class, | |
7 | + # like a Article and have no trouble with that. | |
8 | + def self.for(f) | |
9 | + return f if f.is_a? FilePresenter | |
10 | + klass = FilePresenter.subclasses.sort_by {|class_name| | |
11 | + class_name.constantize.accepts?(f) || 0 | |
12 | + }.last.constantize | |
13 | + klass.accepts?(f) ? klass.new(f) : f | |
14 | + end | |
15 | + | |
16 | + def initialize(f) | |
17 | + @file = f | |
18 | + end | |
19 | + | |
20 | + # Allows to use the original `UploadedFile` reference. | |
21 | + def encapsulated_file | |
22 | + @file | |
23 | + end | |
24 | + | |
25 | + def id | |
26 | + @file.id | |
27 | + end | |
28 | + | |
29 | + def reload | |
30 | + @file.reload | |
31 | + self | |
32 | + end | |
33 | + | |
34 | + # This method must be overridden in subclasses. | |
35 | + # | |
36 | + # If the class accepts the file, return a number that represents the | |
37 | + # priority the class should be given to handle that file. Higher numbers | |
38 | + # mean higher priority. | |
39 | + # | |
40 | + # If the class does not accept the file, return false. | |
41 | + def self.accepts?(f) | |
42 | + nil | |
43 | + end | |
44 | + | |
45 | + def short_description | |
46 | + _("File (%s)") % content_type.sub(/^application\//, '').sub(/^x-/, '').sub(/^image\//, '') | |
47 | + end | |
48 | + | |
49 | + # Define the css classes to style the page fragment with the file related | |
50 | + # content. If you want other classes to identify this area to your | |
51 | + # customized presenter, so do this: | |
52 | + # def css_class_list | |
53 | + # [super, 'myclass'].flatten | |
54 | + # end | |
55 | + def css_class_list | |
56 | + [ @file.css_class_list, | |
57 | + 'file-' + self.class.to_s.split(/:+/).map(&:underscore)[1..-1].join('-'), | |
58 | + 'content-type_' + self.content_type.split('/')[0], | |
59 | + 'content-type_' + self.content_type.gsub(/[^a-z0-9]/i,'-') | |
60 | + ].flatten | |
61 | + end | |
62 | + | |
63 | + # Enable file presenter to customize the css classes on view_page.rhtml | |
64 | + # You may not overwrite this method on your customized presenter. | |
65 | + def css_class_name | |
66 | + [css_class_list].flatten.compact.join(' ') | |
67 | + end | |
68 | + | |
69 | + # The generic icon class-name or the specific file path. | |
70 | + # You may replace this method on your custom FilePresenter. | |
71 | + # See the current used icons class-names in public/designs/icons/tango/style.css | |
72 | + def icon_name | |
73 | + if mime_type | |
74 | + [ mime_type.split('/')[0], mime_type.gsub(/[^a-z0-9]/i, '-') ] | |
75 | + else | |
76 | + 'upload-file' | |
77 | + end | |
78 | + end | |
79 | + | |
80 | + # Automatic render `file_presenter/<custom>.html.erb` to display your | |
81 | + # custom presenter html content. | |
82 | + # You may not overwrite this method on your customized presenter. | |
83 | + # A variable with the same presenter name will be created to refer | |
84 | + # to the file object. | |
85 | + # Example: | |
86 | + # The `FilePresenter::Image` render `file_presenter/image.html.erb` | |
87 | + # inside the `file_presenter/image.html.erb` you can access the | |
88 | + # required `FilePresenter::Image` instance in the `image` variable. | |
89 | + def to_html(options = {}) | |
90 | + file = self | |
91 | + lambda do | |
92 | + render :partial => file.class.to_s.underscore, | |
93 | + :locals => { :options => options }, | |
94 | + :object => file | |
95 | + end | |
96 | + end | |
97 | + | |
98 | + # That makes the presenter to works like any other `UploadedFile` instance. | |
99 | + def method_missing(m, *args) | |
100 | + @file.send(m, *args) | |
101 | + end | |
102 | +end | |
103 | + | |
104 | +# Preload FilePresenters to allow `FilePresenter.for()` to work | |
105 | +Dir.glob(File.join('app', 'presenters', '*.rb')) do |file| | |
106 | + load file | |
107 | +end | ... | ... |
lib/noosfero/plugin.rb
... | ... | @@ -155,6 +155,7 @@ class Noosfero::Plugin |
155 | 155 | |
156 | 156 | # Here the developer may specify the events to which the plugins can |
157 | 157 | # register and must return true or false. The default value must be false. |
158 | + # Must also explicitly define its returning variables. | |
158 | 159 | |
159 | 160 | # -> If true, noosfero will include plugin_dir/public/style.css into |
160 | 161 | # application |
... | ... | @@ -162,10 +163,6 @@ class Noosfero::Plugin |
162 | 163 | false |
163 | 164 | end |
164 | 165 | |
165 | - # Here the developer should specify the events to which the plugins can | |
166 | - # register to. Must be explicitly defined its returning | |
167 | - # variables. | |
168 | - | |
169 | 166 | # -> Adds buttons to the control panel |
170 | 167 | # returns = { :title => title, :icon => icon, :url => url } |
171 | 168 | # title = name that will be displayed. |
... | ... | @@ -175,6 +172,13 @@ class Noosfero::Plugin |
175 | 172 | nil |
176 | 173 | end |
177 | 174 | |
175 | + # -> Customize profile block design and behavior | |
176 | + # (overwrites profile_image_link function) | |
177 | + # returns = lambda block that creates html code. | |
178 | + def profile_image_link(profile, size, tag, extra_info) | |
179 | + nil | |
180 | + end | |
181 | + | |
178 | 182 | # -> Adds tabs to the profile |
179 | 183 | # returns = { :title => title, :id => id, :content => content, :start => start } |
180 | 184 | # title = name that will be displayed. |
... | ... | @@ -304,45 +308,16 @@ class Noosfero::Plugin |
304 | 308 | scope |
305 | 309 | end |
306 | 310 | |
307 | - # This method is called by the CommentHandler background job before sending | |
308 | - # the notification email. If the comment is marked as spam (i.e. by calling | |
309 | - # <tt>comment.spam!</tt>), then the notification email will *not* be sent. | |
310 | - # | |
311 | - # example: | |
312 | - # | |
313 | - # def check_comment_for_spam(comment) | |
314 | - # if anti_spam_service.is_spam?(comment) | |
315 | - # comment.spam! | |
316 | - # end | |
317 | - # end | |
318 | - # | |
319 | - def check_comment_for_spam(comment) | |
311 | + # -> Allows plugins to check weather object is a spam | |
312 | + def check_for_spam(object) | |
320 | 313 | end |
321 | 314 | |
322 | - # This method is called when the user manually marks a comment as SPAM. A | |
323 | - # plugin implementing this method should train its spam detection mechanism | |
324 | - # by submitting this comment as a confirmed spam. | |
325 | - # | |
326 | - # example: | |
327 | - # | |
328 | - # def comment_marked_as_spam(comment) | |
329 | - # anti_spam_service.train_with_spam(comment) | |
330 | - # end | |
331 | - # | |
332 | - def comment_marked_as_spam(comment) | |
315 | + # -> Allows plugins to know when an object is marked as a spam | |
316 | + def marked_as_spam(object) | |
333 | 317 | end |
334 | 318 | |
335 | - # This method is called when the user manually marks a comment a NOT SPAM. A | |
336 | - # plugin implementing this method should train its spam detection mechanism | |
337 | - # by submitting this coimment as a confirmed ham. | |
338 | - # | |
339 | - # example: | |
340 | - # | |
341 | - # def comment_marked_as_ham(comment) | |
342 | - # anti_spam_service.train_with_ham(comment) | |
343 | - # end | |
344 | - # | |
345 | - def comment_marked_as_ham(comment) | |
319 | + # -> Allows plugins to know when an object is marked as a ham | |
320 | + def marked_as_ham(object) | |
346 | 321 | end |
347 | 322 | |
348 | 323 | # Adds extra actions for comments | ... | ... |
lib/noosfero/plugin/manager.rb
... | ... | @@ -34,18 +34,20 @@ class Noosfero::Plugin::Manager |
34 | 34 | alias :dispatch_scopes :dispatch_without_flatten |
35 | 35 | |
36 | 36 | def dispatch_first(event, *args) |
37 | - result = nil | |
37 | + default = Noosfero::Plugin.new.send(event, *args) | |
38 | + result = default | |
38 | 39 | each do |plugin| |
39 | 40 | result = plugin.send(event, *args) |
40 | - break if result.present? | |
41 | + break if result != default | |
41 | 42 | end |
42 | 43 | result |
43 | 44 | end |
44 | 45 | |
45 | 46 | def fetch_first_plugin(event, *args) |
47 | + default = Noosfero::Plugin.new.send(event, *args) | |
46 | 48 | result = nil |
47 | 49 | each do |plugin| |
48 | - if plugin.send(event, *args) | |
50 | + if plugin.send(event, *args) != default | |
49 | 51 | result = plugin.class |
50 | 52 | break |
51 | 53 | end | ... | ... |
... | ... | @@ -0,0 +1,13 @@ |
1 | +Spammable.module_eval do | |
2 | + def marked_as_spam | |
3 | + plugins.dispatch(:marked_as_spam, self) | |
4 | + end | |
5 | + | |
6 | + def marked_as_ham | |
7 | + plugins.dispatch(:marked_as_ham, self) | |
8 | + end | |
9 | + | |
10 | + def check_for_spam | |
11 | + plugins.dispatch(:check_for_spam, self) | |
12 | + end | |
13 | +end | ... | ... |
... | ... | @@ -0,0 +1,47 @@ |
1 | +module Spammable | |
2 | + def self.included(recipient) | |
3 | + raise "This model should have a spam attribute!" if !recipient.new.respond_to?('spam=') | |
4 | + recipient.extend(ClassMethods) | |
5 | + end | |
6 | + | |
7 | + module ClassMethods | |
8 | + def self.extended (base) | |
9 | + if base.respond_to?(:named_scope) | |
10 | + base.class_eval do | |
11 | + named_scope :without_spam, :conditions => ['spam IS NULL OR spam = ?', false] | |
12 | + named_scope :spam, :conditions => ['spam = ?', true] | |
13 | + end | |
14 | + end | |
15 | + end | |
16 | + end | |
17 | + | |
18 | + def spam? | |
19 | + !spam.nil? && spam | |
20 | + end | |
21 | + | |
22 | + def ham? | |
23 | + !spam.nil? && !spam | |
24 | + end | |
25 | + | |
26 | + def spam! | |
27 | + before_spam! | |
28 | + self.spam = true | |
29 | + self.save! | |
30 | + after_spam! | |
31 | + self | |
32 | + end | |
33 | + | |
34 | + def ham! | |
35 | + before_ham! | |
36 | + self.spam = false | |
37 | + self.save! | |
38 | + after_ham! | |
39 | + self | |
40 | + end | |
41 | + | |
42 | + def after_spam!; end | |
43 | + def before_spam!; end | |
44 | + | |
45 | + def after_ham!; end | |
46 | + def before_ham!; end | |
47 | +end | ... | ... |
plugins/anti_spam/lib/anti_spam_plugin.rb
... | ... | @@ -5,38 +5,37 @@ class AntiSpamPlugin < Noosfero::Plugin |
5 | 5 | end |
6 | 6 | |
7 | 7 | def self.plugin_description |
8 | - _("Checks comments against a spam checking service compatible with the Akismet API") | |
8 | + _("Tests comments and suggested articles against a spam checking service compatible with the Akismet API") | |
9 | 9 | end |
10 | 10 | |
11 | 11 | def self.host_default_setting |
12 | 12 | 'api.antispam.typepad.com' |
13 | 13 | end |
14 | 14 | |
15 | - def check_comment_for_spam(comment) | |
16 | - if rakismet_call(comment, :spam?) | |
17 | - comment.spam = true | |
18 | - comment.save! | |
15 | + def check_for_spam(object) | |
16 | + if rakismet_call AntiSpamPlugin::Wrapper.wrap(object), object.environment, :spam? | |
17 | + object.spam = true | |
18 | + object.save! | |
19 | 19 | end |
20 | 20 | end |
21 | 21 | |
22 | - def comment_marked_as_spam(comment) | |
23 | - rakismet_call(comment, :spam!) | |
22 | + def marked_as_spam(object) | |
23 | + rakismet_call AntiSpamPlugin::Wrapper.wrap(object), object.environment, :spam! | |
24 | 24 | end |
25 | 25 | |
26 | - def comment_marked_as_ham(comment) | |
27 | - rakismet_call(comment, :ham!) | |
26 | + def marked_as_ham(object) | |
27 | + rakismet_call AntiSpamPlugin::Wrapper.wrap(object), object.environment, :ham! | |
28 | 28 | end |
29 | 29 | |
30 | 30 | protected |
31 | 31 | |
32 | - def rakismet_call(comment, op) | |
33 | - settings = Noosfero::Plugin::Settings.new(comment.environment, self.class) | |
32 | + def rakismet_call(submission, environment, op) | |
33 | + settings = Noosfero::Plugin::Settings.new(environment, self.class) | |
34 | 34 | |
35 | 35 | Rakismet.host = settings.host |
36 | 36 | Rakismet.key = settings.api_key |
37 | - Rakismet.url = comment.environment.top_url | |
37 | + Rakismet.url = environment.top_url | |
38 | 38 | |
39 | - submission = AntiSpamPlugin::CommentWrapper.new(comment) | |
40 | 39 | submission.send(op) |
41 | 40 | end |
42 | 41 | ... | ... |
plugins/anti_spam/lib/anti_spam_plugin/comment_wrapper.rb
1 | -class AntiSpamPlugin::CommentWrapper < Struct.new(:comment) | |
2 | - | |
3 | - delegate :author_name, :author_email, :title, :body, :ip_address, :user_agent, :referrer, :to => :comment | |
4 | - | |
5 | - include Rakismet::Model | |
6 | - | |
7 | - alias :author :author_name | |
8 | - alias :user_ip :ip_address | |
9 | - alias :content :body | |
10 | - | |
1 | +class AntiSpamPlugin::CommentWrapper < AntiSpamPlugin::Wrapper | |
2 | + alias_attribute :author, :author_name | |
3 | + alias_attribute :user_ip, :ip_address | |
4 | + alias_attribute :content, :body | |
5 | + | |
6 | + def self.wraps?(object) | |
7 | + object.kind_of?(Comment) | |
8 | + end | |
11 | 9 | end | ... | ... |
plugins/anti_spam/lib/anti_spam_plugin/suggest_article_wrapper.rb
0 → 100644
... | ... | @@ -0,0 +1,10 @@ |
1 | +class AntiSpamPlugin::SuggestArticleWrapper < AntiSpamPlugin::Wrapper | |
2 | + alias_attribute :author, :name | |
3 | + alias_attribute :author_email, :email | |
4 | + alias_attribute :user_ip, :ip_address | |
5 | + alias_attribute :content, :article_body | |
6 | + | |
7 | + def self.wraps?(object) | |
8 | + object.kind_of?(SuggestArticle) | |
9 | + end | |
10 | +end | ... | ... |
... | ... | @@ -0,0 +1,18 @@ |
1 | +class AntiSpamPlugin::Wrapper < SimpleDelegator | |
2 | + include Rakismet::Model | |
3 | + | |
4 | + @@wrappers = [] | |
5 | + | |
6 | + def self.wrap(object) | |
7 | + wrapper = @@wrappers.find { |wrapper| wrapper.wraps?(object) } | |
8 | + wrapper ? wrapper.new(object) : object | |
9 | + end | |
10 | + | |
11 | + def self.wraps?(object) | |
12 | + false | |
13 | + end | |
14 | + | |
15 | + def self.inherited(child) | |
16 | + @@wrappers << child | |
17 | + end | |
18 | +end | ... | ... |
plugins/anti_spam/test/unit/anti_spam_plugin/comment_wrapper_test.rb
1 | 1 | require 'test_helper' |
2 | 2 | |
3 | -class AntiSpamPluginCommentWrapperTest < ActiveSupport::TestCase | |
3 | +class AntiSpamPlugin::CommentWrapperTest < ActiveSupport::TestCase | |
4 | 4 | |
5 | 5 | def setup |
6 | 6 | @comment = Comment.new( |
... | ... | @@ -15,10 +15,6 @@ class AntiSpamPluginCommentWrapperTest < ActiveSupport::TestCase |
15 | 15 | @wrapper = AntiSpamPlugin::CommentWrapper.new(@comment) |
16 | 16 | end |
17 | 17 | |
18 | - should 'use Rakismet::Model' do | |
19 | - assert_includes @wrapper.class.included_modules, Rakismet::Model | |
20 | - end | |
21 | - | |
22 | 18 | should 'get contents' do |
23 | 19 | assert_equal @comment.body, @wrapper.content |
24 | 20 | end | ... | ... |
plugins/anti_spam/test/unit/anti_spam_plugin/suggest_article_wrapper_test.rb
0 → 100644
... | ... | @@ -0,0 +1,41 @@ |
1 | +require 'test_helper' | |
2 | + | |
3 | +class AntiSpamPlugin::SuggestArticleWrapperTest < ActiveSupport::TestCase | |
4 | + | |
5 | + def setup | |
6 | + @suggest_article = SuggestArticle.new( | |
7 | + :article_body => 'comment body', | |
8 | + :name => 'author', | |
9 | + :email => 'foo@example.com', | |
10 | + :ip_address => '1.2.3.4', | |
11 | + :user_agent => 'Some Good Browser (I hope)', | |
12 | + :referrer => 'http://noosfero.org/' | |
13 | + ) | |
14 | + @wrapper = AntiSpamPlugin::SuggestArticleWrapper.new(@suggest_article) | |
15 | + end | |
16 | + | |
17 | + should 'get contents' do | |
18 | + assert_equal @suggest_article.article_body, @wrapper.content | |
19 | + end | |
20 | + | |
21 | + should 'get author name' do | |
22 | + assert_equal @suggest_article.name, @wrapper.author | |
23 | + end | |
24 | + | |
25 | + should 'get author email' do | |
26 | + assert_equal @suggest_article.email, @wrapper.author_email | |
27 | + end | |
28 | + | |
29 | + should 'get IP address' do | |
30 | + assert_equal @suggest_article.ip_address, @wrapper.user_ip | |
31 | + end | |
32 | + | |
33 | + should 'get User-Agent' do | |
34 | + assert_equal @suggest_article.user_agent, @wrapper.user_agent | |
35 | + end | |
36 | + | |
37 | + should 'get get Referrer' do | |
38 | + assert_equal @suggest_article.referrer, @wrapper.referrer | |
39 | + end | |
40 | + | |
41 | +end | ... | ... |
plugins/anti_spam/test/unit/anti_spam_plugin/wrapper_test.rb
0 → 100644
... | ... | @@ -0,0 +1,25 @@ |
1 | +require 'test_helper' | |
2 | +require 'anti_spam_plugin/wrapper' | |
3 | + | |
4 | +class AntiSpamPluginWrapperTest < ActiveSupport::TestCase | |
5 | + should 'use Rakismet::Model' do | |
6 | + wrapped = AntiSpamPlugin::Wrapper.new(mock) | |
7 | + assert_includes wrapped.class.included_modules, Rakismet::Model | |
8 | + end | |
9 | + | |
10 | + should 'wrap object according to wraps? method' do | |
11 | + class EvenWrapper < AntiSpamPlugin::Wrapper | |
12 | + def self.wraps?(object) | |
13 | + object % 2 == 0 | |
14 | + end | |
15 | + end | |
16 | + class OddWrapper < AntiSpamPlugin::Wrapper | |
17 | + def self.wraps?(object) | |
18 | + object % 2 != 0 | |
19 | + end | |
20 | + end | |
21 | + | |
22 | + assert AntiSpamPlugin::Wrapper.wrap(5).kind_of?(OddWrapper) | |
23 | + assert AntiSpamPlugin::Wrapper.wrap(6).kind_of?(EvenWrapper) | |
24 | + end | |
25 | +end | ... | ... |
plugins/anti_spam/test/unit/anti_spam_plugin_test.rb
... | ... | @@ -2,35 +2,36 @@ require 'test_helper' |
2 | 2 | |
3 | 3 | class AntiSpamPluginTest < ActiveSupport::TestCase |
4 | 4 | |
5 | - def setup | |
6 | - profile = fast_create(Profile) | |
7 | - article = fast_create(TextileArticle, :profile_id => profile.id) | |
8 | - @comment = fast_create(Comment, :source_id => article.id, :source_type => 'Article') | |
5 | + class SpammableContent | |
6 | + attr_accessor :spam | |
7 | + include Spammable | |
9 | 8 | |
10 | - @settings = Noosfero::Plugin::Settings.new(@comment.environment, AntiSpamPlugin) | |
11 | - @settings.api_key = 'b8b80ddb8084062d0c9119c945ce3bc3' | |
12 | - @settings.save! | |
9 | + def save!; end | |
10 | + def environment; Environment.default; end | |
11 | + end | |
13 | 12 | |
13 | + def setup | |
14 | + @spammable = SpammableContent.new | |
14 | 15 | @plugin = AntiSpamPlugin.new |
15 | - @plugin.context = @comment | |
16 | 16 | end |
17 | 17 | |
18 | - should 'check for spam and mark comment as spam if server says it is spam' do | |
19 | - AntiSpamPlugin::CommentWrapper.any_instance.expects(:spam?).returns(true) | |
20 | - @comment.expects(:save!) | |
18 | + attr_accessor :spammable | |
21 | 19 | |
22 | - @plugin.check_comment_for_spam(@comment) | |
23 | - assert @comment.spam | |
24 | - end | |
20 | + should 'check for spam and mark as spam if server says it is spam' do | |
21 | + spammable.expects(:spam?).returns(true) | |
22 | + spammable.expects(:save!) | |
25 | 23 | |
26 | - should 'report spam' do | |
27 | - AntiSpamPlugin::CommentWrapper.any_instance.expects(:spam!) | |
28 | - @plugin.comment_marked_as_spam(@comment) | |
24 | + @plugin.check_for_spam(spammable) | |
25 | + assert spammable.spam | |
29 | 26 | end |
30 | 27 | |
31 | - should 'report ham' do | |
32 | - AntiSpamPlugin::CommentWrapper.any_instance.expects(:ham!) | |
33 | - @plugin.comment_marked_as_ham(@comment) | |
28 | + should 'report comment spam' do | |
29 | + spammable.expects(:spam!) | |
30 | + @plugin.marked_as_spam(spammable) | |
34 | 31 | end |
35 | 32 | |
33 | + should 'report comment ham' do | |
34 | + spammable.expects(:ham!) | |
35 | + @plugin.marked_as_ham(spammable) | |
36 | + end | |
36 | 37 | end | ... | ... |
... | ... | @@ -0,0 +1,10 @@ |
1 | +class FilePresenter::Video < FilePresenter | |
2 | + def self.accepts?(f) | |
3 | + return nil if !f.respond_to?(:content_type) || f.content_type.nil? | |
4 | + ( f.content_type[0..4] == 'video' ) ? 10 : nil | |
5 | + end | |
6 | + | |
7 | + def short_description | |
8 | + _('Video (%s)') % content_type.split('/')[1].upcase | |
9 | + end | |
10 | +end | ... | ... |
... | ... | @@ -0,0 +1,13 @@ |
1 | +class Html5VideoPlugin < Noosfero::Plugin | |
2 | + | |
3 | + FilePresenter::Video | |
4 | + | |
5 | + def self.plugin_name | |
6 | + "HTML5 Video" | |
7 | + end | |
8 | + | |
9 | + def self.plugin_description | |
10 | + _("A plugin to enable the video suport, with auto conversion for the web.") | |
11 | + end | |
12 | + | |
13 | +end | ... | ... |
plugins/html5_video/test/functional/content_viewer_controler_test.rb
0 → 100644
... | ... | @@ -0,0 +1,30 @@ |
1 | +require File.dirname(__FILE__) + '/../../../../test/test_helper' | |
2 | +require 'content_viewer_controller' | |
3 | + | |
4 | +class ContentViewerController | |
5 | + # Re-raise errors caught by the controller. | |
6 | + def rescue_action(e) raise e end | |
7 | + append_view_path File.join(File.dirname(__FILE__) + '/../../views') | |
8 | +end | |
9 | + | |
10 | +class ContentViewerControllerTest < ActionController::TestCase | |
11 | + | |
12 | + all_fixtures | |
13 | + | |
14 | + def setup | |
15 | + @controller = ContentViewerController.new | |
16 | + @request = ActionController::TestRequest.new | |
17 | + @response = ActionController::TestResponse.new | |
18 | + | |
19 | + @profile = create_user('testinguser').person | |
20 | + @environment = @profile.environment | |
21 | + end | |
22 | + attr_reader :profile, :environment | |
23 | + | |
24 | + should 'add html5 video tag to the page of file type video' do | |
25 | + file = UploadedFile.create!(:uploaded_data => fixture_file_upload('/files/test.txt', 'video/ogg'), :profile => profile) | |
26 | + get :view_page, file.url.merge(:view=>:true) | |
27 | + assert_select '#article video' | |
28 | + end | |
29 | + | |
30 | +end | ... | ... |
plugins/html5_video/views/file_presenter/_video.html.erb
0 → 100644
... | ... | @@ -0,0 +1,8 @@ |
1 | +<video class="video-js vjs-default-skin" controls poster="video.jpg" preload="auto" data-setup="{}"> | |
2 | + <source type="video/ogg" src="<%= video.public_filename %>"/> | |
3 | +</video> | |
4 | + | |
5 | +<div class="uploaded-file-description <%= 'empty' if video.abstract.blank? %>"> | |
6 | + <%= video.abstract %> | |
7 | +</div> | |
8 | + | ... | ... |
public/designs/icons/tango/ie6.css
... | ... | @@ -1,52 +0,0 @@ |
1 | -.msie6 .icon-edit { background-image: url(ie6/Tango/16x16/apps/text-editor.gif) } | |
2 | -.msie6 .icon-home { background-image: url(ie6/Tango/16x16/actions/go-home.gif) } | |
3 | -.msie6 .icon-new, | |
4 | -.msie6 .icon-suggest { background-image: url(ie6/Tango/16x16/actions/filenew.gif) } | |
5 | -.msie6 .icon-close { background-image: url(ie6/Tango/16x16/actions/gtk-cancel.gif) } | |
6 | -.msie6 .icon-newfolder { background-image: url(ie6/Tango/16x16/actions/folder-new.gif) } | |
7 | -.msie6 .icon-save { background-image: url(ie6/Tango/16x16/actions/filesave.gif) } | |
8 | -.msie6 .icon-send { background-image: url(ie6/Tango/16x16/actions/stock_mail-forward.gif) } | |
9 | -.msie6 .icon-cancel { background-image: url(ie6/Tango/16x16/actions/gtk-cancel.gif) } | |
10 | -.msie6 .icon-person { background-image: url(ie6/Tango/16x16/apps/system-config-users.gif) } | |
11 | -.msie6 .icon-product { background-image: url(ie6/Tango/16x16/mimetypes/package.gif) } | |
12 | -.msie6 .icon-delete { background-image: url(ie6/Tango/16x16/places/user-trash.gif) } | |
13 | -.msie6 .icon-back { background-image: url(ie6/Tango/16x16/actions/back.gif) } | |
14 | -.msie6 .icon-next { background-image: url(ie6/Tango/16x16/actions/go-next.gif) } | |
15 | -.msie6 .icon-add { background-image: url(ie6/Tango/16x16/actions/add.gif) } | |
16 | -.msie6 .icon-more { background-image: url(ie6/Tango/16x16/actions/add.gif) } | |
17 | -.msie6 .icon-up { background-image: url(ie6/Tango/16x16/actions/go-up.gif) } | |
18 | -.msie6 .icon-down { background-image: url(ie6/Tango/16x16/actions/go-down.gif) } | |
19 | -.msie6 .icon-left { background-image: url(ie6/Tango/16x16/actions/go-previous.gif) } | |
20 | -.msie6 .icon-right { background-image: url(ie6/Tango/16x16/actions/go-next.gif) } | |
21 | -.msie6 .icon-up-disabled { background-image: url(ie6/Tango/16x16/actions/go-up.gif); opacity: 0.25; filter:alpha(opacity=25); } | |
22 | -.msie6 .icon-down-disabled { background-image: url(ie6/Tango/16x16/actions/go-down.gif); opacity: 0.25; filter:alpha(opacity=25); } | |
23 | -.msie6 .icon-left-disabled { background-image: url(ie6/Tango/16x16/actions/go-previous.gif); opacity: 0.25; filter:alpha(opacity=25); } | |
24 | -.msie6 .icon-right-disabled { background-image: url(ie6/Tango/16x16/actions/go-next.gif); opacity: 0.25; filter:alpha(opacity=25); } | |
25 | -.msie6 .icon-up-red { background-image: url(ie6/mod/16x16/actions/go-up-red.gif) } | |
26 | -.msie6 .icon-forward { background-image: url(ie6/Tango/16x16/actions/go-next.gif) } | |
27 | -.msie6 .icon-search { background-image: url(ie6/Tango/16x16/actions/search.gif) } | |
28 | -.msie6 .icon-ok { background-image: url(ie6/Tango/16x16/actions/media-playback-start.gif) } | |
29 | -.msie6 .icon-login { background-image: url(ie6/mod/16x16/actions/log-in.gif) } | |
30 | -.msie6 .icon-help { background-image: url(ie6/Tango/16x16/apps/gnome-help.gif) } | |
31 | -.msie6 .icon-firefox { background-image: url(firefox-24x24.gif) } | |
32 | -.msie6 .icon-help32on { background-image: url(ie6/Tango/32x32/apps/gnome-help.gif) } | |
33 | -.msie6 .icon-help32off { background-image: url(ie6/mod/32x32/apps/gnome-help-red.gif) } | |
34 | -.msie6 .icon-spread { background-image: url(ie6/mod/16x16/actions/spread.gif) } | |
35 | -.msie6 .icon-todo { background-image: url(ie6/Tango/16x16/actions/stock_paste.gif) } | |
36 | -.msie6 .icon-eyes { background-image: url(ie6/Tango/16x16/actions/gtk-print-preview.gif) } | |
37 | -.msie6 .icon-menu-home { background-image: url(ie6/Tango/16x16/actions/go-home.gif) } | |
38 | -.msie6 .icon-menu-product { background-image: url(ie6/Tango/16x16/mimetypes/package.gif) } | |
39 | -.msie6 .icon-menu-enterprise { background-image: url(ie6/Tango/16x16/actions/go-home.gif) } | |
40 | -.msie6 .icon-menu-community { background-image: url(ie6/Tango/16x16/apps/system-config-users.gif) } | |
41 | -.msie6 .icon-menu-ctrl-panel { background-image: url(ie6/Tango/16x16/categories/preferences-desktop.gif) } | |
42 | -.msie6 .icon-menu-admin { background-image: url(ie6/Tango/16x16/categories/preferences-system.gif) } | |
43 | -.msie6 .icon-menu-my-groups { background-image: url(ie6/Tango/16x16/apps/system-config-users.gif) } | |
44 | -.msie6 .icon-menu-login { background-image: url(ie6/mod/16x16/actions/log-in.gif) } | |
45 | -.msie6 .icon-menu-logout { background-image: url(ie6/Tango/16x16/actions/exit.gif) } | |
46 | -.msie6 .icon-menu-search { background-image: url(ie6/Tango/16x16/actions/search.gif) } | |
47 | -.msie6 .icon-menu-events { background-image: url(ie6/Tango/16x16/mimetypes/stock_calendar.gif) } | |
48 | -.msie6 .icon-menu-articles { background-image: url(ie6/Tango/16x16/apps/text-editor.gif) } | |
49 | -.msie6 .icon-menu-people { background-image: url(ie6/mod/16x16/apps/user.gif) } | |
50 | -.msie6 .icon-menu-mail { background-image: url(ie6/Tango/16x16/apps/email.gif) } | |
51 | -.msie6 .icon-upload-file { background-image: url(ie6/Tango/16x16/actions/filesave.gif) } | |
52 | -.msie6 .icon-slideshow { background-image: url(ie6/Tango/16x16/mimetypes/x-office-presentation.gif) } |
public/designs/icons/tango/ie6/Tango/16x16/actions/add.gif
192 Bytes
public/designs/icons/tango/ie6/Tango/16x16/actions/back.gif
570 Bytes
public/designs/icons/tango/ie6/Tango/16x16/actions/exit.gif
1.03 KB
public/designs/icons/tango/ie6/Tango/16x16/actions/filenew.gif
354 Bytes
public/designs/icons/tango/ie6/Tango/16x16/actions/filesave.gif
750 Bytes
public/designs/icons/tango/ie6/Tango/16x16/actions/folder-new.gif
599 Bytes
public/designs/icons/tango/ie6/Tango/16x16/actions/go-down.gif
568 Bytes
public/designs/icons/tango/ie6/Tango/16x16/actions/go-home.gif
587 Bytes
public/designs/icons/tango/ie6/Tango/16x16/actions/go-next.gif
570 Bytes
public/designs/icons/tango/ie6/Tango/16x16/actions/go-previous.gif
570 Bytes
public/designs/icons/tango/ie6/Tango/16x16/actions/go-up.gif
572 Bytes
public/designs/icons/tango/ie6/Tango/16x16/actions/gtk-cancel.gif
1022 Bytes
public/designs/icons/tango/ie6/Tango/16x16/actions/gtk-print-preview.gif
1022 Bytes
public/designs/icons/tango/ie6/Tango/16x16/actions/media-playback-start.gif
314 Bytes
public/designs/icons/tango/ie6/Tango/16x16/actions/search.gif
601 Bytes
public/designs/icons/tango/ie6/Tango/16x16/actions/stock_mail-forward.gif
601 Bytes
public/designs/icons/tango/ie6/Tango/16x16/actions/stock_paste.gif
595 Bytes
public/designs/icons/tango/ie6/Tango/16x16/apps/email.gif
347 Bytes
public/designs/icons/tango/ie6/Tango/16x16/apps/gnome-help.gif
1.01 KB
public/designs/icons/tango/ie6/Tango/16x16/apps/system-config-users.gif
1.05 KB
public/designs/icons/tango/ie6/Tango/16x16/apps/text-editor.gif
363 Bytes
public/designs/icons/tango/ie6/Tango/16x16/categories/preferences-desktop.gif
357 Bytes
public/designs/icons/tango/ie6/Tango/16x16/categories/preferences-system.gif
333 Bytes
public/designs/icons/tango/ie6/Tango/16x16/mimetypes/package.gif
573 Bytes
public/designs/icons/tango/ie6/Tango/16x16/mimetypes/stock_calendar.gif
382 Bytes
public/designs/icons/tango/ie6/Tango/16x16/mimetypes/x-office-presentation.gif
559 Bytes
public/designs/icons/tango/ie6/Tango/16x16/places/user-home.gif
1 KB
public/designs/icons/tango/ie6/Tango/16x16/places/user-trash.gif
1009 Bytes
public/designs/icons/tango/ie6/Tango/32x32/apps/gnome-help.gif
1.03 KB
public/designs/icons/tango/ie6/mod/16x16/actions/go-up-red.gif
361 Bytes
public/designs/icons/tango/ie6/mod/16x16/actions/log-in.gif
246 Bytes
public/designs/icons/tango/ie6/mod/16x16/actions/log-out.gif
241 Bytes
public/designs/icons/tango/ie6/mod/16x16/actions/password.gif
546 Bytes
public/designs/icons/tango/ie6/mod/16x16/actions/spread.gif
532 Bytes
public/designs/icons/tango/ie6/mod/16x16/apps/user.gif
620 Bytes
public/designs/icons/tango/ie6/mod/32x32/apps/gnome-help-red.gif
969 Bytes
public/designs/icons/tango/style.css
1 | -@import url(ie6.css); | |
2 | - | |
3 | 1 | /******************SMALL ICONS********************/ |
4 | 2 | .icon-edit { background-image: url(Tango/16x16/apps/text-editor.png) } |
5 | -.icon-home { background-image: url(Tango/16x16/actions/go-home.png) } | |
3 | +.icon-home { background-image: url(Tango/16x16/actions/go-home.png) } | |
6 | 4 | .icon-new, |
7 | -.icon-suggest { background-image: url(Tango/16x16/actions/filenew.png) } | |
8 | -.icon-close { background-image: url(Tango/16x16/actions/gtk-cancel.png) } | |
5 | +.icon-suggest { background-image: url(Tango/16x16/actions/filenew.png) } | |
6 | +.icon-close { background-image: url(Tango/16x16/actions/gtk-cancel.png) } | |
9 | 7 | .icon-newfolder { background-image: url(Tango/16x16/actions/folder-new.png) } |
10 | 8 | .icon-folder { background-image: url(Tango/16x16/places/folder.png) } |
11 | -.icon-parent-folder { background-image: url(Tango/16x16/places/folder_home.png) } | |
9 | +.icon-parent-folder { background-image: url(Tango/16x16/places/folder_home.png) } | |
12 | 10 | .icon-newblog { background-image: url(mod/16x16/apps/text-editor.png) } |
13 | 11 | .icon-blog { background-image: url(mod/16x16/apps/text-editor.png) } |
14 | -/*.icon-open { background-image: url(folder-open.gif) } UNUSED*/ | |
15 | -/*.icon-cms { background-image: url(abiword_48.png) } UNUSED*/ | |
16 | -.icon-save { background-image: url(Tango/16x16/actions/filesave.png) } | |
17 | -.icon-send { background-image: url(Tango/16x16/actions/stock_mail-forward.png) } | |
18 | -.icon-cancel { background-image: url(Tango/16x16/actions/gtk-cancel.png) } | |
19 | -.icon-person { background-image: url(Tango/16x16/apps/system-config-users.png) } | |
20 | -.icon-product { background-image: url(Tango/16x16/mimetypes/package.png) } | |
12 | +/*.icon-open { background-image: url(folder-open.gif) } UNUSED*/ | |
13 | +/*.icon-cms { background-image: url(abiword_48.png) } UNUSED*/ | |
14 | +.icon-save { background-image: url(Tango/16x16/actions/filesave.png) } | |
15 | +.icon-send { background-image: url(Tango/16x16/actions/stock_mail-forward.png) } | |
16 | +.icon-cancel { background-image: url(Tango/16x16/actions/gtk-cancel.png) } | |
17 | +.icon-person { background-image: url(Tango/16x16/apps/system-config-users.png) } | |
18 | +.icon-product { background-image: url(Tango/16x16/mimetypes/package.png) } | |
21 | 19 | .icon-delete { background-image: url(Tango/16x16/places/user-trash.png) } |
22 | -/*.icon-find { background-image: url(noosfero-find.png) } UNUSED*/ | |
23 | -.icon-back { background-image: url(Tango/16x16/actions/back.png) } | |
24 | -.icon-next { background-image: url(Tango/16x16/actions/go-next.png) } | |
25 | -.icon-add { background-image: url(Tango/16x16/actions/add.png) } | |
26 | -.icon-remove { background-image: url(Tango/16x16/actions/gtk-remove.png) } | |
27 | -.icon-more { background-image: url(Tango/16x16/actions/add.png) } | |
28 | -.icon-up { background-image: url(Tango/16x16/actions/go-up.png) } | |
29 | -.icon-down { background-image: url(Tango/16x16/actions/go-down.png) } | |
30 | -.icon-left { background-image: url(Tango/16x16/actions/go-previous.png) } | |
31 | -.icon-right { background-image: url(Tango/16x16/actions/go-next.png) } | |
32 | -.icon-up-disabled { background-image: url(Tango/16x16/actions/go-up.png); opacity: 0.25; filter:alpha(opacity=25); } | |
33 | -.icon-down-disabled { background-image: url(Tango/16x16/actions/go-down.png); opacity: 0.25; filter:alpha(opacity=25); } | |
34 | -.icon-left-disabled { background-image: url(Tango/16x16/actions/go-previous.png); opacity: 0.25; filter:alpha(opacity=25); } | |
35 | -.icon-right-disabled { background-image: url(Tango/16x16/actions/go-next.png); opacity: 0.25; filter:alpha(opacity=25); } | |
36 | -.icon-up-red { background-image: url(mod/16x16/actions/go-up-red.png) } | |
37 | -.icon-forward { background-image: url(Tango/16x16/actions/go-next.png) } | |
38 | -.icon-search { background-image: url(Tango/16x16/actions/search.png) } | |
39 | -.icon-ok { background-image: url(Tango/16x16/actions/media-playback-start.png) } | |
40 | -.icon-login { background-image: url(mod/16x16/actions/log-in.png) } | |
41 | -.icon-help { background-image: url(Tango/16x16/apps/gnome-help.png) } | |
42 | -.icon-firefox { background-image: url(firefox-24x24.gif) } | |
43 | -.icon-help32on { background-image: url(Tango/32x32/apps/gnome-help.png) } | |
44 | -.icon-help32off { background-image: url(mod/32x32/apps/gnome-help-red.png) } | |
20 | +/*.icon-find { background-image: url(noosfero-find.png) } UNUSED*/ | |
21 | +.icon-back { background-image: url(Tango/16x16/actions/back.png) } | |
22 | +.icon-next { background-image: url(Tango/16x16/actions/go-next.png) } | |
23 | +.icon-add { background-image: url(Tango/16x16/actions/add.png) } | |
24 | +.icon-remove { background-image: url(Tango/16x16/actions/gtk-remove.png) } | |
25 | +.icon-more { background-image: url(Tango/16x16/actions/add.png) } | |
26 | +.icon-up { background-image: url(Tango/16x16/actions/go-up.png) } | |
27 | +.icon-down { background-image: url(Tango/16x16/actions/go-down.png) } | |
28 | +.icon-left { background-image: url(Tango/16x16/actions/go-previous.png) } | |
29 | +.icon-right { background-image: url(Tango/16x16/actions/go-next.png) } | |
30 | +.icon-up-disabled { background-image: url(Tango/16x16/actions/go-up.png); opacity: 0.25; filter:alpha(opacity=25); } | |
31 | +.icon-down-disabled { background-image: url(Tango/16x16/actions/go-down.png); opacity: 0.25; filter:alpha(opacity=25); } | |
32 | +.icon-left-disabled { background-image: url(Tango/16x16/actions/go-previous.png); opacity: 0.25; filter:alpha(opacity=25); } | |
33 | +.icon-right-disabled { background-image: url(Tango/16x16/actions/go-next.png); opacity: 0.25; filter:alpha(opacity=25); } | |
34 | +.icon-up-red { background-image: url(mod/16x16/actions/go-up-red.png) } | |
35 | +.icon-forward { background-image: url(Tango/16x16/actions/go-next.png) } | |
36 | +.icon-search { background-image: url(Tango/16x16/actions/search.png) } | |
37 | +.icon-ok { background-image: url(Tango/16x16/actions/media-playback-start.png) } | |
38 | +.icon-login { background-image: url(mod/16x16/actions/log-in.png) } | |
39 | +.icon-help { background-image: url(Tango/16x16/apps/gnome-help.png) } | |
40 | +.icon-firefox { background-image: url(firefox-24x24.gif) } | |
41 | +.icon-help32on { background-image: url(Tango/32x32/apps/gnome-help.png) } | |
42 | +.icon-help32off { background-image: url(mod/32x32/apps/gnome-help-red.png) } | |
45 | 43 | .icon-spread { background-image: url(mod/16x16/actions/spread.png) } |
46 | -.icon-todo { background-image: url(Tango/16x16/actions/stock_paste.png) } | |
47 | -.icon-eyes { background-image: url(Tango/16x16/actions/gtk-print-preview.png) } | |
48 | -/*.icon-menu- { background-image: url(menu-without-ico-HC.gif) }*/ | |
49 | -.icon-menu-home { background-image: url(Tango/16x16/actions/go-home.png) } | |
50 | -/*.icon-menu-blog { background-image: url(blog-HC.gif) } UNUSED*/ | |
51 | -/*.icon-menu-album { background-image: url(album-HC.gif) } UNUSED*/ | |
52 | -.icon-menu-product { background-image: url(Tango/16x16/mimetypes/package.png) } | |
53 | -.icon-menu-enterprise { background-image: url(Tango/16x16/actions/go-home.png) } | |
54 | -.icon-menu-community { background-image: url(Tango/16x16/apps/system-config-users.png) } | |
55 | -/*.icon-menu-edit { background-image: url(edit-HC.gif) } UNUSED */ | |
56 | -.icon-menu-ctrl-panel { background-image: url(Tango/16x16/categories/preferences-desktop.png) } | |
57 | -.icon-menu-admin { background-image: url(Tango/16x16/categories/preferences-system.png) } | |
58 | -.icon-menu-my-groups { background-image: url(Tango/16x16/apps/system-config-users.png) } | |
59 | -.icon-menu-login { background-image: url(mod/16x16/actions/log-in.png) } | |
60 | -.icon-menu-logout { background-image: url(mod/16x16/actions/log-out.png) } | |
61 | -.icon-menu-search { background-image: url(Tango/16x16/actions/search.png) } | |
62 | -/*.icon-menu-ed-design { background-image: url(edit-design-HC.gif) } UNUSED */ | |
63 | -.icon-menu-events { background-image: url(Tango/16x16/mimetypes/stock_calendar.png) } | |
64 | -.icon-event { background-image: url(Tango/16x16/mimetypes/stock_calendar.png) } | |
65 | -.icon-newevent { background-image: url(Tango/16x16/mimetypes/stock_calendar.png) } | |
66 | -.icon-menu-articles { background-image: url(Tango/16x16/apps/text-editor.png) } | |
67 | -/*.icon-menu-comments { background-image: url(blog-HC.gif) } UNUSED */ | |
68 | -.icon-menu-people { background-image: url(mod/16x16/apps/user.png) } | |
69 | -.icon-menu-mail { background-image: url(Tango/16x16/apps/email.png) } | |
70 | -.icon-upload-file { background-image: url(Tango/16x16/actions/filesave.png) } | |
71 | -.icon-newupload-file { background-image: url(Tango/16x16/actions/filesave.png) } | |
72 | -.icon-slideshow { background-image: url(Tango/16x16/mimetypes/x-office-presentation.png) } | |
44 | +.icon-todo { background-image: url(Tango/16x16/actions/stock_paste.png) } | |
45 | +.icon-eyes { background-image: url(Tango/16x16/actions/find.png) } | |
46 | +/*.icon-menu- { background-image: url(menu-without-ico-HC.gif) }*/ | |
47 | +.icon-menu-home { background-image: url(Tango/16x16/actions/go-home.png) } | |
48 | +/*.icon-menu-blog { background-image: url(blog-HC.gif) } UNUSED*/ | |
49 | +/*.icon-menu-album { background-image: url(album-HC.gif) } UNUSED*/ | |
50 | +.icon-menu-product { background-image: url(Tango/16x16/mimetypes/package.png) } | |
51 | +.icon-menu-enterprise { background-image: url(Tango/16x16/actions/go-home.png) } | |
52 | +.icon-menu-community { background-image: url(Tango/16x16/apps/system-config-users.png) } | |
53 | +/*.icon-menu-edit { background-image: url(edit-HC.gif) } UNUSED */ | |
54 | +.icon-menu-ctrl-panel { background-image: url(Tango/16x16/categories/preferences-desktop.png) } | |
55 | +.icon-menu-admin { background-image: url(Tango/16x16/categories/preferences-system.png) } | |
56 | +.icon-menu-my-groups { background-image: url(Tango/16x16/apps/system-config-users.png) } | |
57 | +.icon-menu-login { background-image: url(mod/16x16/actions/log-in.png) } | |
58 | +.icon-menu-logout { background-image: url(mod/16x16/actions/log-out.png) } | |
59 | +.icon-menu-search { background-image: url(Tango/16x16/actions/search.png) } | |
60 | +/*.icon-menu-ed-design { background-image: url(edit-design-HC.gif) } UNUSED */ | |
61 | +.icon-menu-events { background-image: url(Tango/16x16/mimetypes/stock_calendar.png) } | |
62 | +.icon-event { background-image: url(Tango/16x16/mimetypes/stock_calendar.png) } | |
63 | +.icon-newevent { background-image: url(Tango/16x16/mimetypes/stock_calendar.png) } | |
64 | +.icon-menu-articles { background-image: url(Tango/16x16/apps/text-editor.png) } | |
65 | +/*.icon-menu-comments { background-image: url(blog-HC.gif) } UNUSED */ | |
66 | +.icon-menu-people { background-image: url(mod/16x16/apps/user.png) } | |
67 | +.icon-menu-mail { background-image: url(Tango/16x16/apps/email.png) } | |
68 | +.icon-upload-file { background-image: url(Tango/16x16/actions/filesave.png) } | |
69 | +.icon-newupload-file { background-image: url(Tango/16x16/actions/filesave.png) } | |
70 | +.icon-slideshow { background-image: url(Tango/16x16/mimetypes/x-office-presentation.png) } | |
73 | 71 | .icon-photos { background-image: url(Tango/16x16/devices/camera-photo.png) } |
74 | 72 | |
75 | -.icon-text-html { background-image: url(Tango/16x16/mimetypes/text-html.png) } | |
73 | +.icon-text-html { background-image: url(Tango/16x16/mimetypes/text-html.png) } | |
76 | 74 | .icon-text-plain { background-image: url(Tango/16x16/mimetypes/text-x-generic.png) } |
77 | -.icon-image-svg-xml { background-image: url(Tango/16x16/mimetypes/image-x-generic.png) } | |
75 | +.icon-image-svg-xml { background-image: url(Tango/16x16/mimetypes/image-x-generic.png) } | |
78 | 76 | .icon-application-octet-stream { background-image: url(Tango/16x16/mimetypes/binary.png) } |
79 | -.icon-application-x-gzip { background-image: url(Tango/16x16/mimetypes/gnome-mime-application-x-gzip.png) } | |
80 | -.icon-application-postscript { background-image: url(Tango/16x16/mimetypes/gnome-mime-application-postscript.png) } | |
81 | -.icon-application-pdf { background-image: url(Tango/16x16/mimetypes/gnome-mime-application-pdf.png) } | |
82 | -.icon-application-ogg { background-image: url(Tango/16x16/mimetypes/gnome-mime-application-ogg.png) } | |
83 | -.icon-video-mpeg { background-image: url(Tango/16x16/mimetypes/video-x-generic.png) } | |
84 | -.icon-application-vnd-oasis-opendocument-text { background-image: url(Tango/16x16/mimetypes/gnome-mime-application-vnd.oasis.opendocument.text.png) } | |
77 | +.icon-application-x-gzip { background-image: url(Tango/16x16/mimetypes/gnome-mime-application-x-gzip.png) } | |
78 | +.icon-application-postscript { background-image: url(Tango/16x16/mimetypes/gnome-mime-application-postscript.png) } | |
79 | +.icon-application-pdf { background-image: url(Tango/16x16/mimetypes/gnome-mime-application-pdf.png) } | |
80 | +.icon-application-ogg { background-image: url(Tango/16x16/mimetypes/gnome-mime-application-ogg.png) } | |
81 | +.icon-video, .icon-video-mpeg { background-image: url(Tango/16x16/mimetypes/video-x-generic.png) } | |
82 | +.icon-application-vnd-oasis-opendocument-text { background-image: url(Tango/16x16/mimetypes/gnome-mime-application-vnd.oasis.opendocument.text.png) } | |
85 | 83 | .icon-application-vnd-oasis-opendocument-spreadsheet { background-image: url(Tango/16x16/mimetypes/gnome-mime-application-vnd.oasis.opendocument.spreadsheet.png) } |
86 | -.icon-application-vnd-oasis-opendocument-presentation { background-image: url(Tango/16x16/mimetypes/gnome-mime-application-vnd.oasis.opendocument.presentation.png) } | |
84 | +.icon-application-vnd-oasis-opendocument-presentation { background-image: url(Tango/16x16/mimetypes/gnome-mime-application-vnd.oasis.opendocument.presentation.png) } | |
87 | 85 | |
88 | -.icon-media-pause { background-image: url(Tango/16x16/actions/media-playback-pause.png) } | |
89 | -.icon-media-play { background-image: url(Tango/16x16/actions/media-playback-start.png) } | |
90 | -.icon-media-prev { background-image: url(Tango/16x16/actions/media-skip-backward.png) } | |
91 | -.icon-media-next { background-image: url(Tango/16x16/actions/media-skip-forward.png) } | |
86 | +.icon-media-pause { background-image: url(Tango/16x16/actions/media-playback-pause.png) } | |
87 | +.icon-media-play { background-image: url(Tango/16x16/actions/media-playback-start.png) } | |
88 | +.icon-media-prev { background-image: url(Tango/16x16/actions/media-skip-backward.png) } | |
89 | +.icon-media-next { background-image: url(Tango/16x16/actions/media-skip-forward.png) } | |
92 | 90 | .icon-lock { background-image: url(Tango/16x16/actions/lock.png) } |
93 | -.icon-chat { background-image: url(Tango/16x16/apps/internet-group-chat.png); background-repeat: no-repeat } | |
94 | -.icon-reply { background-image: url(Tango/16x16/actions/mail-reply-sender.png) } | |
95 | -.icon-newforum { background-image: url(Tango/16x16/apps/internet-group-chat.png) } | |
96 | -.icon-forum { background-image: url(Tango/16x16/apps/system-users.png) } | |
97 | -.icon-gallery { background-image: url(Tango/16x16/mimetypes/image-x-generic.png) } | |
91 | +.icon-chat { background-image: url(Tango/16x16/apps/internet-group-chat.png); background-repeat: no-repeat } | |
92 | +.icon-reply { background-image: url(Tango/16x16/actions/mail-reply-sender.png) } | |
93 | +.icon-newforum { background-image: url(Tango/16x16/apps/internet-group-chat.png) } | |
94 | +.icon-forum { background-image: url(Tango/16x16/apps/system-users.png) } | |
95 | +.icon-gallery { background-image: url(Tango/16x16/mimetypes/image-x-generic.png) } | |
98 | 96 | .icon-newgallery { background-image: url(Tango/16x16/mimetypes/image-x-generic.png) } |
99 | -.icon-locale { background-image: url(Tango/16x16/apps/preferences-desktop-locale.png) } | |
100 | -.icon-user-removed { background-image: url(Tango/16x16/actions/gtk-cancel.png) } | |
101 | -.icon-user-unknown { background-image: url(Tango/16x16/status/dialog-error.png) } | |
102 | -.icon-alert { background-image: url(Tango/16x16/status/dialog-warning.png) } | |
97 | +.icon-locale { background-image: url(Tango/16x16/apps/preferences-desktop-locale.png) } | |
98 | +.icon-user-removed { background-image: url(Tango/16x16/actions/gtk-cancel.png) } | |
99 | +.icon-user-unknown { background-image: url(Tango/16x16/status/dialog-error.png) } | |
100 | +.icon-alert { background-image: url(Tango/16x16/status/dialog-warning.png) } | |
103 | 101 | |
104 | 102 | /******************LARGE ICONS********************/ |
105 | -.image-gallery-item .folder { background-image: url(mod/96x96/places/folder.png) } | |
106 | -.image-gallery-item .gallery { background-image: url(mod/96x96/mimetypes/image-x-generic.png) } | |
103 | +.image-gallery-item .folder { background-image: url(mod/96x96/places/folder.png) } | |
104 | +.image-gallery-item .gallery { background-image: url(mod/96x96/mimetypes/image-x-generic.png) } | ... | ... |
public/designs/themes/base/style.css
... | ... | @@ -89,7 +89,7 @@ body, th, td, input { |
89 | 89 | color: #555753; |
90 | 90 | } |
91 | 91 | |
92 | -#controlpanel, #logout, #openchat, #manage-enterprises { | |
92 | +#controlpanel, #logout, #openchat, .manage-groups { | |
93 | 93 | margin-left: 25px; |
94 | 94 | } |
95 | 95 | |
... | ... | @@ -822,12 +822,6 @@ div#notice { |
822 | 822 | margin-bottom: 0px; |
823 | 823 | } |
824 | 824 | |
825 | -X.sep { | |
826 | - background: url(imgs/blog-sep.png) 50% 50% repeat-x; | |
827 | - padding: 10px 20px; | |
828 | - margin: 10px -19px; | |
829 | -} | |
830 | - | |
831 | 825 | /* ==> search-results.css <== */ |
832 | 826 | |
833 | 827 | |
... | ... | @@ -1019,6 +1013,46 @@ hr.pre-posts, hr.sep-posts { |
1019 | 1013 | background: transparent; |
1020 | 1014 | } |
1021 | 1015 | |
1016 | +/************* uploaded file *****************/ | |
1017 | + | |
1018 | +#article .gallery-navigation { | |
1019 | + padding: 10px 0; | |
1020 | +} | |
1021 | + | |
1022 | +#article .gallery-navigation .previous { | |
1023 | + margin-right: 10px; | |
1024 | +} | |
1025 | + | |
1026 | +#article .gallery-navigation .next { | |
1027 | + margin-left: 10px; | |
1028 | +} | |
1029 | + | |
1030 | +#article .gallery-navigation .total-of-images { | |
1031 | + font-weight: bold; | |
1032 | +} | |
1033 | + | |
1034 | +#article .uploaded-file-description { | |
1035 | + background: #f6f6f6; | |
1036 | + border-top: 1px solid #ccc; | |
1037 | + border-bottom: 1px solid #ccc; | |
1038 | + padding: 1em; | |
1039 | +} | |
1040 | +#article .uploaded-file-description.empty { | |
1041 | + display: none; | |
1042 | +} | |
1043 | + | |
1044 | +#article.file-generic .download-link { | |
1045 | + display: block; | |
1046 | + margin-bottom: 10px; | |
1047 | +} | |
1048 | +#article.file-generic .download-link span { | |
1049 | + font-size: 150%; | |
1050 | + padding-right: 5px; | |
1051 | +} | |
1052 | +#article.file-generic .download-link a { | |
1053 | + font-size: 180%; | |
1054 | + text-decoration: none; | |
1055 | +} | |
1022 | 1056 | |
1023 | 1057 | /**************************** Comments *******************************/ |
1024 | 1058 | ... | ... |
public/javascripts/application.js
... | ... | @@ -709,7 +709,7 @@ jQuery(function($) { |
709 | 709 | document.location.href = this.href; |
710 | 710 | }) |
711 | 711 | } |
712 | - $('#manage-enterprises-link').live('click', function() { | |
712 | + $('.manage-groups > a').live('click', function() { | |
713 | 713 | toggleMenu(this); |
714 | 714 | return false; |
715 | 715 | }); | ... | ... |
... | ... | @@ -0,0 +1,28 @@ |
1 | +function removeTaskBox(button, url, task_box_id, msg) { | |
2 | + var $ = jQuery; | |
3 | + if (msg && !confirm(msg)) { | |
4 | + return; | |
5 | + } | |
6 | + button = $(button); | |
7 | + button.addClass('task-button-loading'); | |
8 | + $.post(url, function (data) { | |
9 | + if (data.ok) { | |
10 | + $('#' + task_box_id).slideUp(); | |
11 | + } else { | |
12 | + button.removeClass('task-button-loading'); | |
13 | + button.addClass('task-button-failure'); | |
14 | + } | |
15 | + }); | |
16 | +} | |
17 | + | |
18 | +function toggleDetails(link, msg_hide, msg_show) { | |
19 | + var $ = jQuery; | |
20 | + $(link).toggleClass('icon-up icon-down'); | |
21 | + details = $(link).closest('.task_box').find('.suggest-article-details'); | |
22 | + if (details.css('display') == 'none') { | |
23 | + link.innerHTML = msg_hide; | |
24 | + } else { | |
25 | + link.innerHTML = msg_show; | |
26 | + } | |
27 | + details.slideToggle(); | |
28 | +} | ... | ... |
public/stylesheets/application.css
... | ... | @@ -882,6 +882,40 @@ code input { |
882 | 882 | .webkit #manage-enterprises .simplemenu-submenu { |
883 | 883 | top: 20px; |
884 | 884 | } |
885 | +#manage-communities { | |
886 | + display: inline-block; | |
887 | + margin-right: 5px; | |
888 | + position: relative; | |
889 | +} | |
890 | +#manage-communities .ui-icon { | |
891 | + position: absolute; | |
892 | + top: 0; | |
893 | + right: -20px; | |
894 | +} | |
895 | +#manage-communities .simplemenu-submenu { | |
896 | + text-align: left; | |
897 | + left: -20px; | |
898 | + width: 200px; | |
899 | +} | |
900 | +#manage-communities .simplemenu-item { | |
901 | + padding: 5px 0; | |
902 | +} | |
903 | +#manage-communities .simplemenu-item a { | |
904 | + background-repeat: no-repeat; | |
905 | + padding-left: 20px; | |
906 | +} | |
907 | +#manage-communities .simplemenu-item a span { | |
908 | + display: none; | |
909 | +} | |
910 | +.msie8 #manage-communities-link { /* IE8 hack */ | |
911 | + border: 0px solid; | |
912 | +} | |
913 | +.msie8 #manage-communities .simplemenu-submenu { | |
914 | + top: 16px; | |
915 | +} | |
916 | +.webkit #manage-communities .simplemenu-submenu { | |
917 | + top: 20px; | |
918 | +} | |
885 | 919 | #article { |
886 | 920 | position: relative; |
887 | 921 | text-align: justify; |
... | ... | @@ -1552,6 +1586,7 @@ a.button.disabled, input.disabled { |
1552 | 1586 | .map { |
1553 | 1587 | clear: both; |
1554 | 1588 | } |
1589 | + | |
1555 | 1590 | /*********************************************************** |
1556 | 1591 | * style for blocks |
1557 | 1592 | ***********************************************************/ |
... | ... | @@ -3176,6 +3211,14 @@ table.cms-articles .icon:hover { |
3176 | 3211 | background: #eeeeec; |
3177 | 3212 | border: 1px solid #d3d7cf; |
3178 | 3213 | } |
3214 | + | |
3215 | +.controller-cms .article-mime { | |
3216 | + max-width: 90px; | |
3217 | + overflow: hidden; | |
3218 | + text-overflow: ellipsis; | |
3219 | + white-space: nowrap; | |
3220 | +} | |
3221 | + | |
3179 | 3222 | .controller-cms .article-controls { |
3180 | 3223 | white-space: nowrap; |
3181 | 3224 | } |
... | ... | @@ -3446,26 +3489,7 @@ div#article-parent { |
3446 | 3489 | .article-body-uploaded-file { |
3447 | 3490 | text-align: center; |
3448 | 3491 | } |
3449 | -/************* uploaded file *****************/ | |
3450 | 3492 | |
3451 | -#article .gallery-navigation { | |
3452 | - padding: 10px 0; | |
3453 | -} | |
3454 | -#article .gallery-navigation .left { | |
3455 | - margin-right: 10px; | |
3456 | -} | |
3457 | -#article .gallery-navigation .right { | |
3458 | - margin-left: 10px; | |
3459 | -} | |
3460 | -#article .gallery-navigation .total-of-images { | |
3461 | - font-weight: bold; | |
3462 | -} | |
3463 | -#article .uploaded-file-description { | |
3464 | - background: #f6f6f6; | |
3465 | - border-top: 1px solid #ccc; | |
3466 | - border-bottom: 1px solid #ccc; | |
3467 | - padding: 1em; | |
3468 | -} | |
3469 | 3493 | /* ==> public/stylesheets/controller_events.css <== */ |
3470 | 3494 | #agenda { |
3471 | 3495 | position: relative; | ... | ... |
script/development
test/functional/cms_controller_test.rb
... | ... | @@ -940,8 +940,8 @@ class CmsControllerTest < ActionController::TestCase |
940 | 940 | :article => {:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png')} |
941 | 941 | |
942 | 942 | process_delayed_job_queue |
943 | - file = profile.articles.find_by_name('rails.png') | |
944 | - assert File.exists?(file.class.icon_name(file)) | |
943 | + file = FilePresenter.for profile.articles.find_by_name('rails.png') | |
944 | + assert File.exists?(file.icon_name) | |
945 | 945 | file.destroy |
946 | 946 | end |
947 | 947 | |
... | ... | @@ -951,8 +951,8 @@ class CmsControllerTest < ActionController::TestCase |
951 | 951 | :article => {:uploaded_data => fixture_file_upload('/files/rails.png', 'image/png')} |
952 | 952 | |
953 | 953 | process_delayed_job_queue |
954 | - file = profile.articles.find_by_name('rails.png') | |
955 | - assert File.exists?(file.class.icon_name(file)) | |
954 | + file = FilePresenter.for profile.articles.find_by_name('rails.png') | |
955 | + assert File.exists?(file.icon_name) | |
956 | 956 | file.destroy |
957 | 957 | end |
958 | 958 | ... | ... |