Commit d22033e15511619097d416269ad76cba4fd440a6

Authored by Victor Costa
2 parents e76b5bbb 11166297

Merge branch 'stable' of gitlab.com:participa/noosfero into stable

Conflicts:
	Gemfile
Showing 59 changed files with 1124 additions and 80 deletions   Show diff stats
@@ -15,7 +15,7 @@ gem 'thin', '~> 1.3.1' @@ -15,7 +15,7 @@ gem 'thin', '~> 1.3.1'
15 gem 'hpricot', '~> 0.8.6' 15 gem 'hpricot', '~> 0.8.6'
16 gem 'nokogiri', '~> 1.5.5' 16 gem 'nokogiri', '~> 1.5.5'
17 gem 'rake', :require => false 17 gem 'rake', :require => false
18 -gem 'grape', '0.2.1' 18 +gem 'grape', '~> 0.2.1'
19 gem 'rest-client', '~> 1.6.7' 19 gem 'rest-client', '~> 1.6.7'
20 gem 'exception_notification', '~> 4.0.1' 20 gem 'exception_notification', '~> 4.0.1'
21 gem 'gettext', '~> 2.2.1', :require => false, :group => :development 21 gem 'gettext', '~> 2.2.1', :require => false, :group => :development
lib/feed_writer.rb
@@ -19,7 +19,7 @@ class FeedWriter @@ -19,7 +19,7 @@ class FeedWriter
19 for article in articles 19 for article in articles
20 xml.item do 20 xml.item do
21 xml.title(article.name) 21 xml.title(article.name)
22 - xml.description(article.to_html) 22 + xml.description(article.to_html(:feed => true))
23 if article.created_at 23 if article.created_at
24 # rfc822 24 # rfc822
25 xml.pubDate(article.created_at.rfc2822) 25 xml.pubDate(article.created_at.rfc2822)
plugins/dspace/controllers/dspace_plugin_controller.rb 0 → 100644
@@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
  1 +class DspacePluginController < PublicController
  2 + append_view_path File.join(File.dirname(__FILE__) + '/../views')
  3 +
  4 + def view_item
  5 +
  6 + collection_id = params[:collection_id]
  7 + item_id = params[:id]
  8 +
  9 + begin
  10 + @collection = DspacePlugin::Collection.find(collection_id)
  11 + rescue ActiveRecord::RecordNotFound
  12 + render_not_found
  13 + return
  14 + end
  15 +
  16 + begin
  17 + dspace_server = @collection.parent.parent.dspace_server_url
  18 + @item = Dspace::Item.get_item_by_id dspace_server, item_id
  19 + rescue ActiveResource::UnauthorizedAccess
  20 + render_not_found
  21 + return
  22 + end
  23 +
  24 + begin
  25 + @collection = DspacePlugin::Collection.find(collection_id)
  26 + rescue ActiveRecord::RecordNotFound
  27 + render_not_found
  28 + return
  29 + end
  30 +
  31 + end
  32 +
  33 +end
plugins/dspace/controllers/dspace_plugin_myprofile_controller.rb 0 → 100644
@@ -0,0 +1,72 @@ @@ -0,0 +1,72 @@
  1 +class DspacePluginMyprofileController < CmsController
  2 + append_view_path File.join(File.dirname(__FILE__) + '/../views')
  3 +
  4 + def new
  5 +
  6 + @success_back_to = params[:success_back_to]
  7 +
  8 + @parent = profile.articles.find(params[:parent_id]) if params && params[:parent_id]
  9 + record_coming
  10 + @type = params[:type]
  11 + if @type.blank?
  12 + @article_types = []
  13 + available_article_types.each do |type|
  14 + @article_types.push({
  15 + :class => type,
  16 + :short_description => type.short_description,
  17 + :description => type.description
  18 + })
  19 + end
  20 + @parent_id = params[:parent_id]
  21 + render :action => 'select_article_type', :layout => false, :back_to => @back_to
  22 + return
  23 + else
  24 + refuse_blocks
  25 + end
  26 +
  27 + raise "Invalid article type #{@type}" unless valid_article_type?(@type)
  28 +
  29 + klass = @type.constantize
  30 + article_data = environment.enabled?('articles_dont_accept_comments_by_default') ? { :accept_comments => false } : {}
  31 + article_data.merge!(params[:article]) if params[:article]
  32 +
  33 + if @type == 'DspacePlugin::Collection'
  34 + dspace_objects = article_data['dspace_collections']
  35 + elsif @type == 'DspacePlugin::Communityy'
  36 + dspace_objects = article_data['dspace_communities']
  37 + end
  38 +
  39 + dspace_objects.each do |object|
  40 +
  41 + entity = klass.new
  42 +
  43 + parent = check_parent(params[:parent_id])
  44 +
  45 + if parent
  46 + entity.parent = parent
  47 + parent_id = parent.id
  48 + end
  49 +
  50 + if @type == 'DspacePlugin::Communityy'
  51 + entity.dspace_community_id = object['id']
  52 + elsif @type == 'DspacePlugin::Collection'
  53 + entity.dspace_community_id = article_data['dspace_community_id']
  54 + entity.dspace_collection_id = object['id']
  55 + entity.accept_comments = false
  56 + end
  57 +
  58 + entity.name = object['name']
  59 + entity.profile = profile
  60 + entity.author = user
  61 + entity.last_changed_by = user
  62 + entity.created_by = user
  63 +
  64 + entity.save!
  65 +
  66 + end
  67 +
  68 + redirect_to @parent.view_url
  69 +
  70 + end
  71 +
  72 +end
plugins/dspace/lib/dspace/collection.rb 0 → 100644
@@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
  1 +class Dspace::Collection < Dspace::Resource
  2 +
  3 + def self.get_all_items_from(dspace_server, collection_id)
  4 + self.site = dspace_server
  5 + result = self.find collection_id, :params => { :expand => 'items' }
  6 +
  7 + item_list = []
  8 +
  9 + if result.items.count > 0
  10 + result.items.each { |element|
  11 + item = Dspace::Item.get_item_by_id dspace_server, element.id
  12 + item_list << item
  13 + }
  14 + end
  15 +
  16 + item_list
  17 + end
  18 +
  19 + def self.get_all_collections_from(dspace_server)
  20 + self.site = dspace_server
  21 + self.find(:all)
  22 + end
  23 +
  24 +end
plugins/dspace/lib/dspace/community.rb 0 → 100644
@@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
  1 +class Dspace::Community < Dspace::Resource
  2 +
  3 + def self.get_all_communities_from(dspace_server)
  4 + self.site = dspace_server
  5 + self.find(:all)
  6 + end
  7 +
  8 + def self.get_all_collections_from(dspace_server, community_id)
  9 + self.site = dspace_server
  10 + result = self.find community_id, :params => { :expand => 'collections' }
  11 + result.collections
  12 + end
  13 +
  14 +end
plugins/dspace/lib/dspace/item.rb 0 → 100644
@@ -0,0 +1,89 @@ @@ -0,0 +1,89 @@
  1 +class Dspace::Item < Dspace::Resource
  2 +
  3 + def self.get_all_item_metadata_from(dspace_server, item_id)
  4 + self.site = dspace_server
  5 + result = self.find item_id, :params => { :expand => 'metadata' }
  6 + result.metadata
  7 + end
  8 +
  9 + def self.get_item_by_id(dspace_server, item_id)
  10 + self.site = dspace_server
  11 + result = self.find item_id, :params => { :expand => 'metadata' }
  12 +
  13 + item_metadata = Dspace::Item.get_all_item_metadata_from self.site, result.id
  14 +
  15 + # author
  16 + metadata = item_metadata[0].attributes
  17 + if metadata != {}
  18 + metadata = Hash[[metadata.map{|k,v| v}]]
  19 + author = metadata.has_key?('dc.contributor.author') ? metadata['dc.contributor.author'] : nil
  20 + end
  21 +
  22 + # issue date
  23 + metadata = item_metadata[3].attributes
  24 + if metadata != {}
  25 + metadata = Hash[[metadata.map{|k,v| v}]]
  26 + issue_date = metadata.has_key?('dc.date.issued') ? metadata['dc.date.issued'] : nil
  27 + end
  28 +
  29 + # uri
  30 + metadata = item_metadata[4].attributes
  31 + if metadata != {}
  32 + metadata = Hash[[metadata.map{|k,v| v}]]
  33 + uri = metadata.has_key?('dc.identifier.uri') ? metadata['dc.identifier.uri'] : nil
  34 + end
  35 +
  36 + # description
  37 + metadata = item_metadata[5].attributes
  38 + if metadata != {}
  39 + metadata = Hash[[metadata.map{|k,v| v}]]
  40 + abstract = metadata.has_key?('dc.description') ? metadata['dc.description'] : nil
  41 + end
  42 +
  43 + # abstract
  44 + metadata = item_metadata[6].attributes
  45 + if metadata != {}
  46 + metadata = Hash[[metadata.map{|k,v| v}]]
  47 + description = metadata.has_key?('dc.description.abstract') ? metadata['dc.description.abstract'] : nil
  48 + end
  49 +
  50 + item = DspacePlugin::Item.new
  51 +
  52 + item.id = result.id
  53 + item.name = result.name
  54 + item.author = author
  55 + item.issue_date = issue_date
  56 + item.abstract = abstract
  57 + item.description = description
  58 + item.uri = uri
  59 +
  60 + ### BITSTREAMS
  61 +
  62 + item_bitstreams = self.find item_id, :params => { :expand => 'bitstreams' }
  63 +
  64 + bitstreams = item_bitstreams.bitstreams
  65 +
  66 + bitstreams.each do |bs|
  67 + bitstream = DspacePlugin::Bitstream.new
  68 + bitstream.id = bs.attributes[:id]
  69 + bitstream.name = bs.attributes[:name]
  70 + bitstream.description = bs.attributes[:description]
  71 + bitstream.mimetype = bs.attributes[:mimeType]
  72 + bitstream.size_bytes = bs.attributes[:sizeBytes]
  73 + bitstream.retrieve_link = bs.attributes[:retrieveLink]
  74 + bitstream.format = bs.attributes[:format]
  75 + bitstream.link = bs.attributes[:link]
  76 +
  77 + item.files << bitstream
  78 +
  79 + end
  80 +
  81 + if item.files.count > 0
  82 + item.mimetype = item.files.first.mimetype
  83 + end
  84 +
  85 + item
  86 +
  87 + end
  88 +
  89 +end
plugins/dspace/lib/dspace/resource.rb 0 → 100644
@@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
  1 +class Dspace::Resource < ActiveResource::Base
  2 +
  3 + class << self
  4 + def element_path(id, prefix_options = {}, query_options = nil)
  5 + prefix_options, query_options = split_options(prefix_options) if query_options.nil?
  6 + "#{prefix(prefix_options)}#{collection_name}/#{id}#{query_string(query_options)}"
  7 + end
  8 +
  9 + def collection_path(prefix_options = {}, query_options = nil)
  10 + prefix_options, query_options = split_options(prefix_options) if query_options.nil?
  11 + "#{prefix(prefix_options)}#{collection_name}#{query_string(query_options)}"
  12 + end
  13 + end
  14 +
  15 +end
plugins/dspace/lib/dspace_plugin.rb 0 → 100644
@@ -0,0 +1,36 @@ @@ -0,0 +1,36 @@
  1 +class DspacePlugin < Noosfero::Plugin
  2 +
  3 + def self.plugin_name
  4 + "DSpace Plugin"
  5 + end
  6 +
  7 + def self.plugin_description
  8 + _("A plugin that add a DSpace library feature to noosfero.")
  9 + end
  10 +
  11 + def content_types
  12 + if context.respond_to?(:params) && context.params
  13 + types = []
  14 + parent_id = context.params[:parent_id]
  15 + types << DspacePlugin::Library if context.profile.community? && !parent_id
  16 + parent = parent_id ? context.profile.articles.find(parent_id) : nil
  17 + if parent.kind_of?(DspacePlugin::Library)
  18 + types << DspacePlugin::Communityy
  19 + elsif parent.kind_of?(DspacePlugin::Communityy)
  20 + types << DspacePlugin::Collection
  21 + end
  22 + types
  23 + else
  24 + [DspacePlugin::Library, DspacePlugin::Collection, DspacePlugin::Communityy]
  25 + end
  26 + end
  27 +
  28 + def stylesheet?
  29 + true
  30 + end
  31 +
  32 + def self.has_admin_url?
  33 + false
  34 + end
  35 +
  36 +end
plugins/dspace/lib/dspace_plugin/bitstream.rb 0 → 100644
@@ -0,0 +1,5 @@ @@ -0,0 +1,5 @@
  1 +class DspacePlugin::Bitstream
  2 +
  3 + attr_accessor :id, :name, :description, :mimetype, :size_bytes, :retrieve_link, :format, :link
  4 +
  5 +end
plugins/dspace/lib/dspace_plugin/collection.rb 0 → 100644
@@ -0,0 +1,31 @@ @@ -0,0 +1,31 @@
  1 +class DspacePlugin::Collection < Article
  2 +
  3 + settings_items :dspace_collection_id, :type => :string
  4 + settings_items :dspace_community_id, :type => :integer
  5 +
  6 + attr_accessible :dspace_collection_id, :dspace_community_id
  7 +
  8 + def self.icon_name(article = nil)
  9 + 'dspace-collection'
  10 + end
  11 +
  12 + def self.short_description
  13 + _("DSpace collection")
  14 + end
  15 +
  16 + def self.description
  17 + _("Defines a DSpace collection")
  18 + end
  19 +
  20 + def to_html(options = {})
  21 + dspace_content = self
  22 + proc do
  23 + render :file => 'content_viewer/dspace_content', :locals => { :dspace_content => dspace_content }
  24 + end
  25 + end
  26 +
  27 + def items(dspace_server, collection_id)
  28 + Dspace::Collection.get_all_items_from dspace_server, collection_id
  29 + end
  30 +
  31 +end
plugins/dspace/lib/dspace_plugin/collection_helper.rb 0 → 100644
@@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
  1 +module DspacePlugin::CollectionHelper
  2 +
  3 + include ArticleHelper
  4 +
  5 + def custom_options_for_article(article,tokenized_children)
  6 + @article = article
  7 +
  8 + visibility_options(article,tokenized_children) +
  9 + content_tag('div',
  10 + hidden_field_tag('article[accept_comments]', 0)
  11 + )
  12 + end
  13 +
  14 +end
plugins/dspace/lib/dspace_plugin/communityy.rb 0 → 100644
@@ -0,0 +1,30 @@ @@ -0,0 +1,30 @@
  1 +class DspacePlugin::Communityy < Folder
  2 +
  3 + settings_items :dspace_community_id, :type => :string
  4 +
  5 + attr_accessible :dspace_community_id
  6 +
  7 + def self.icon_name(article = nil)
  8 + 'dspace-community'
  9 + end
  10 +
  11 + def self.short_description
  12 + _("DSpace community")
  13 + end
  14 +
  15 + def self.description
  16 + _("Defines a DSpace community")
  17 + end
  18 +
  19 + def to_html(options = {})
  20 + dspace_content = self
  21 + proc do
  22 + render :file => 'content_viewer/dspace_content', :locals => { :dspace_content => dspace_content }
  23 + end
  24 + end
  25 +
  26 + def collections(dspace_server, community_id)
  27 + DspacePlugin::Collection.find(:all)
  28 + end
  29 +
  30 +end
plugins/dspace/lib/dspace_plugin/communityy_helper.rb 0 → 100644
@@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
  1 +module DspacePlugin::CommunityyHelper
  2 +
  3 + include ArticleHelper
  4 +
  5 + def custom_options_for_article(article,tokenized_children)
  6 + @article = article
  7 +
  8 + visibility_options(article,tokenized_children) +
  9 + content_tag('div',
  10 + hidden_field_tag('article[accept_comments]', 0)
  11 + )
  12 + end
  13 +
  14 +end
plugins/dspace/lib/dspace_plugin/item.rb 0 → 100644
@@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
  1 +class DspacePlugin::Item
  2 +
  3 + include DspacePlugin::ItemHelper
  4 +
  5 + attr_accessor :id, :name, :author, :issue_date, :abstract, :description, :uri, :files, :mimetype
  6 +
  7 + def initialize
  8 + self.files = []
  9 + end
  10 +
  11 +end
plugins/dspace/lib/dspace_plugin/item_helper.rb 0 → 100644
@@ -0,0 +1,90 @@ @@ -0,0 +1,90 @@
  1 +module DspacePlugin::ItemHelper
  2 +
  3 + TEXT_MIMETYPES = [ 'text/plain; charset=utf-8',
  4 + 'text/html',
  5 + 'text/xml',
  6 + 'text/plain',
  7 + 'text/html',
  8 + 'text/css',
  9 + 'text/richtext' ]
  10 +
  11 + AUDIO_MIMETYPES = [ 'audio/x-pn-realaudio',
  12 + 'audio/x-mpeg',
  13 + 'audio/x-aiff',
  14 + 'audio/basic',
  15 + 'audio/x-wav' ]
  16 +
  17 + DOCUMENT_MIMETYPES = [ 'application/msword',
  18 + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
  19 + 'application/vnd.oasis.opendocument.text',
  20 + 'application/vnd.oasis.opendocument.text-template',
  21 + 'application/vnd.oasis.opendocument.text-web',
  22 + 'application/vnd.oasis.opendocument.text-master',
  23 + 'application/vnd.sun.xml.writer',
  24 + 'application/vnd.sun.xml.writer.template',
  25 + 'application/vnd.sun.xml.writer.global',
  26 + 'application/vnd.stardivision.writer',
  27 + 'application/vnd.stardivision.writer-global' ]
  28 +
  29 + PICTURE_MIMETYPES = [ 'image/x-photo-cd',
  30 + 'image/x-ms-bmp',
  31 + 'image/jpeg',
  32 + 'image/gif',
  33 + 'image/png',
  34 + 'image/tiff',
  35 + 'application/x-photoshop',
  36 + 'application/postscript' ]
  37 +
  38 + SPREADSHEET_MIMETYPES = [ 'application/vnd.ms-excel',
  39 + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  40 + 'application/vnd.oasis.opendocument.spreadsheet',
  41 + 'application/vnd.oasis.opendocument.spreadsheet-template',
  42 + 'application/vnd.sun.xml.calc',
  43 + 'application/vnd.sun.xml.calc.template',
  44 + 'application/vnd.sun.xml.math',
  45 + 'application/vnd.stardivision.calc' ]
  46 +
  47 + VIDEO_MIMETYPES = [ 'video/quicktime',
  48 + 'video/mpeg' ]
  49 +
  50 +
  51 + def remove_slash_at_end_url(url)
  52 + url.gsub!(/\/$/,'') if url =~ /\/$/
  53 + url
  54 + end
  55 +
  56 + def class_for_item_mimetype(mimetype)
  57 +
  58 + case
  59 +
  60 + when mimetype == 'application/pdf'
  61 + mimetype_class = 'pdf'
  62 +
  63 + when TEXT_MIMETYPES.include?(mimetype)
  64 + mimetype_class = 'text'
  65 +
  66 + when AUDIO_MIMETYPES.include?(mimetype)
  67 + mimetype_class = 'audio'
  68 +
  69 + when DOCUMENT_MIMETYPES.include?(mimetype)
  70 + mimetype_class = 'document'
  71 +
  72 + when PICTURE_MIMETYPES.include?(mimetype)
  73 + mimetype_class = 'picture'
  74 +
  75 + when SPREADSHEET_MIMETYPES.include?(mimetype)
  76 + mimetype_class = 'spreadsheet'
  77 +
  78 + when VIDEO_MIMETYPES.include?(mimetype)
  79 + mimetype_class = 'video'
  80 +
  81 + else
  82 + mimetype_class = 'other'
  83 +
  84 + end
  85 +
  86 + "icon-#{mimetype_class}"
  87 +
  88 + end
  89 +
  90 +end
plugins/dspace/lib/dspace_plugin/library.rb 0 → 100644
@@ -0,0 +1,49 @@ @@ -0,0 +1,49 @@
  1 +class DspacePlugin::Library < Folder
  2 +
  3 + settings_items :dspace_server_url, :type => :string
  4 +
  5 + attr_accessible :dspace_server_url
  6 +
  7 + def dspace_server_url_valid
  8 +
  9 + if self.dspace_server_url.blank?
  10 + errors.add(:dspace_server_url, _("can't be blank") )
  11 + return
  12 + end
  13 +
  14 + errors.add(self.dspace_server_url, _("is not a valid URL. Please correct it and resubmit.")) unless url_valid?(self.dspace_server_url)
  15 + end
  16 +
  17 + validate :dspace_server_url_valid
  18 +
  19 + def self.icon_name(article = nil)
  20 + 'dspace-library'
  21 + end
  22 +
  23 + def self.short_description
  24 + _("DSpace library")
  25 + end
  26 +
  27 + def self.description
  28 + _("Defines a DSpace library")
  29 + end
  30 +
  31 + def to_html(options = {})
  32 + dspace_content = self
  33 + proc do
  34 + render :file => 'content_viewer/dspace_content', :locals => { :dspace_content => dspace_content }
  35 + end
  36 + end
  37 +
  38 + def communities
  39 + DspacePlugin::Communityy.find(:all)
  40 + end
  41 +
  42 + protected
  43 +
  44 + def url_valid?(url)
  45 + url = URI.parse(url) rescue false
  46 + url.kind_of?(URI::HTTP) || url.kind_of?(URI::HTTPS)
  47 + end
  48 +
  49 +end
plugins/dspace/lib/dspace_plugin/library_helper.rb 0 → 100644
@@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
  1 +module DspacePlugin::LibraryHelper
  2 +
  3 + include ArticleHelper
  4 +
  5 + def custom_options_for_article(article,tokenized_children)
  6 + @article = article
  7 +
  8 + visibility_options(article,tokenized_children) +
  9 + content_tag('div',
  10 + hidden_field_tag('article[accept_comments]', 0)
  11 + )
  12 + end
  13 +
  14 +end
plugins/dspace/public/icons/audio.png 0 → 100644

717 Bytes

plugins/dspace/public/icons/document.png 0 → 100644

658 Bytes

plugins/dspace/public/icons/dspace.png 0 → 100644

3.2 KB

plugins/dspace/public/icons/pdf.png 0 → 100644

874 Bytes

plugins/dspace/public/icons/picture.png 0 → 100644

525 Bytes

plugins/dspace/public/icons/spreadsheet.png 0 → 100644

644 Bytes

plugins/dspace/public/icons/text.png 0 → 100644

419 Bytes

plugins/dspace/public/icons/video.png 0 → 100644

711 Bytes

plugins/dspace/public/javascripts/dspace_plugin.js 0 → 100644
@@ -0,0 +1,85 @@ @@ -0,0 +1,85 @@
  1 +/**
  2 +
  3 +function selectCommunity(element, community_slug) {
  4 + var hidden_field = jQuery('<input>').attr({
  5 + id: 'article_dspace_community_name_',
  6 + name: 'article[dspace_communities_names][]',
  7 + type: 'hidden',
  8 + name: 'article[dspace_communities_names][]',
  9 + value: community_slug
  10 + });
  11 + jQuery(hidden_field).insertAfter(element);
  12 +}
  13 +
  14 +
  15 +function selectCollection(element, collection_slug) {
  16 + var hidden_field = jQuery('<input>').attr({
  17 + id: 'article_dspace_collection_name_',
  18 + name: 'article[dspace_collections_names][]',
  19 + type: 'hidden',
  20 + name: 'article[dspace_collections_names][]',
  21 + value: collection_slug
  22 + });
  23 + jQuery(hidden_field).insertAfter(element);
  24 +}
  25 +
  26 +function select_action(field_active) {
  27 +}
  28 +**/
  29 +
  30 +jQuery(document).ready(function() {
  31 + url_base = window.location.protocol + '//' + window.location.host;
  32 + forms = jQuery('form');
  33 + forms.each( function(f) {
  34 + url_action = forms[f].action;
  35 + if (url_action.indexOf("/cms/new") > -1) {
  36 + forms[f].action = url_action.replace("/cms/new", "/plugin/dspace/new").replace(url_base,'');
  37 + }
  38 + });
  39 +
  40 + function check_fields(check, table_id) {
  41 + var checkboxes = jQuery("#" + table_id + " tbody tr td input[type='checkbox']")
  42 + for (var i = 0; i < checkboxes.length; i++) {
  43 + if (checkboxes[i].disabled == false) {
  44 + checkboxes[i].checked = check
  45 + }
  46 + }
  47 + }
  48 +
  49 + function verify_checked(field_id){
  50 + var checkboxes = jQuery("#" + field_id + "_fields_conf tbody tr td input[type='checkbox']")
  51 + var allchecked = true;
  52 + for (var j = 1; j < checkboxes.length; j++) {
  53 + if(!checkboxes[j].checked) {
  54 + allchecked = false;
  55 + break;
  56 + }
  57 + }
  58 +
  59 + var checkbox = jQuery("#" + field_id + "_active");
  60 + checkbox.attr("checked", allchecked);
  61 + }
  62 +
  63 +
  64 + function check_all(field_id) {
  65 + jQuery("#" + field_id + "_active").click(function (){
  66 + check_fields(this.checked, field_id + "_fields_conf")
  67 + });
  68 + verify_checked(field_id);
  69 + }
  70 +
  71 + check_all("community");
  72 + check_all("collection");
  73 +
  74 + jQuery("input[type='checkbox']").click(function () {
  75 + var checkbox = jQuery(this).attr("id").split("_");
  76 + verify_checked(checkbox.first());
  77 +
  78 + if(this.checked == false) {
  79 + jQuery("#" + checkbox.first() + "_" + checkbox.last()).attr("checked", false)
  80 + }
  81 +
  82 + jQuery(this).next().attr("disabled", !this.checked);
  83 + })
  84 +
  85 +});
plugins/dspace/public/style.css 0 → 100644
@@ -0,0 +1,101 @@ @@ -0,0 +1,101 @@
  1 +#dspace_library ul {
  2 + margin: 0;
  3 + padding: 0 0 0 5px;
  4 +}
  5 +
  6 +#dspace_library li {
  7 + /**list-style-image: url(/designs/themes/base/imgs/li-recent.gif);*/
  8 + list-style-type: none;
  9 +}
  10 +
  11 +#dspace_library li.item,
  12 +#dspace_library li.collection,
  13 +#dspace_library li.community {
  14 + margin: 0;
  15 + padding: 10px 0;
  16 +}
  17 +
  18 +#dspace_library li.item span.name,
  19 +#dspace_library li.collection span.title,
  20 +#dspace_library li.community span.title {
  21 + font-weight: bold;
  22 +}
  23 +
  24 +#dspace_library div#actions {
  25 + margin: 10px 0;
  26 +}
  27 +
  28 +#dspace_library_item {
  29 + /*8border: 1px solid green;*/
  30 +}
  31 +
  32 +.dspace_item_section {
  33 + margin: 15px;
  34 +}
  35 +
  36 +.dspace_item_section_title {
  37 + margin: 0px;
  38 + font-weight: bold;
  39 + border-bottom: 1px solid #c0c0c0;
  40 +}
  41 +
  42 +#dspace_library_item ul {
  43 + list-style-type: none;
  44 +}
  45 +
  46 +#dspace_library_item ul#item_files_list,
  47 +#dspace_library_item ul.item_file_attributes_list {
  48 + margin: 0;
  49 + padding: 0;
  50 +}
  51 +
  52 +#dspace_library_item ul#item_files_list > li {
  53 + margin: 5px 0;
  54 +}
  55 +
  56 +.icon-newdspace-library,
  57 +.icon-dspace-library,
  58 +.icon-newdspace-community,
  59 +.icon-dspace-community,
  60 +.icon-newdspace-collection,
  61 +.icon-dspace-collection {
  62 + background-image: url(/plugins/dspace/icons/dspace.png)
  63 +}
  64 +
  65 +#dspace_library div.icon-item {
  66 + width: 32px;
  67 + height: 33px;
  68 + display: inline-block;
  69 + vertical-align: top;
  70 + border-right: 1px solid #c0c0c0;
  71 +}
  72 +
  73 +#dspace_library div.icon-audio {
  74 + background-image: url(/plugins/dspace/icons/audio.png)
  75 +}
  76 +
  77 +#dspace_library div.icon-document {
  78 + background-image: url(/plugins/dspace/icons/document.png)
  79 +}
  80 +
  81 +#dspace_library div.icon-pdf {
  82 + background-image: url(/plugins/dspace/icons/pdf.png)
  83 +}
  84 +
  85 +#dspace_library div.icon-picture {
  86 + background-image: url(/plugins/dspace/icons/picture.png)
  87 +}
  88 +
  89 +#dspace_library div.icon-spreadsheet {
  90 + background-image: url(/plugins/dspace/icons/spreadsheet.png)
  91 +}
  92 +
  93 +#dspace_library div.icon-text,
  94 +#dspace_library div.icon-other {
  95 + background-image: url(/plugins/dspace/icons/text.png)
  96 +}
  97 +
  98 +#dspace_library div.icon-video {
  99 + background-image: url(/plugins/dspace/icons/video.png)
  100 +}
  101 +
plugins/dspace/views/cms/dspace_plugin/_collection.html.erb 0 → 100644
@@ -0,0 +1,50 @@ @@ -0,0 +1,50 @@
  1 +<h1><%= _('DSpace Collections') %></h1>
  2 +
  3 +<%= hidden_field_tag 'article[parent_id]', @article.parent_id %>
  4 +
  5 +<%= hidden_field_tag 'article[dspace_community_id]', @article.parent.dspace_community_id %>
  6 +
  7 +<% dspace_server_url = @article.parent.parent.dspace_server_url %>
  8 +
  9 +<% community_id = @article.parent.dspace_community_id %>
  10 +
  11 +<% collections = Dspace::Community.get_all_collections_from( dspace_server_url, community_id ).map { |collection| item = [_(collection.name), collection.id] } %>
  12 +
  13 +<table id="collection_fields_conf" border="0" style="border-bottom: 1px solid #c0c0c0;">
  14 + <tr style="background-color: #f0f0f0; border-top: 1px solid #c0c0c0; border-bottom: 1px solid #c0c0c0;">
  15 + <td style="font-style: italic">
  16 + <%= _("Check/Uncheck All Unlocked")%>
  17 + </td>
  18 + <td align="center">
  19 + <input type="checkbox" id="collection_active" />
  20 + </td>
  21 + </tr>
  22 +
  23 + <% dspace_collections_ids = DspacePlugin::Collection.find(:all, :conditions => { :parent_id => @article.parent_id}).map { |collection| ids = collection.dspace_collection_id.to_i } %>
  24 +
  25 + <% collections.each do |collection| %>
  26 +
  27 + <tr>
  28 + <td>
  29 + <%= collection[0] %>
  30 + </td>
  31 +
  32 + <% if dspace_collections_ids.include? collection[1] %>
  33 + <td align="center">
  34 + <%= check_box_tag "article[dspace_collections][][id]", collection[1], true, :disabled => 'disabled', :id => "collection_id_#{collection[1]}" %>
  35 + <%= hidden_field_tag "article[dspace_collections][][name]", collection[0], :disabled => 'disabled' %>
  36 + </td>
  37 + <% else %>
  38 + <td align="center">
  39 + <%= check_box_tag "article[dspace_collections][][id]", collection[1], false, :id => "collection_id_#{collection[1]}" %>
  40 + <%= hidden_field_tag "article[dspace_collections][][name]", collection[0], :disabled => 'disabled', :id => "collection_name_#{collection[1]}" %>
  41 + </td>
  42 + <% end %>
  43 +
  44 + </tr>
  45 +
  46 + <% end %>
  47 +
  48 +</table>
  49 +
  50 +<%= javascript_include_tag 'plugins/dspace/javascripts/dspace_plugin' %>
plugins/dspace/views/cms/dspace_plugin/_communityy.html.erb 0 → 100644
@@ -0,0 +1,46 @@ @@ -0,0 +1,46 @@
  1 +<h1><%= _('DSpace Communities') %></h1>
  2 +
  3 +<%= hidden_field_tag 'article[parent_id]', @article.parent_id %>
  4 +
  5 +<% dspace_server_url = @article.parent.dspace_server_url %>
  6 +
  7 +<% communities = Dspace::Community.get_all_communities_from(dspace_server_url).map { |community| item = [_(community.name), community.id] } %>
  8 +
  9 +<table id="community_fields_conf" border="0" style="border-bottom: 1px solid #c0c0c0;">
  10 + <tr style="background-color: #f0f0f0; border-top: 1px solid #c0c0c0; border-bottom: 1px solid #c0c0c0;">
  11 + <td style="font-style: italic">
  12 + <%= _("Check/Uncheck All Unlocked")%>
  13 + </td>
  14 + <td align="center">
  15 + <input type="checkbox" id="community_active" />
  16 + </td>
  17 + </tr>
  18 +
  19 + <% dspace_communities_ids = DspacePlugin::Communityy.find(:all, :conditions => { :parent_id => @article.parent_id }).map { |community| ids = community.dspace_community_id.to_i } %>
  20 +
  21 + <% communities.each do |community| %>
  22 +
  23 + <tr>
  24 + <td>
  25 + <%= community[0] %>
  26 + </td>
  27 +
  28 + <% if dspace_communities_ids.include? community[1] %>
  29 + <td align="center">
  30 + <%= check_box_tag "article[dspace_communities][][id]", community[1], true, :disabled => 'disabled', :id => "community_id_#{community[1]}" %>
  31 + <%= hidden_field_tag "article[dspace_communities][][name]", community[0], :disabled => 'disabled' %>
  32 + </td>
  33 + <% else %>
  34 + <td align="center">
  35 + <%= check_box_tag "article[dspace_communities][][id]", community[1], false, :id => "community_id_#{community[1]}" %>
  36 + <%= hidden_field_tag "article[dspace_communities][][name]", community[0], :disabled => 'disabled', :id => "community_name_#{community[1]}" %>
  37 + </td>
  38 + <% end %>
  39 +
  40 + </tr>
  41 +
  42 + <% end %>
  43 +
  44 +</table>
  45 +
  46 +<%= javascript_include_tag 'plugins/dspace/javascripts/dspace_plugin' %>
plugins/dspace/views/cms/dspace_plugin/_library.html.erb 0 → 100644
@@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
  1 +<h1><%= _('My DSpace Library') %></h1>
  2 +
  3 +<%= render :file => 'shared/tiny_mce' %>
  4 +
  5 +<%= required f.text_field(:name, :size => '64', :maxlength => 150, :onchange => "updateUrlField(this, 'article_slug')") %>
  6 +
  7 +<%= required f.text_field(:dspace_server_url, :size => '150', :maxlength => 150) %>
  8 +
  9 +<%= render :partial => 'general_fields' %>
  10 +
  11 +<%= labelled_form_field(_('Description:'), text_area(:article, :body, :cols => 68, :rows => 10)) %>
plugins/dspace/views/content_viewer/_collection.html.erb 0 → 100644
@@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
  1 +<li class="collection">
  2 + <span class="title"><%= link_to collection.name, :controller => 'content_viewer', :action => 'view_page', :page => collection.path %></span>
  3 +</li>
plugins/dspace/views/content_viewer/_community.html.erb 0 → 100644
@@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
  1 +<li class="community">
  2 + <span class="title"><%= link_to community.title, :controller => 'content_viewer', :action => 'view_page', :page => community.path %></span>
  3 +</li>
plugins/dspace/views/content_viewer/_item.html.erb 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +<li class="item">
  2 + <div style="vertical-align: top;">
  3 + <div class="icon-item <%= item.class_for_item_mimetype(item.mimetype) %>"></div>
  4 + <div style="display: inline-block; width: 92%;">
  5 + <span class="name"><%= link_to item.name, :controller => 'dspace_plugin', :action => 'view_item', :id => item.id, :collection_id => @page.id %></span><br />
  6 + <span class="authors"><%= item.author %></span> <span class="date_issued">(<%= item.issue_date %>)</span>
  7 + </div>
  8 + </div>
  9 +</li>
plugins/dspace/views/content_viewer/dspace_content.html.erb 0 → 100644
@@ -0,0 +1,59 @@ @@ -0,0 +1,59 @@
  1 +<div id="dspace_library">
  2 +
  3 + <% if dspace_content.allow_create?(user) %>
  4 +
  5 + <div id="actions">
  6 +
  7 + <% if dspace_content.is_a? DspacePlugin::Library %>
  8 +
  9 + <%= content_tag('a', :href => url_for({:controller => 'cms', :action => 'new', :type => "DspacePlugin::Communityy", :parent_id => dspace_content.id}), :class => 'button with-text icon-add') do %>
  10 + <%= _("Add %s") % DspacePlugin::Communityy.short_description %>
  11 + <% end %>
  12 +
  13 + <% elsif dspace_content.is_a? DspacePlugin::Communityy %>
  14 +
  15 + <%= content_tag('a', :href => url_for({:controller => 'cms', :action => 'new', :type => "DspacePlugin::Collection", :parent_id => dspace_content.id}), :class => 'button with-text icon-add') do %>
  16 + <%= _("Add %s") % DspacePlugin::Collection.short_description %>
  17 + <% end %>
  18 +
  19 + <% end %>
  20 +
  21 + </div>
  22 +
  23 + <% end %>
  24 +
  25 + <% if dspace_content.is_a? DspacePlugin::Library %>
  26 +
  27 + <% communities = dspace_content.communities %>
  28 +
  29 + <ul id="communities_list">
  30 + <%= render :partial => 'community', :collection => communities %>
  31 + </ul>
  32 +
  33 + <% elsif dspace_content.is_a? DspacePlugin::Communityy %>
  34 +
  35 + <% community_id = dspace_content.dspace_community_id %>
  36 + <% dspace_server = dspace_content.parent.dspace_server_url %>
  37 +
  38 + <% collections = dspace_content.collections dspace_server, community_id %>
  39 +
  40 + <ul id="collections_list">
  41 + <%= render :partial => 'collection', :collection => collections %>
  42 + </ul>
  43 +
  44 + <% elsif dspace_content.is_a? DspacePlugin::Collection %>
  45 +
  46 + <% collection_id = dspace_content.dspace_collection_id %>
  47 + <% dspace_server = dspace_content.parent.parent.dspace_server_url %>
  48 +
  49 + <div id="dspace_library">
  50 + <div id="dspace_collection">
  51 + <ul id="items_list">
  52 + <%= render :partial => 'item', :collection => dspace_content.items(dspace_server, collection_id) %>
  53 + </ul>
  54 + </div>
  55 + </div>
  56 +
  57 + <% end %>
  58 +
  59 +</div>
plugins/dspace/views/dspace_plugin/_item_file.html.erb 0 → 100644
@@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
  1 +<li>
  2 + <ul class="item_file_attributes_list">
  3 + <li>
  4 + <span><%= _('File:') %></span> <%= link_to item_file.name, dspace_server_url + item_file.retrieve_link, :target => '_blank' %></li>
  5 + <% unless item_file.description.blank? %>
  6 + <li>
  7 + <span><%= _('Description:') %> </span> <%= item_file.description %></li>
  8 + <% end %>
  9 + <li>
  10 + <span><%= _('Size:') %> </span> <%= number_to_human_size( item_file.size_bytes ) %></li>
  11 + </ul>
  12 +</li>
plugins/dspace/views/dspace_plugin/_item_section.html.erb 0 → 100644
@@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
  1 +<div class="dspace_item_section">
  2 + <div class="dspace_item_section_title">
  3 + <%= item_section[:title] %>
  4 + </div>
  5 + <div class="dspace_item_section_content">
  6 + <%= item_section[:content] %>
  7 + </div>
  8 +</div>
plugins/dspace/views/dspace_plugin/view_item.html.erb 0 → 100644
@@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
  1 +<% extend DspacePlugin::ItemHelper %>
  2 +
  3 +<div id="article-parent">
  4 + <%= button(:back, _('Go back to %s') % @collection.short_title, @collection.url) %>
  5 +</div>
  6 +
  7 +<div id="dspace_library_item">
  8 +
  9 + <div id="dspace_item_title">
  10 + <h1 class="title"><%= @item.name %></h1>
  11 + </div>
  12 +
  13 + <% item_files = render :partial => 'item_file',
  14 + :locals => { :dspace_server_url => remove_slash_at_end_url(@collection.parent.parent.dspace_server_url) },
  15 + :collection => @item.files %>
  16 +
  17 + <% item_files_content = content_tag('ul', item_files, :id => 'item_files_list') %>
  18 +
  19 +
  20 + <%= render :partial => 'item_section',
  21 + :collection => [ { :title => _('Authors:'), :content => @item.author },
  22 + { :title => _('Issue date:'), :content => @item.issue_date },
  23 + { :title => _('Abstract:'), :content => @item.abstract },
  24 + { :title => _('Description:'), :content => @item.description },
  25 + { :title => _('URI:'), :content => link_to(@item.uri, @item.uri, :target => '_blank') },
  26 + { :title => _('Files in this item'), :content => item_files_content } ] %>
  27 +
  28 +</div>
plugins/proposals_discussion/controllers/public/proposals_discussion_plugin_public_controller.rb
@@ -20,6 +20,12 @@ class ProposalsDiscussionPluginPublicController &lt; ApplicationController @@ -20,6 +20,12 @@ class ProposalsDiscussionPluginPublicController &lt; ApplicationController
20 case order 20 case order
21 when 'alphabetical' 21 when 'alphabetical'
22 proposals.reorder('name') 22 proposals.reorder('name')
  23 + when 'recent'
  24 + proposals.reorder('created_at DESC')
  25 + when 'most_commented'
  26 + proposals.reorder('comments_count DESC')
  27 + when 'most_recently_commented'
  28 + proposals.joins("LEFT OUTER JOIN comments ON comments.source_id=articles.id AND comments.created_at >= '#{5.days.ago}'").group('articles.id').reorder('count(comments.id) DESC')
23 else 29 else
24 set_seed 30 set_seed
25 proposals.reorder('random()') 31 proposals.reorder('random()')
plugins/proposals_discussion/lib/proposals_discussion_plugin/discussion.rb
1 class ProposalsDiscussionPlugin::Discussion < Folder 1 class ProposalsDiscussionPlugin::Discussion < Folder
2 2
  3 + acts_as_having_posts
  4 +
3 has_many :topics, :class_name => 'ProposalsDiscussionPlugin::Topic', :foreign_key => 'parent_id' 5 has_many :topics, :class_name => 'ProposalsDiscussionPlugin::Topic', :foreign_key => 'parent_id'
4 has_many :proposals, :class_name => 'ProposalsDiscussionPlugin::Proposal', :through => :children, :source => :children 6 has_many :proposals, :class_name => 'ProposalsDiscussionPlugin::Proposal', :through => :children, :source => :children
5 7
@@ -26,4 +28,9 @@ class ProposalsDiscussionPlugin::Discussion &lt; Folder @@ -26,4 +28,9 @@ class ProposalsDiscussionPlugin::Discussion &lt; Folder
26 end 28 end
27 alias_method_chain :cache_key, :person 29 alias_method_chain :cache_key, :person
28 30
  31 + def posts
  32 + #override posts method to list proposals in feed
  33 + ProposalsDiscussionPlugin::Proposal.from_discussion(self)
  34 + end
  35 +
29 end 36 end
plugins/proposals_discussion/lib/proposals_discussion_plugin/proposal.rb
1 class ProposalsDiscussionPlugin::Proposal < TinyMceArticle 1 class ProposalsDiscussionPlugin::Proposal < TinyMceArticle
2 2
3 scope :private, lambda {|user| {:conditions => {:last_changed_by_id => user.id, :published => false}}} 3 scope :private, lambda {|user| {:conditions => {:last_changed_by_id => user.id, :published => false}}}
  4 + scope :from_discussion, lambda {|discussion| joins(:parent).where(['parents_articles.parent_id = ?', discussion.id])}
4 5
5 alias :topic :parent 6 alias :topic :parent
6 7
@@ -16,8 +17,12 @@ class ProposalsDiscussionPlugin::Proposal &lt; TinyMceArticle @@ -16,8 +17,12 @@ class ProposalsDiscussionPlugin::Proposal &lt; TinyMceArticle
16 17
17 18
18 def to_html(options = {}) 19 def to_html(options = {})
19 - proc do  
20 - render :file => 'content_viewer/proposal' 20 + unless options[:feed]
  21 + proc do
  22 + render :file => 'content_viewer/proposal'
  23 + end
  24 + else
  25 + body
21 end 26 end
22 end 27 end
23 28
@@ -38,4 +43,8 @@ class ProposalsDiscussionPlugin::Proposal &lt; TinyMceArticle @@ -38,4 +43,8 @@ class ProposalsDiscussionPlugin::Proposal &lt; TinyMceArticle
38 end 43 end
39 alias_method_chain :cache_key, :person 44 alias_method_chain :cache_key, :person
40 45
  46 + def can_display_versions?
  47 + false
  48 + end
  49 +
41 end 50 end
plugins/proposals_discussion/lib/proposals_discussion_plugin/proposal_helper.rb
@@ -1,8 +0,0 @@ @@ -1,8 +0,0 @@
1 -module ProposalsDiscussionPlugin::ProposalHelper  
2 -  
3 - def visibility_options(article, tokenized_children)  
4 - article.published = false if article.new_record?  
5 - super  
6 - end  
7 -  
8 -end  
plugins/proposals_discussion/lib/proposals_discussion_plugin/proposals_list_helper.rb
1 module ProposalsDiscussionPlugin::ProposalsListHelper 1 module ProposalsDiscussionPlugin::ProposalsListHelper
2 2
  3 + def sort_criteria
  4 + [[_('Random'), :random], [_('Alphabetical'), :alphabetical], [_('Recent'), :recent], [_('Most Commented'), :most_commented], [_('Most Recently Commented'), :most_recently_commented]]
  5 + end
  6 +
3 def more_proposals(text, holder, order, page=1) 7 def more_proposals(text, holder, order, page=1)
4 link_to text, url_for({:controller => 'proposals_discussion_plugin_public', :action => 'load_proposals', :holder_id => holder.id, :profile => profile.identifier, :order => order, :page => page }) 8 link_to text, url_for({:controller => 'proposals_discussion_plugin_public', :action => 'load_proposals', :holder_id => holder.id, :profile => profile.identifier, :order => order, :page => page })
5 end 9 end
plugins/proposals_discussion/lib/proposals_discussion_plugin/topic.rb
@@ -44,11 +44,21 @@ class ProposalsDiscussionPlugin::Topic &lt; Folder @@ -44,11 +44,21 @@ class ProposalsDiscussionPlugin::Topic &lt; Folder
44 end 44 end
45 45
46 def proposals_per_day 46 def proposals_per_day
47 - proposals.group("date(created_at)").count 47 + result = proposals.group("date(created_at)").count
  48 + fill_empty_days(result)
48 end 49 end
49 50
50 def comments_per_day 51 def comments_per_day
51 - proposals.joins(:comments).group('date(comments.created_at)').count('comments.id') 52 + result = proposals.joins(:comments).group('date(comments.created_at)').count('comments.id')
  53 + fill_empty_days(result)
  54 + end
  55 +
  56 + def fill_empty_days(result)
  57 + from = created_at.to_date
  58 + (from..Date.today).inject({}) do |h, date|
  59 + h[date.to_s] = result[date.to_s] || 0
  60 + h
  61 + end
52 end 62 end
53 63
54 def cache_key_with_person(params = {}, user = nil, language = 'en') 64 def cache_key_with_person(params = {}, user = nil, language = 'en')
plugins/proposals_discussion/lib/proposals_discussion_plugin/topic_helper.rb 0 → 100644
@@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
  1 +module ProposalsDiscussionPlugin::TopicHelper
  2 +
  3 + def topic_title(topic)
  4 + image_icon = topic.image ? image_tag(topic.image.public_filename(:thumb), :class => 'disable-zoom') : ''
  5 +
  6 + content_tag(:div, (
  7 + content_tag(:div, '', :class=>'topic-color', :style => "background-color: #{topic.color};") +
  8 + content_tag(:h2, link_to(image_icon + content_tag(:span, topic.title), topic.view_url))
  9 + ), :class => 'topic-title')
  10 + end
  11 +
  12 +end
plugins/proposals_discussion/public/proposals_graph.js~
@@ -1,53 +0,0 @@ @@ -1,53 +0,0 @@
1 -(function basic_time(container) {  
2 -  
3 - var  
4 - d1 = [],  
5 - start = new Date("2009/01/01 01:00").getTime(),  
6 - options,  
7 - graph,  
8 - i, x, o;  
9 -  
10 - for (i = 0; i < 100; i++) {  
11 - x = start+(i*1000*3600*24*36.5);  
12 - d1.push([x, i+Math.random()*30+Math.sin(i/20+Math.random()*2)*20+Math.sin(i/10+Math.random())*10]);  
13 - }  
14 -  
15 - options = {  
16 - xaxis : {  
17 - mode : 'time',  
18 - labelsAngle : 45  
19 - },  
20 - selection : {  
21 - mode : 'x'  
22 - },  
23 - HtmlText : false,  
24 - title : 'Time'  
25 - };  
26 -  
27 - // Draw graph with default options, overwriting with passed options  
28 - function drawGraph (opts) {  
29 -  
30 - // Clone the options, so the 'options' variable always keeps intact.  
31 - o = Flotr._.extend(Flotr._.clone(options), opts || {});  
32 -  
33 - // Return a new graph.  
34 - return Flotr.draw(  
35 - container,  
36 - [ d1 ],  
37 - o  
38 - );  
39 - }  
40 -  
41 - graph = drawGraph();  
42 -  
43 - Flotr.EventAdapter.observe(container, 'flotr:select', function(area){  
44 - // Draw selected area  
45 - graph = drawGraph({  
46 - xaxis : { min : area.x1, max : area.x2, mode : 'time', labelsAngle : 45 },  
47 - yaxis : { min : area.y1, max : area.y2 }  
48 - });  
49 - });  
50 -  
51 - // When graph is clicked, draw the graph with default area.  
52 - Flotr.EventAdapter.observe(container, 'flotr:click', function () { graph = drawGraph(); });  
53 -})(document.getElementById("editor-render-0"));  
plugins/proposals_discussion/public/proposals_list.js
@@ -10,9 +10,9 @@ jQuery(document).ready(function($) { @@ -10,9 +10,9 @@ jQuery(document).ready(function($) {
10 }); 10 });
11 11
12 function proposalsScroll() { 12 function proposalsScroll() {
13 - var scroll = $('.article-body-proposals-discussion-plugin_topic .topic-content .proposals_list'); 13 + var scroll = $('.article-body-proposals-discussion-plugin_topic .topic-content .proposals_list .proposals');
14 var nextSelector = 'div.more a'; 14 var nextSelector = 'div.more a';
15 - if(scroll.data('jscroll')) scroll.jscroll.destroy(); 15 + if(scroll.data('jscroll')) scroll.data('jscroll', null);
16 16
17 if(scroll.find(nextSelector).length > 0) { 17 if(scroll.find(nextSelector).length > 0) {
18 scroll.jscroll({ 18 scroll.jscroll({
@@ -31,6 +31,12 @@ jQuery(document).ready(function($) { @@ -31,6 +31,12 @@ jQuery(document).ready(function($) {
31 $('.topics').masonry(); 31 $('.topics').masonry();
32 }); 32 });
33 $('.topics').masonry(); 33 $('.topics').masonry();
  34 + $(window).resize(function() {
  35 + $('.topics').masonry();
  36 + });
  37 + $(window).bind('toggleFullwidth', function() {
  38 + $('.topics').masonry();
  39 + });
34 }); 40 });
35 41
36 function loadSocialButtons() { 42 function loadSocialButtons() {
plugins/proposals_discussion/public/style.css
@@ -156,11 +156,14 @@ form .proposals-discussion-plugin .body textarea { @@ -156,11 +156,14 @@ form .proposals-discussion-plugin .body textarea {
156 #content .topic-item h2 a, #article .article-body-proposals-discussion-plugin_topic h2 a, 156 #content .topic-item h2 a, #article .article-body-proposals-discussion-plugin_topic h2 a,
157 #content .topic h2 a { 157 #content .topic h2 a {
158 text-decoration: none; 158 text-decoration: none;
159 - padding: 10px;  
160 display: inline-block; 159 display: inline-block;
161 width: 94%; 160 width: 94%;
162 color: white; 161 color: white;
163 } 162 }
  163 +#content .topic-title h2 span {
  164 + padding: 10px;
  165 + display: inline-block;
  166 +}
164 .topic-item .topic-content, #article .article-body-proposals-discussion-plugin_topic .topic-content { 167 .topic-item .topic-content, #article .article-body-proposals-discussion-plugin_topic .topic-content {
165 padding: 5px 7px 5px 2px; 168 padding: 5px 7px 5px 2px;
166 } 169 }
@@ -177,7 +180,7 @@ form .proposals-discussion-plugin .body textarea { @@ -177,7 +180,7 @@ form .proposals-discussion-plugin .body textarea {
177 margin: 1px 0 0 0; 180 margin: 1px 0 0 0;
178 } 181 }
179 182
180 -#content .tag_cloud a { 183 +#content .article-body-proposals-discussion-plugin_topic .tag_cloud a {
181 text-decoration: none; 184 text-decoration: none;
182 } 185 }
183 186
@@ -199,7 +202,7 @@ form .proposals-discussion-plugin .body textarea { @@ -199,7 +202,7 @@ form .proposals-discussion-plugin .body textarea {
199 #content .statistics h5 { 202 #content .statistics h5 {
200 color: rgb(95, 95, 95); 203 color: rgb(95, 95, 95);
201 } 204 }
202 -#content .tag_cloud { 205 +#content .article-body-proposals-discussion-plugin_topic .tag_cloud {
203 float: right; 206 float: right;
204 width: 300px; 207 width: 300px;
205 box-shadow: 5px 5px 5px -2px #ddd; 208 box-shadow: 5px 5px 5px -2px #ddd;
@@ -219,3 +222,13 @@ form .proposals-discussion-plugin .body textarea { @@ -219,3 +222,13 @@ form .proposals-discussion-plugin .body textarea {
219 clear: both; 222 clear: both;
220 padding-top: 10px; 223 padding-top: 10px;
221 } 224 }
  225 +
  226 +.proposal .actions .fb-share-button {
  227 + top: -3px;
  228 +}
  229 +
  230 +.topic-title h2 img {
  231 + max-height: 36px;
  232 + vertical-align: middle;
  233 + padding: 4px 0 4px 4px;
  234 +}
plugins/proposals_discussion/test/functional/proposals_discussion_plugin_public_controller_test.rb
@@ -35,4 +35,48 @@ class ProposalsDiscussionPluginPublicControllerTest &lt; ActionController::TestCase @@ -35,4 +35,48 @@ class ProposalsDiscussionPluginPublicControllerTest &lt; ActionController::TestCase
35 assert_equal [proposal2, proposal3, proposal1], assigns(:proposals) 35 assert_equal [proposal2, proposal3, proposal1], assigns(:proposals)
36 end 36 end
37 37
  38 + should 'load proposals with most commented order' do
  39 + proposal1 = fast_create(ProposalsDiscussionPlugin::Proposal, :name => 'proposal1', :abstract => 'proposal abstract', :profile_id => profile.id, :parent_id => topic.id)
  40 + proposal2 = fast_create(ProposalsDiscussionPlugin::Proposal, :name => 'proposal2', :abstract => 'proposal abstract', :profile_id => profile.id, :parent_id => topic.id)
  41 + proposal3 = fast_create(ProposalsDiscussionPlugin::Proposal, :name => 'proposal3', :abstract => 'proposal abstract', :profile_id => profile.id, :parent_id => topic.id)
  42 +
  43 + author = fast_create(Person)
  44 + Comment.create!(:source => proposal2, :body => 'text', :author => author)
  45 + Comment.create!(:source => proposal2, :body => 'text', :author => author)
  46 + Comment.create!(:source => proposal3, :body => 'text', :author => author)
  47 +
  48 + get :load_proposals, :profile => profile.identifier, :holder_id => topic.id, :order => 'most_commented'
  49 + assert_equal [proposal2, proposal3, proposal1], assigns(:proposals)
  50 + end
  51 +
  52 + should 'load proposals with most recent order' do
  53 + proposal1 = fast_create(ProposalsDiscussionPlugin::Proposal, :name => 'z', :abstract => 'proposal abstract', :profile_id => profile.id, :parent_id => topic.id)
  54 + proposal2 = fast_create(ProposalsDiscussionPlugin::Proposal, :name => 'b', :abstract => 'proposal abstract', :profile_id => profile.id, :parent_id => topic.id)
  55 + proposal3 = fast_create(ProposalsDiscussionPlugin::Proposal, :name => 'k', :abstract => 'proposal abstract', :profile_id => profile.id, :parent_id => topic.id)
  56 +
  57 + author = fast_create(Person)
  58 + Comment.create!(:source => proposal2, :body => 'text', :author => author)
  59 + Comment.create!(:source => proposal2, :body => 'text', :author => author)
  60 + Comment.create!(:source => proposal3, :body => 'text', :author => author)
  61 +
  62 + get :load_proposals, :profile => profile.identifier, :holder_id => topic.id, :order => 'recent'
  63 + assert_equal [proposal3, proposal2, proposal1], assigns(:proposals)
  64 + end
  65 +
  66 + should 'load proposals with most recently commented order' do
  67 + proposal1 = fast_create(ProposalsDiscussionPlugin::Proposal, :name => 'proposal1', :abstract => 'proposal abstract', :profile_id => profile.id, :parent_id => topic.id)
  68 + proposal2 = fast_create(ProposalsDiscussionPlugin::Proposal, :name => 'proposal2', :abstract => 'proposal abstract', :profile_id => profile.id, :parent_id => topic.id)
  69 + proposal3 = fast_create(ProposalsDiscussionPlugin::Proposal, :name => 'proposal3', :abstract => 'proposal abstract', :profile_id => profile.id, :parent_id => topic.id)
  70 +
  71 + author = fast_create(Person)
  72 + Comment.create!({:source => proposal2, :body => 'text', :author => author, :created_at => 10.days.ago}, :without_protection => true)
  73 + Comment.create!({:source => proposal2, :body => 'text', :author => author, :created_at => 10.days.ago}, :without_protection => true)
  74 + Comment.create!(:source => proposal3, :body => 'text', :author => author)
  75 + Comment.create!(:source => proposal3, :body => 'text', :author => author)
  76 + Comment.create!(:source => proposal1, :body => 'text', :author => author)
  77 +
  78 + get :load_proposals, :profile => profile.identifier, :holder_id => topic.id, :order => 'most_recently_commented'
  79 + assert_equal [proposal3, proposal1, proposal2], assigns(:proposals)
  80 + end
  81 +
38 end 82 end
plugins/proposals_discussion/test/unit/proposal_test.rb
@@ -29,4 +29,26 @@ class ProposalTest &lt; ActiveSupport::TestCase @@ -29,4 +29,26 @@ class ProposalTest &lt; ActiveSupport::TestCase
29 assert !proposal.allow_edit?(fast_create(Person)) 29 assert !proposal.allow_edit?(fast_create(Person))
30 end 30 end
31 31
  32 + should 'return body when to_html was called with feed=true' do
  33 + assert_equal proposal.body, proposal.to_html(:feed => true)
  34 + end
  35 +
  36 + should 'return a proc when to_html was called with feed=false' do
  37 + assert proposal.to_html(:feed => false).kind_of?(Proc)
  38 + end
  39 +
  40 + should 'return a proc when to_html was called with no feed parameter' do
  41 + assert proposal.to_html.kind_of?(Proc)
  42 + end
  43 +
  44 + should 'return proposals by discussion' do
  45 + discussion = fast_create(ProposalsDiscussionPlugin::Discussion)
  46 + topic = fast_create(ProposalsDiscussionPlugin::Topic, :parent_id => discussion.id)
  47 + proposal1 = fast_create(ProposalsDiscussionPlugin::Proposal, :parent_id => topic.id)
  48 + proposal2 = fast_create(ProposalsDiscussionPlugin::Proposal)
  49 + proposal3 = fast_create(ProposalsDiscussionPlugin::Proposal, :parent_id => topic.id)
  50 +
  51 + assert_equivalent [proposal1, proposal3], ProposalsDiscussionPlugin::Proposal.from_discussion(discussion)
  52 + end
  53 +
32 end 54 end
plugins/proposals_discussion/views/cms/proposals_discussion_plugin/_proposal.html.erb
@@ -5,7 +5,14 @@ @@ -5,7 +5,14 @@
5 <% title_limit = 70 %> 5 <% title_limit = 70 %>
6 <% abstract_limit = 140 %> 6 <% abstract_limit = 140 %>
7 7
  8 +<% extend ProposalsDiscussionPlugin::TopicHelper %>
  9 +
8 <div class="proposals-discussion-plugin"> 10 <div class="proposals-discussion-plugin">
  11 +
  12 + <div class="topic">
  13 + <%= topic_title @article.topic %>
  14 + </div>
  15 +
9 <div class="title"> 16 <div class="title">
10 <%= required labelled_form_field _('Title'), limited_text_area(:article, :name, title_limit, 'title_textarea', :rows => 1) %> 17 <%= required labelled_form_field _('Title'), limited_text_area(:article, :name, title_limit, 'title_textarea', :rows => 1) %>
11 </div> 18 </div>
plugins/proposals_discussion/views/cms/proposals_discussion_plugin/_topic.html.erb
@@ -11,3 +11,8 @@ @@ -11,3 +11,8 @@
11 11
12 <%= labelled_colorpicker_field(_('Color:'), :article, :color) %> 12 <%= labelled_colorpicker_field(_('Color:'), :article, :color) %>
13 <span id="color_preview" class = "color_marker" style="background-color: <%= @article.color %>" ></span> 13 <span id="color_preview" class = "color_marker" style="background-color: <%= @article.color %>" ></span>
  14 +
  15 +<%= f.fields_for :image_builder, @article.image do |i| %>
  16 + <%= file_field_or_thumbnail(_('Image:'), @article.image, i)%>
  17 + <%= _("Max size: %s (.jpg, .gif, .png)")% Image.max_size.to_humanreadable %>
  18 +<% end %>
plugins/proposals_discussion/views/content_viewer/_proposals_list.html.erb
@@ -12,7 +12,7 @@ @@ -12,7 +12,7 @@
12 <% order ||= 'random' %> 12 <% order ||= 'random' %>
13 <div class="proposals_list"> 13 <div class="proposals_list">
14 <div class="filters"> 14 <div class="filters">
15 - <% [[_('Random'), :random], [_('Aplhabetical'), :alphabetical]].each_with_index do |order, i| %> 15 + <% sort_criteria.each_with_index do |order, i| %>
16 <%= link_to order.first, url_for({:controller => 'proposals_discussion_plugin_public', :action => 'load_proposals', :holder_id => holder.id, :profile => profile.identifier, :order => order.second}), :remote => true, :class => "order #{order.second} #{i==0 ? 'selected':''}" %> 16 <%= link_to order.first, url_for({:controller => 'proposals_discussion_plugin_public', :action => 'load_proposals', :holder_id => holder.id, :profile => profile.identifier, :order => order.second}), :remote => true, :class => "order #{order.second} #{i==0 ? 'selected':''}" %>
17 <% end %> 17 <% end %>
18 </div> 18 </div>
plugins/proposals_discussion/views/content_viewer/_social.html.erb
1 <a href="https://twitter.com/share" class="twitter-share-button" data-url="<%= url_for proposal.view_url %>" data-text="<%= proposal.title %>" data-count="none"></a> 1 <a href="https://twitter.com/share" class="twitter-share-button" data-url="<%= url_for proposal.view_url %>" data-text="<%= proposal.title %>" data-count="none"></a>
2 2
3 -<div class="fb-share-button" data-href="<%= url_for proposal.view_url %>" data-layout="box-count"></div> 3 +<div class="fb-share-button" data-href="<%= url_for proposal.view_url %>"></div>
plugins/proposals_discussion/views/content_viewer/discussion.html.erb
1 <%= javascript_include_tag 'plugins/proposals_discussion/proposals_list.js' %> 1 <%= javascript_include_tag 'plugins/proposals_discussion/proposals_list.js' %>
2 2
  3 +<%= add_rss_feed_to_head(@page.name, @page.feed.url) if @page.feed %>
  4 +
3 <div class="description"> 5 <div class="description">
4 <%= @page.body %> 6 <%= @page.body %>
5 </div> 7 </div>
plugins/proposals_discussion/views/content_viewer/proposal.html.erb
@@ -2,9 +2,10 @@ @@ -2,9 +2,10 @@
2 <h5><%= @page.topic.discussion.title %> </h5> 2 <h5><%= @page.topic.discussion.title %> </h5>
3 </div> 3 </div>
4 4
  5 +<% extend ProposalsDiscussionPlugin::TopicHelper %>
  6 +
5 <div class="topic"> 7 <div class="topic">
6 - <div class="topic-color" style="background-color: <%= @page.topic.color %>;"></div>  
7 - <h2><%= link_to @page.topic.title, @page.topic.view_url %></h2> 8 + <%= topic_title @page.topic %>
8 </div> 9 </div>
9 10
10 <div class="title"> 11 <div class="title">
plugins/proposals_discussion/views/content_viewer/topic.html.erb
@@ -4,8 +4,8 @@ @@ -4,8 +4,8 @@
4 <%= javascript_include_tag 'plugins/proposals_discussion/proposals_list.js' %> 4 <%= javascript_include_tag 'plugins/proposals_discussion/proposals_list.js' %>
5 <% end %> 5 <% end %>
6 6
7 -<div class="topic-color" style="background-color: <%= topic.color %>;"></div>  
8 -<h2><%= link_to topic.title, topic.view_url %></h2> 7 +<% extend ProposalsDiscussionPlugin::TopicHelper %>
  8 +<%= topic_title topic %>
9 9
10 <div class="topic-content"> 10 <div class="topic-content">
11 11
plugins/proposals_discussion/views/select_topic.html.erb
@@ -16,7 +16,7 @@ @@ -16,7 +16,7 @@
16 <h3><%= _('Select topic') %></h3> 16 <h3><%= _('Select topic') %></h3>
17 <div id="topics"> 17 <div id="topics">
18 18
19 - <% @discussion.children.each do |topic| %> 19 + <% @discussion.topics.each do |topic| %>
20 <h4> 20 <h4>
21 <%= radio_button_tag('discussion[topic]', topic.id) %> 21 <%= radio_button_tag('discussion[topic]', topic.id) %>
22 <%= topic.title %> 22 <%= topic.title %>
public/javascripts/application.js
@@ -1037,7 +1037,7 @@ jQuery(document).ready(function(){ @@ -1037,7 +1037,7 @@ jQuery(document).ready(function(){
1037 function apply_zoom_to_images(zoom_text) { 1037 function apply_zoom_to_images(zoom_text) {
1038 jQuery(function($) { 1038 jQuery(function($) {
1039 $(window).load( function() { 1039 $(window).load( function() {
1040 - $('#article .article-body img').each( function(index) { 1040 + $('#article .article-body img:not(.disable-zoom)').each( function(index) {
1041 var original = original_image_dimensions($(this).attr('src')); 1041 var original = original_image_dimensions($(this).attr('src'));
1042 if ($(this).width() < original['width'] || $(this).height() < original['height']) { 1042 if ($(this).width() < original['width'] || $(this).height() < original['height']) {
1043 $(this).wrap('<div class="zoomable-image" />'); 1043 $(this).wrap('<div class="zoomable-image" />');
@@ -1083,6 +1083,7 @@ function toggle_fullwidth(itemId){ @@ -1083,6 +1083,7 @@ function toggle_fullwidth(itemId){
1083 jQuery("#fullscreen-btn").hide() 1083 jQuery("#fullscreen-btn").hide()
1084 fullwidth = true; 1084 fullwidth = true;
1085 } 1085 }
  1086 + jQuery(window).trigger("toggleFullwidth", fullwidth);
1086 } 1087 }
1087 1088
1088 function fullscreenPageLoad(itemId){ 1089 function fullscreenPageLoad(itemId){