Commit 7b8dee326412c7c8efde796e1f7144aa431fbd4f

Authored by Francisco Marcelo de Araújo Lima Júnior
2 parents 4b06d2fb 988f4a83

Merge branch 'AI3074-community_dashboard' into rails3_community_dashboard

Showing 53 changed files with 2241 additions and 2 deletions   Show diff stats
app/controllers/public/content_viewer_controller.rb
... ... @@ -127,9 +127,9 @@ class ContentViewerController < ApplicationController
127 127  
128 128 if params[:slideshow]
129 129 render :action => 'slideshow', :layout => 'slideshow'
130   - return
  130 + else
  131 + render :file => @page.view_page, :layout => true
131 132 end
132   - render :view_page, :formats => [:html]
133 133 end
134 134  
135 135 def versions_diff
... ...
app/models/article.rb
... ... @@ -745,6 +745,10 @@ class Article < ActiveRecord::Base
745 745 true
746 746 end
747 747  
  748 + def view_page
  749 + "content_viewer/view_page.rhtml"
  750 + end
  751 +
748 752 private
749 753  
750 754 def sanitize_tag_list
... ...
app/models/comment.rb
... ... @@ -32,6 +32,8 @@ class Comment < ActiveRecord::Base
32 32 rec.errors.add(:name, _('{fn} can only be informed for unauthenticated authors').fix_i18n)
33 33 end
34 34 end
  35 +
  36 + acts_as_having_settings :field => :setting
35 37  
36 38 xss_terminate :only => [ :body, :title, :name ], :on => 'validation'
37 39  
... ...
db/migrate/20140505190748_add_setting_to_comments.rb 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +class AddSettingToComments < ActiveRecord::Migration
  2 + def self.up
  3 + add_column :comments, :setting, :text
  4 + end
  5 +
  6 + def self.down
  7 + remove_column :comments, :setting
  8 + end
  9 +end
... ...
plugins/community_hub/controllers/myprofile/community_dashboard_plugin_myprofile_controller.rb 0 → 100644
... ... @@ -0,0 +1,18 @@
  1 +class CommunityDashboardPluginMyprofileController < MyProfileController
  2 +
  3 + append_view_path File.join(File.dirname(__FILE__) + '/../../views')
  4 +
  5 + before_filter :allow_edit_dashboard, :only => :save_order
  6 +
  7 + def save_order
  8 + dashboard = profile.articles.find(params[:dashboard])
  9 + redirect_to dashboard.url
  10 + end
  11 +
  12 + protected
  13 +
  14 + def allow_edit_dashboard
  15 + render_access_denied unless profile.articles.find(params[:dashboard]).allow_edit?(user)
  16 + end
  17 +
  18 +end
... ...
plugins/community_hub/controllers/public/community_hub_plugin_public_controller.rb 0 → 100644
... ... @@ -0,0 +1,219 @@
  1 +class CommunityHubPluginPublicController < PublicController
  2 +
  3 + append_view_path File.join(File.dirname(__FILE__) + '/../../views')
  4 +
  5 + layout false
  6 +
  7 +
  8 + def new_message
  9 + if logged_in?
  10 +
  11 + begin
  12 + hub = Article.find(params[:article_id])
  13 + rescue
  14 + hub = nil
  15 + end
  16 +
  17 + if hub
  18 + message_data = {}
  19 + message_data.merge!(params[:message]) if params[:message]
  20 +
  21 + message = Comment.new(message_data)
  22 + message.author = user
  23 + message.title = message_timestamp
  24 + message.article = hub
  25 + message.ip_address = request.remote_ip
  26 + message.user_agent = request.user_agent
  27 + message.referrer = request.referrer
  28 +
  29 + if message && message.save
  30 + render :text => {'ok' => true}.to_json, :content_type => 'application/json'
  31 + return true
  32 + end
  33 + end
  34 +
  35 + end
  36 + render :text => {'ok' => false}.to_json, :content_type => 'application/json'
  37 + end
  38 +
  39 +
  40 + def new_mediation
  41 + if logged_in?
  42 +
  43 + begin
  44 + profile = Profile.find(params[:profile_id])
  45 + rescue
  46 + profile = nil
  47 + end
  48 +
  49 + if profile
  50 + mediation_data = {}
  51 + mediation_data.merge!(params[:article]) if params[:article]
  52 +
  53 + mediation = CommunityHubPlugin::Mediation.new(mediation_data)
  54 + mediation.name = CommunityHubPlugin::Mediation.timestamp
  55 + mediation.profile = profile
  56 + mediation.last_changed_by = user
  57 + mediation.created_by_id = user.id
  58 + mediation.source = 'local'
  59 +
  60 + if mediation && mediation.save
  61 + render :text => {'ok' => true}.to_json, :content_type => 'application/json'
  62 + return true
  63 + end
  64 + end
  65 +
  66 + end
  67 + render :text => {'ok' => false}.to_json, :content_type => 'application/json'
  68 + end
  69 +
  70 +
  71 + def newer_mediation_comment
  72 + latest_id = params[:latest_post]
  73 + mediation = params[:mediation]
  74 + comments = Comment.find(:all, :conditions => ["id > :id and source_id = :mediation", { :id => latest_id, :mediation => mediation }])
  75 + render :partial => "mediation_comment", :collection => comments
  76 + end
  77 +
  78 +
  79 + def newer_comments
  80 + latest_post = params[:latest_post]
  81 + hub = Article.find(params[:hub])
  82 + posts = Comment.find(:all, :order => "id desc", :conditions => ["id > :id and source_id = :hub", { :id => latest_post, :hub => hub }], :limit => 30)
  83 +
  84 + if !posts.empty?
  85 + oldest_post = posts.last.id
  86 + latest_post = posts.first.id
  87 + size = posts.size
  88 + else
  89 + oldest_post = 0
  90 + latest_post = 0
  91 + end
  92 +
  93 + render :partial => "post", :collection => posts, :locals => { :latest_id => latest_post, :oldest_id => oldest_post, :hub => hub }
  94 + end
  95 +
  96 +
  97 + def older_comments
  98 + oldest_id = params[:oldest_id]
  99 + hub = Article.find(params[:hub])
  100 + posts = Comment.find(:all, :order => "id desc", :conditions => ["id < :id and source_id = :hub", { :id => oldest_id, :hub => hub }], :limit => 30)
  101 +
  102 + if !posts.empty?
  103 + oldest_id = posts.last.id
  104 + latest_id = posts.first.id
  105 + end
  106 +
  107 + render :partial => "post", :collection => posts, :locals => { :latest_id => latest_id, :oldest_id => oldest_id, :hub => hub }
  108 + end
  109 +
  110 +
  111 + def newer_articles
  112 + latest_post = params[:latest_post]
  113 + hub = Article.find(params[:hub])
  114 + posts = CommunityHubPlugin::Mediation.find(:all, :order => "id desc", :conditions => ["id > :id and parent_id = :hub", { :id => latest_post, :hub => hub.id }])
  115 +
  116 + if !posts.empty?
  117 + oldest_post = posts.last.id
  118 + latest_post = posts.first.id
  119 + else
  120 + oldest_post = 0
  121 + latest_post = 0
  122 + end
  123 +
  124 + render :partial => "mediation", :collection => posts, :locals => { :latest_post => latest_post, :oldest_post => oldest_post, :hub => hub }
  125 + end
  126 +
  127 +
  128 + def promote_user
  129 + if logged_in?
  130 + if (!params[:hub].blank? && !params[:user].blank?)
  131 + begin
  132 + hub = Article.find(params[:hub])
  133 + rescue
  134 + hub = nil
  135 + end
  136 + if hub && hub.mediator?(user)
  137 + begin
  138 + user_to_promote = Profile.find(params[:user])
  139 + rescue
  140 + user_to_promote = nil
  141 + end
  142 + if user_to_promote
  143 + hub.mediators += [user_to_promote.id] unless hub.mediators.include?(user_to_promote.id)
  144 + if hub.save
  145 + render :text => {'ok' => true}.to_json, :content_type => 'application/json'
  146 + return true
  147 + end
  148 + end
  149 + end
  150 + end
  151 + end
  152 + render :text => {'ok' => false}.to_json, :content_type => 'application/json'
  153 + end
  154 +
  155 +
  156 + def pin_message
  157 + if logged_in?
  158 + if (!params[:hub].blank? && !params[:message].blank?)
  159 +
  160 + begin
  161 + hub = Article.find(params[:hub])
  162 + rescue
  163 + hub = nil
  164 + end
  165 +
  166 + if hub && hub.mediator?(user)
  167 + begin
  168 + message = Comment.find(params[:message])
  169 + rescue
  170 + message = nil
  171 + end
  172 +
  173 + if message
  174 + author = message.author.blank? ? user : message.author
  175 +
  176 + mediation = CommunityHubPlugin::Mediation.new
  177 + mediation.name = CommunityHubPlugin::Mediation.timestamp
  178 +
  179 + mediation.profile = hub.profile
  180 + mediation.last_changed_by = author
  181 + mediation.created_by_id = author.id
  182 + mediation.body = message.body
  183 + mediation.parent_id = hub.id
  184 + mediation.source = 'local'
  185 +
  186 + if mediation && mediation.save
  187 +
  188 + if ( message.title == 'hub-message-twitter' )
  189 + mediation.source = 'twitter'
  190 + mediation.author_name = message.name
  191 + mediation.profile_picture = message.profile_picture
  192 + mediation.save
  193 + end
  194 +
  195 + hub.pinned_messages += [message.id] unless hub.pinned_messages.include?(message.id)
  196 + hub.pinned_mediations += [mediation.id] unless hub.pinned_mediations.include?(mediation.id)
  197 +
  198 + if hub && hub.save
  199 + render :text => {'ok' => true}.to_json, :content_type => 'application/json'
  200 + return true
  201 + end
  202 +
  203 + end
  204 +
  205 + end
  206 + end
  207 + end
  208 + end
  209 + render :text => {'ok' => false}.to_json, :content_type => 'application/json'
  210 + end
  211 +
  212 +
  213 + protected
  214 +
  215 + def message_timestamp
  216 + "hub-message-#{(Time.now.to_f * 1000).to_i}"
  217 + end
  218 +
  219 +end
... ...
plugins/community_hub/facebook_stream/facebook_stream.rb 0 → 100755
... ... @@ -0,0 +1,55 @@
  1 +require 'rubygems'
  2 +require 'koala'
  3 +require 'json'
  4 +
  5 +#Aviso 12/04/2014
  6 +#token que só deverá expirar em 59 dias
  7 +@graph = Koala::Facebook::API.new('CAAD8cd4tMVkBAO3sh2DrzwZCDfeQq9ZAvTz7Jz24ZC26KtMfBoljqaXhD2vBV1zpP0bjrpxXUBzJvKKcFzOm6rMG9Sok7iNVUaxt5iwr7dfMqCvHpMboKpqrqgeLrfCH5ITVTAdezA6ZBSr9iOJrqyCSOYfui0zTmbXJ3FqtshwNRrRy4NPH')
  8 +
  9 +#feed = @graph.get_connections("participabr", "posts")
  10 +
  11 +comentariosIniciais = []
  12 +comentariosExtraidos = []
  13 +comentariosNovos = []
  14 +
  15 +primeiraVez = true
  16 +
  17 +while true
  18 +
  19 + feed = @graph.get_connections("mundoreagindo", "posts")
  20 +
  21 + array = []
  22 + comentariosExtraidos = []
  23 + feed.each {|f|
  24 + if f['comments'] != nil && f['comments']['data'] != nil
  25 + array.push(f['comments']['data'])
  26 + end
  27 + }
  28 +
  29 + array.each{ |comentarios|
  30 + comentarios.each{|comentario|
  31 + comentariosExtraidos.push("#{comentario['from']['name']} disse: #{comentario['message']}")
  32 + }
  33 + }
  34 +
  35 + comentariosExtraidos = comentariosExtraidos.uniq
  36 +
  37 + if primeiraVez
  38 + comentariosIniciais=comentariosExtraidos.clone
  39 + primeiraVez = false
  40 + end
  41 +
  42 +# comentariosExtraidos.each{|comentario|
  43 +# puts comentario
  44 +# }
  45 +
  46 + comentariosNovos = comentariosExtraidos - comentariosIniciais
  47 + comentariosNovos = comentariosNovos.uniq
  48 + comentariosIniciais += comentariosNovos
  49 + comentariosIniciais = comentariosIniciais.uniq
  50 + comentariosNovos.each{|comentario|
  51 + puts comentario
  52 + }
  53 +
  54 + sleep(5)
  55 +end
... ...
plugins/community_hub/facebook_stream/lib_facebook_stream.rb 0 → 100644
... ... @@ -0,0 +1,48 @@
  1 +require 'rubygems'
  2 +require 'koala'
  3 +require 'json'
  4 +
  5 +#Warning!!! Warning!!! Warning!!! Warning!!! Warning!!! Warning!!! Warning!!! Warning!!!
  6 +#token will expire at 12/04/2014 (Brazilian date format) + 59 days
  7 +#'CAAD8cd4tMVkBAO3sh2DrzwZCDfeQq9ZAvTz7Jz24ZC26KtMfBoljqaXhD2vBV1zpP0bjrpxXUBzJvKKcFzOm6rMG9Sok7iNVUaxt5iwr7dfMqCvHpMboKpqrqgeLrfCH5ITVTAdezA6ZBSr9iOJrqyCSOYfui0zTmbXJ3FqtshwNRrRy4NPH'
  8 +# BACKUP TOKEN 'CAAEhsewl0ZAcBAHhipXszZCURSwWLmgvceDbs9mB5baJdLriFxYMEzywmF2fvZBuThuA2Mm7QF8wPd3E6R5pVqVEnC2VhcBb4VrfAnkZC73ZC5g1NRUnKZCB2e6CaRiUBDatR2nf505PeKp7Aj5XxvTdfSqdZCsXxQFYZApPNSUUgkUWm6HwL4rp21MRJXb612sZD'
  9 +
  10 +def facebook_comments(hub, author_id, page_id, pooling_time, token, proxy_url)
  11 + pooling_time ||= 5
  12 + Koala.http_service.http_options = { :proxy => proxy_url } unless proxy_url.blank?
  13 +
  14 + @graph = Koala::Facebook::API.new(token)
  15 + initialComments = []
  16 + firstTime = true
  17 + while true
  18 + feed = @graph.get_connections(page_id, "posts")
  19 + array = []
  20 + extractedComments = []
  21 + feed.each {|f|
  22 + if f['comments'] != nil && f['comments']['data'] != nil
  23 + array.push(f['comments']['data'])
  24 + end
  25 + }
  26 + extractedComments = array.flatten.uniq
  27 + if firstTime
  28 + initialComments = extractedComments.clone
  29 + firstTime = false
  30 + end
  31 + newComments = extractedComments - initialComments
  32 + newComments = newComments.uniq
  33 + initialComments += newComments
  34 + initialComments = initialComments.uniq
  35 + newComments.each{|comment|
  36 + puts "#{comment['from']['name']} " + _("said") + ": #{comment['message']}"
  37 + noosferoComment = Comment.new
  38 + noosferoComment.title = 'hub-message-facebook'
  39 + noosferoComment.source = hub
  40 + noosferoComment.body = comment['message']
  41 + noosferoComment.author_id = author_id
  42 + noosferoComment.name = comment['from']['name']
  43 + noosferoComment.email = 'admin@localhost.local'
  44 + noosferoComment.save!
  45 + }
  46 + sleep(pooling_time)
  47 + end
  48 +end
... ...
plugins/community_hub/facebook_stream/sample.hash 0 → 100644
... ... @@ -0,0 +1,37 @@
  1 +{"shares"=>
  2 + {"count"=>1}, "actions"=>[{"name"=>"Comment", "link"=>"https://www.facebook.com/584831918242311/posts/671466872912148"},
  3 + {"name"=>"Like", "link"=>"https://www.facebook.com/584831918242311/posts/671466872912148"}],
  4 + "from"=>{"name"=>"Participabr", "category"=>"Community", "id"=>"584831918242311"},
  5 + "icon"=>"https://fbstatic-a.akamaihd.net/rsrc.php/v2/yz/r/StEh3RhPvjk.gif",
  6 + "id"=>"584831918242311_671466872912148",
  7 + "created_time"=>"2014-04-12T13:00:01+0000",
  8 + "type"=>"photo",
  9 + "updated_time"=>"2014-04-12T13:00:01+0000",
  10 + "privacy"=>{"value"=>""},
  11 + "link"=>"https://www.facebook.com/photo.php?fbid=671348086257360&set=a.611370448921791.1073741828.584831918242311&type=1&relevant_count=1", "object_id"=>"671348086257360", "status_type"=>"added_photos",
  12 + "message"=>"BOM DIA pra voc\303\252 que est\303\241 contando os dias para a #ArenaNETmundial!\n\nFALTA POUCO! Fique por dentro de tudo o que rolar\303\241 no maior evento da cultura digit@l! Quer saber mais sobre a programa\303\247\303\243o, os di\303\241logos e atra\303\247\303\265es? Ent\303\243o n\303\243o perca tempo! \n\nACOMPANHE e PARTICIPE! http://www.participa.br/arena\n\n#ParticipaBR", "likes"=>{"data"=>[{"name"=>"Nanda Barreto", "id"=>"100000525584317"}, {"name"=>"Natascha Castro", "id"=>"1792307671"}, {"name"=>"Vanessa Ferreira", "id"=>"100008128234636"}, {"name"=>"Katia Figueira", "id"=>"1171034080"}, {"name"=>"Carla Joner", "id"=>"1659400126"}, {"name"=>"Fagner Cunha", "id"=>"100007101672860"}, {"name"=>"Fernando Silva Soares Silva", "id"=>"1578450483"}], "paging"=>{"cursors"=>{"after"=>"MTU3ODQ1MDQ4Mw==", "before"=>"MTAwMDAwNTI1NTg0MzE3"}}}, "picture"=>"https://fbcdn-photos-d-a.akamaihd.net/hphotos-ak-prn1/v/t1.0-0/10171617_671348086257360_5332957054169466779_s.jpg?oh=57626662a0fccb0325162a7c72f86097&oe=53C4ECE6&__gda__=1405116765_706c0ad0982e3858c862eab9d71eed39"}
  13 +
  14 +{"shares"=>{"count"=>5}, "actions"=>[{"name"=>"Comment", "link"=>"https://www.facebook.com/584831918242311/posts/671235546268614"}, {"name"=>"Like", "link"=>"https://www.facebook.com/584831918242311/posts/671235546268614"}], "from"=>{"name"=>"Participabr", "category"=>"Community", "id"=>"584831918242311"}, "icon"=>"https://fbstatic-a.akamaihd.net/rsrc.php/v2/yz/r/StEh3RhPvjk.gif", "to"=>{"data"=>[{"name"=>"Centro Cultural S\303\243o Paulo", "category"=>"Public places", "id"=>"320942385642", "category_list"=>[{"name"=>"Art Gallery", "id"=>"197384240287028"}, {"name"=>"Theatre", "id"=>"173883042668223"}, {"name"=>"Library", "id"=>"169896676390222"}]}]}, "id"=>"584831918242311_671235546268614", "created_time"=>"2014-04-11T22:00:01+0000", "type"=>"photo", "updated_time"=>"2014-04-11T22:00:01+0000", "privacy"=>{"value"=>""}, "link"=>"https://www.facebook.com/photo.php?fbid=671207849604717&set=a.611370448921791.1073741828.584831918242311&type=1&relevant_count=1", "message_tags"=>{"187"=>[{"name"=>"Centro Cultural S\303\243o Paulo", "id"=>"320942385642", "type"=>"page", "length"=>25, "offset"=>187}]}, "object_id"=>"671207849604717", "status_type"=>"added_photos", "message"=>"Se voc\303\252 gosta de navegar LIVREMENTE pela INTERNET, a #ArenaNETmundial \303\251 o local ideal para nos encontramos! \n\nVamos AGITAR a cidade de S\303\243o Paulo, durante os dias 22, 23 e 24 de abril, no Centro Cultural S\303\243o Paulo, e contamos com a sua PARTICIPA\303\207\303\203O para definirmos, juntos, o FUTURO da REDE!\n\nConfirme sua presen\303\247a e venha para o maior encontro da cultura digital! http://bit.ly/ArenaNETmundial \n\n#ParticipaBR", "likes"=>{"data"=>[{"name"=>"MP LN", "id"=>"100000053156433"}, {"name"=>"Murutinga Abaetetuba Murutinga", "id"=>"100008004282653"}, {"name"=>"Robson B. Sampaio", "id"=>"100000664962544"}, {"name"=>"Luiz Claudio Souza", "id"=>"100000088952450"}, {"name"=>"Raquel Saraiva", "id"=>"100001990410008"}, {"name"=>"Participabr", "id"=>"584831918242311"}, {"name"=>"Jo\303\243o Paulo Mehl", "id"=>"1231157546"}, {"name"=>"Alexandra Peixoto", "id"=>"749059638"}], "paging"=>{"cursors"=>{"after"=>"NzQ5MDU5NjM4", "before"=>"MTAwMDAwMDUzMTU2NDMz"}}}, "picture"=>"https://fbcdn-photos-g-a.akamaihd.net/hphotos-ak-prn2/t1.0-0/10169317_671207849604717_5406099128447544778_s.jpg"}
  15 +{"shares"=>{"count"=>1}, "actions"=>[{"name"=>"Comment", "link"=>"https://www.facebook.com/584831918242311/posts/671197902939045"}, {"name"=>"Like", "link"=>"https://www.facebook.com/584831918242311/posts/671197902939045"}], "from"=>{"name"=>"Participabr", "category"=>"Community", "id"=>"584831918242311"}, "icon"=>"https://fbstatic-a.akamaihd.net/rsrc.php/v2/yz/r/StEh3RhPvjk.gif", "to"=>{"data"=>[{"name"=>"Centro Cultural S\303\243o Paulo", "category"=>"Public places", "id"=>"320942385642", "category_list"=>[{"name"=>"Art Gallery", "id"=>"197384240287028"}, {"name"=>"Theatre", "id"=>"173883042668223"}, {"name"=>"Library", "id"=>"169896676390222"}]}]}, "id"=>"584831918242311_671197902939045", "created_time"=>"2014-04-11T19:47:48+0000", "type"=>"photo", "updated_time"=>"2014-04-11T19:47:48+0000", "privacy"=>{"value"=>""}, "link"=>"https://www.facebook.com/photo.php?fbid=671197652939070&set=a.611370448921791.1073741828.584831918242311&type=1&relevant_count=1", "message_tags"=>{"174"=>[{"name"=>"Centro Cultural S\303\243o Paulo", "id"=>"320942385642", "type"=>"page", "length"=>25, "offset"=>174}]}, "object_id"=>"671197652939070", "status_type"=>"added_photos", "message"=>"A #ArenaNETmundial est\303\241 sendo criada por muitas mentes e cora\303\247\303\265es que acreditam na #InternetLivre como uma condi\303\247\303\243o para a democracia!\n\nNeste EXATO momento est\303\241 rolando, no Centro Cultural S\303\243o Paulo, o \303\272ltimo ENCONTR\303\203O com a SOCIEDADE CIVIL para debater a AGENDA do evento! Na pauta, a defini\303\247\303\243o de temas, sugest\303\243o de convidad@s e e \303\272ltimos retoques na programa\303\247\303\243o. \n\nNosso MUITO obrigad@ a tod@s os parceir@s que est\303\243o conosco na constru\303\247\303\243o desta hist\303\263ria! \n\nAcompanhe nossa cobertura pelo Twitter: https://twitter.com/participabr", "likes"=>{"data"=>[{"name"=>"Carla Joner", "id"=>"1659400126"}, {"name"=>"Cl\303\241udia Sousa Leit\303\243o", "id"=>"100004451373687"}, {"name"=>"Robson B. Sampaio", "id"=>"100000664962544"}, {"name"=>"At\303\255lio Alencar", "id"=>"100001932291363"}, {"name"=>"Participabr", "id"=>"584831918242311"}, {"name"=>"Yuri Almeida", "id"=>"551947517"}, {"name"=>"Janaina Spode", "id"=>"579251019"}, {"name"=>"Nanda Barreto", "id"=>"100000525584317"}], "paging"=>{"cursors"=>{"after"=>"MTAwMDAwNTI1NTg0MzE3", "before"=>"MTY1OTQwMDEyNg=="}}}, "picture"=>"https://fbcdn-photos-b-a.akamaihd.net/hphotos-ak-prn2/t1.0-0/1477604_671197652939070_5437456354222840972_s.jpg"}
  16 +{"shares"=>{"count"=>3}, "actions"=>[{"name"=>"Comment", "link"=>"https://www.facebook.com/584831918242311/posts/671156409609861"}, {"name"=>"Like", "link"=>"https://www.facebook.com/584831918242311/posts/671156409609861"}], "from"=>{"name"=>"Participabr", "category"=>"Community", "id"=>"584831918242311"}, "icon"=>"https://fbstatic-a.akamaihd.net/rsrc.php/v2/yz/r/StEh3RhPvjk.gif", "id"=>"584831918242311_671156409609861", "created_time"=>"2014-04-11T17:35:47+0000", "type"=>"photo", "updated_time"=>"2014-04-11T17:35:47+0000", "privacy"=>{"value"=>""}, "link"=>"https://www.facebook.com/photo.php?fbid=671156066276562&set=a.611370448921791.1073741828.584831918242311&type=1&relevant_count=1", "object_id"=>"671156066276562", "status_type"=>"added_photos", "message"=>"A #ArenaNETmundial ser\303\241 o nosso ponto de encontro para discutirmos o FUTURO da INTERNET! \n\nVenha conferir os di\303\241logos sobre a DEMOCRACIA na REDE, DIREITOS HUMANOS, PARTICIPA\303\207\303\203O SOCIAL e muito mais! http://ow.ly/vCgb7\n\nSe voc\303\252 ainda n\303\243o confirmou presen\303\247a no evento, corre que ainda d\303\241 tempo! Vamos AGITAR a REDE!\n\n#ParticipaBR", "likes"=>{"data"=>[{"name"=>"Natalia Menhem", "id"=>"501520025"}, {"name"=>"Robson B. Sampaio", "id"=>"100000664962544"}, {"name"=>"Luiz Claudio Souza", "id"=>"100000088952450"}, {"name"=>"Adriana Martorano", "id"=>"100005369532256"}, {"name"=>"Leo Farias", "id"=>"1475415098"}, {"name"=>"Myrian Conor", "id"=>"100000262033394"}, {"name"=>"Alexandra Peixoto", "id"=>"749059638"}], "paging"=>{"cursors"=>{"after"=>"NzQ5MDU5NjM4", "before"=>"NTAxNTIwMDI1"}}}, "picture"=>"https://fbcdn-photos-f-a.akamaihd.net/hphotos-ak-frc3/t1.0-0/10151967_671156066276562_1040945857784462133_s.png"}
  17 +{"shares"=>{"count"=>3}, "actions"=>[{"name"=>"Comment", "link"=>"https://www.facebook.com/584831918242311/posts/671092979616204"}, {"name"=>"Like", "link"=>"https://www.facebook.com/584831918242311/posts/671092979616204"}], "from"=>{"name"=>"Participabr", "category"=>"Community", "id"=>"584831918242311"}, "icon"=>"https://fbstatic-a.akamaihd.net/rsrc.php/v2/yz/r/StEh3RhPvjk.gif", "id"=>"584831918242311_671092979616204", "created_time"=>"2014-04-11T14:15:00+0000", "type"=>"photo", "updated_time"=>"2014-04-11T14:15:00+0000", "privacy"=>{"value"=>""}, "link"=>"https://www.facebook.com/photo.php?fbid=670251459700356&set=a.611370448921791.1073741828.584831918242311&type=1&relevant_count=1", "object_id"=>"670251459700356", "status_type"=>"added_photos", "message"=>"Agora a LUTA \303\251 no Senado!\n\n#MarcoCivil: Senado far\303\241 tr\303\252s audi\303\252ncias p\303\272blicas!\n\nSer\303\243o convidados para o debate representantes da Anatel, do CGI, do Sindtelebrasil e o Idec. As audi\303\252ncias est\303\243o previstas para os dias 10, 15 e 22 de abril. Saiba mais: http://ow.ly/vClKH\n\n#NaM\303\255dia #ParticipaBR", "likes"=>{"data"=>[{"name"=>"Robson B. Sampaio", "id"=>"100000664962544"}, {"name"=>"Alexandre Arns Gonzales", "id"=>"100001822508049"}, {"name"=>"Vanessa Ferreira", "id"=>"100008128234636"}, {"name"=>"MP LN", "id"=>"100000053156433"}, {"name"=>"Carlos Lobo", "id"=>"763893285"}, {"name"=>"Leo Farias", "id"=>"1475415098"}, {"name"=>"Janaina Spode", "id"=>"579251019"}, {"name"=>"Adriana Martorano", "id"=>"100005369532256"}, {"name"=>"Myrian Conor", "id"=>"100000262033394"}, {"name"=>"Alexandra Peixoto", "id"=>"749059638"}], "paging"=>{"cursors"=>{"after"=>"NzQ5MDU5NjM4", "before"=>"MTAwMDAwNjY0OTYyNTQ0"}}}, "picture"=>"https://fbcdn-photos-d-a.akamaihd.net/hphotos-ak-prn2/t1.0-0/10258237_670251459700356_7951669488914497992_s.jpg"}
  18 +{"shares"=>{"count"=>11}, "actions"=>[{"name"=>"Comment", "link"=>"https://www.facebook.com/584831918242311/posts/671067426285426"}, {"name"=>"Like", "link"=>"https://www.facebook.com/584831918242311/posts/671067426285426"}], "from"=>{"name"=>"Participabr", "category"=>"Community", "id"=>"584831918242311"}, "icon"=>"https://fbstatic-a.akamaihd.net/rsrc.php/v2/yz/r/StEh3RhPvjk.gif", "to"=>{"data"=>[{"name"=>"Elizabeth Gilbert", "category"=>"Writer", "id"=>"227291194019670"}, {"name"=>"Be\303\241 Tibiri\303\247\303\241", "id"=>"100001756483405"}, {"name"=>"Javier Toret Medina", "id"=>"1221646905"}, {"name"=>"Sergio Amadeu da Silveira", "id"=>"752385273"}]}, "id"=>"584831918242311_671067426285426", "created_time"=>"2014-04-11T13:00:01+0000", "type"=>"photo", "updated_time"=>"2014-04-11T13:00:01+0000", "privacy"=>{"value"=>""}, "link"=>"https://www.facebook.com/photo.php?fbid=670811722977663&set=a.611370448921791.1073741828.584831918242311&type=1&relevant_count=1", "message_tags"=>{"229"=>[{"name"=>"Sergio Amadeu", "id"=>"752385273", "type"=>"user", "length"=>13, "offset"=>229}], "164"=>[{"name"=>"Elizabeth Gilbert", "id"=>"227291194019670", "type"=>"page", "length"=>17, "offset"=>164}], "200"=>[{"name"=>"Be\303\241 Tibiri\303\247\303\241", "id"=>"100001756483405", "type"=>"user", "length"=>12, "offset"=>200}], "214"=>[{"name"=>"Javier Toret", "id"=>"1221646905", "type"=>"user", "length"=>12, "offset"=>214}]}, "object_id"=>"670811722977663", "status_type"=>"added_photos", "message"=>"Veja quem s\303\243o os debatedores que j\303\241 CONFIRMARAM presen\303\247a na #ArenaNETmundial, o evento que vai sacudir a REDE, de 22 a 24 de abril, no Centro Cultural S\303\243o Paulo! \n\nElizabeth Gilbert, Tim Berners-Lee, Be\303\241 Tibiri\303\247\303\241, Javier Toret e Sergio Amadeu s\303\243o alguns dos GRANDES nomes confirmados! Quer saber mais sobre os debatedores? \303\211 s\303\263 CLICAR aqui -> http://ow.ly/vEPfV\n\nCONFIRME sua presen\303\247a no evento e venha discutir a GOVERNAN\303\207A da REDE! http://bit.ly/ArenaNETmundial!\n\n#ParticipaBR", "likes"=>{"data"=>[{"name"=>"Murutinga Abaetetuba Murutinga", "id"=>"100008004282653"}, {"name"=>"Robson B. Sampaio", "id"=>"100000664962544"}, {"name"=>"Tatiana Sim\303\265es Sottili", "id"=>"1642810466"}, {"name"=>"Javier Toret Medina", "id"=>"1221646905"}, {"name"=>"Lucio Uberdan", "id"=>"685024343"}, {"name"=>"Allix Lis Rodrigues", "id"=>"624623048"}, {"name"=>"Nanda Barreto", "id"=>"100000525584317"}, {"name"=>"Alexandra Peixoto", "id"=>"749059638"}, {"name"=>"Janaina Spode", "id"=>"579251019"}, {"name"=>"Adriana Martorano", "id"=>"100005369532256"}, {"name"=>"Myrian Conor", "id"=>"100000262033394"}], "paging"=>{"cursors"=>{"after"=>"MTAwMDAwMjYyMDMzMzk0", "before"=>"MTAwMDA4MDA0MjgyNjUz"}}}, "picture"=>"https://fbcdn-photos-a-a.akamaihd.net/hphotos-ak-frc3/t1.0-0/1466021_670811722977663_2539462382863559512_s.png"}
  19 +{"shares"=>{"count"=>6}, "actions"=>[{"name"=>"Comment", "link"=>"https://www.facebook.com/584831918242311/posts/671044212954414"}, {"name"=>"Like", "link"=>"https://www.facebook.com/584831918242311/posts/671044212954414"}], "from"=>{"name"=>"Participabr", "category"=>"Community", "id"=>"584831918242311"}, "icon"=>"https://fbstatic-a.akamaihd.net/rsrc.php/v2/yz/r/StEh3RhPvjk.gif", "id"=>"584831918242311_671044212954414", "created_time"=>"2014-04-11T11:30:00+0000", "type"=>"photo", "updated_time"=>"2014-04-11T11:30:00+0000", "privacy"=>{"value"=>""}, "link"=>"https://www.facebook.com/photo.php?fbid=670808672977968&set=a.611370448921791.1073741828.584831918242311&type=1&relevant_count=1", "object_id"=>"670808672977968", "status_type"=>"added_photos", "message"=>"BOM DIA pra voc\303\252 que quer revolucionar a INTERNET! \n\nE que tal come\303\247ar esta revolu\303\247\303\243o dando ideias e enviando propostas para mudarmos o FUTURO da REDE? Acesse a nossa consulta p\303\272blica e deixe a sua sugest\303\243o! http://www.participa.br/\n\nA #ArenaNETmundial quer ouvir a sua opini\303\243o: QUE INTERNET VOC\303\212 QUER? \n\n#ParticipaBR", "likes"=>{"data"=>[{"name"=>"Renato Cortez", "id"=>"100000144194858"}, {"name"=>"Izabela Matos Chaves", "id"=>"100004256850261"}, {"name"=>"Raquel Le\303\243es", "id"=>"100000163559078"}, {"name"=>"Robson B. Sampaio", "id"=>"100000664962544"}, {"name"=>"Vanessa Ferreira", "id"=>"100008128234636"}, {"name"=>"Myrian Conor", "id"=>"100000262033394"}, {"name"=>"Alexandra Peixoto", "id"=>"749059638"}, {"name"=>"Nathalia Sautchuk Patricio", "id"=>"662335299"}, {"name"=>"Carola Oliveira", "id"=>"1160276837"}, {"name"=>"Luiz Augusto Lisb\303\264a", "id"=>"100002956996510"}, {"name"=>"Janaina Spode", "id"=>"579251019"}, {"name"=>"Elly Marlley", "id"=>"100005663351771"}, {"name"=>"Participabr", "id"=>"584831918242311"}, {"name"=>"Yuri Almeida", "id"=>"551947517"}, {"name"=>"MP LN", "id"=>"100000053156433"}], "paging"=>{"cursors"=>{"after"=>"MTAwMDAwMDUzMTU2NDMz", "before"=>"MTAwMDAwMTQ0MTk0ODU4"}}}, "picture"=>"https://fbcdn-photos-g-a.akamaihd.net/hphotos-ak-prn2/t1.0-0/10007468_670808672977968_7995649865195786401_s.jpg"}
  20 +{"shares"=>{"count"=>12}, "actions"=>[{"name"=>"Comment", "link"=>"https://www.facebook.com/584831918242311/posts/670853929640109"}, {"name"=>"Like", "link"=>"https://www.facebook.com/584831918242311/posts/670853929640109"}], "comments"=>{"data"=>[{"like_count"=>1, "user_likes"=>false, "can_remove"=>false, "from"=>{"name"=>"Evelyn Araripe", "id"=>"100003010308675"}, "id"=>"670805622978273_2156946", "created_time"=>"2014-04-11T17:57:19+0000", "message"=>"T\303\241 ficando muito boa essa programa\303\247\303\243o!!!"}], "paging"=>{"cursors"=>{"after"=>"MQ==", "before"=>"MQ=="}}}, "from"=>{"name"=>"Participabr", "category"=>"Community", "id"=>"584831918242311"}, "icon"=>"https://fbstatic-a.akamaihd.net/rsrc.php/v2/yz/r/StEh3RhPvjk.gif", "to"=>{"data"=>[{"name"=>"Centro Cultural S\303\243o Paulo", "category"=>"Public places", "id"=>"320942385642", "category_list"=>[{"name"=>"Art Gallery", "id"=>"197384240287028"}, {"name"=>"Theatre", "id"=>"173883042668223"}, {"name"=>"Library", "id"=>"169896676390222"}]}, {"name"=>"Tom Z\303\251", "category"=>"Musician/band", "id"=>"26030117065"}, {"name"=>"Fernando Anitelli", "category"=>"Musician/band", "id"=>"146916915375515"}, {"name"=>"Emicida", "category"=>"Musician/band", "id"=>"145578725499808"}, {"name"=>"Jorge Mautner", "category"=>"Musician/band", "id"=>"24050959127"}]}, "id"=>"584831918242311_670853929640109", "created_time"=>"2014-04-11T00:00:01+0000", "type"=>"photo", "updated_time"=>"2014-04-11T17:57:19+0000", "privacy"=>{"value"=>""}, "link"=>"https://www.facebook.com/photo.php?fbid=670805622978273&set=a.611370448921791.1073741828.584831918242311&type=1&relevant_count=1", "message_tags"=>{"206"=>[{"name"=>"Tom Z\303\251", "id"=>"26030117065", "type"=>"page", "length"=>6, "offset"=>206}], "243"=>[{"name"=>"Jorge Mautner", "id"=>"24050959127", "type"=>"page", "length"=>13, "offset"=>243}], "233"=>[{"name"=>"Emicida", "id"=>"145578725499808", "type"=>"page", "length"=>7, "offset"=>233}], "157"=>[{"name"=>"Centro Cultural S\303\243o Paulo", "id"=>"320942385642", "type"=>"page", "length"=>25, "offset"=>157}], "214"=>[{"name"=>"Fernando Anitelli", "id"=>"146916915375515", "type"=>"page", "length"=>17, "offset"=>214}]}, "object_id"=>"670805622978273", "status_type"=>"added_photos", "message"=>"A CULTURA DIGITAL TEM ESPA\303\207O NOS SHOWS DA #ArenaNETmundial!\n\nPara instigar a criatividade coletiva, a #ArenaNETmundial abre espa\303\247o para atra\303\247\303\265es musicais no Centro Cultural S\303\243o Paulo, de 22 a 24 de abril!\n\nTom Z\303\251, Fernando Anitelli, Emicida e Jorge Mautner v\303\243o fechar a rotina di\303\241ria de di\303\241logos e oficinas do evento! Se voc\303\252 est\303\241 curios@ para saber a programa\303\247\303\243o, n\303\243o perca tempo, acesse: http://ow.ly/vFaAu\n\n#ParticipaBR", "likes"=>{"data"=>[{"name"=>"Robson B. Sampaio", "id"=>"100000664962544"}, {"name"=>"Pepe Martini", "id"=>"1254030646"}, {"name"=>"Evelyn Araripe", "id"=>"100003010308675"}, {"name"=>"Fernando Caixeta", "id"=>"100000103555498"}, {"name"=>"Alan Collyer", "id"=>"100003584527506"}, {"name"=>"Laila Bellix", "id"=>"679318319"}, {"name"=>"Participabr", "id"=>"584831918242311"}, {"name"=>"Rodolfo Tokimatsu", "id"=>"100003197560595"}, {"name"=>"B Tany B. Tany", "id"=>"100000308845954"}, {"name"=>"Reinaldo Castro", "id"=>"1265463106"}, {"name"=>"Nanda Barreto", "id"=>"100000525584317"}, {"name"=>"Adriana Martorano", "id"=>"100005369532256"}, {"name"=>"Talita Nogueira", "id"=>"100001714757945"}, {"name"=>"Renilson Dur\303\243es", "id"=>"1665215750"}, {"name"=>"Janaina Spode", "id"=>"579251019"}, {"name"=>"Mariana Heinz", "id"=>"100001699022773"}, {"name"=>"Wellington Par\303\241", "id"=>"100000408605032"}, {"name"=>"Yuri Almeida", "id"=>"551947517"}, {"name"=>"Christiano Cavalcanti", "id"=>"100001984914972"}, {"name"=>"Alexandra Peixoto", "id"=>"749059638"}, {"name"=>"Fernando Silva Soares Silva", "id"=>"1578450483"}, {"name"=>"Henrique Parra Parra Filho", "id"=>"100000747904691"}, {"name"=>"D\303\251bora Lessa", "id"=>"680508753"}], "paging"=>{"cursors"=>{"after"=>"NjgwNTA4NzUz", "before"=>"MTAwMDAwNjY0OTYyNTQ0"}}}, "picture"=>"https://fbcdn-photos-e-a.akamaihd.net/hphotos-ak-ash3/t1.0-0/10155378_670805622978273_7293058947948255933_s.jpg"}
  21 +{"actions"=>[{"name"=>"Comment", "link"=>"https://www.facebook.com/584831918242311/posts/670799439645558"}, {"name"=>"Like", "link"=>"https://www.facebook.com/584831918242311/posts/670799439645558"}], "from"=>{"name"=>"Participabr", "category"=>"Community", "id"=>"584831918242311"}, "icon"=>"https://fbstatic-a.akamaihd.net/rsrc.php/v2/yz/r/StEh3RhPvjk.gif", "id"=>"584831918242311_670799439645558", "created_time"=>"2014-04-10T22:00:00+0000", "type"=>"photo", "updated_time"=>"2014-04-10T22:00:00+0000", "privacy"=>{"value"=>""}, "link"=>"https://www.facebook.com/photo.php?fbid=670783762980459&set=a.611370448921791.1073741828.584831918242311&type=1&relevant_count=1", "object_id"=>"670783762980459", "status_type"=>"added_photos", "message"=>"Da #ArenaNETmundial para o MUNDO!\n\nColuna do Estad\303\243o fala sobre a participa\303\247\303\243o do Tim Berners-Lee no evento que vai AGITAR a REDE neste m\303\252s! http://ow.ly/vEPUy\n\n#NaM\303\255dia #ParticipaBR", "likes"=>{"data"=>[{"name"=>"Robson B. Sampaio", "id"=>"100000664962544"}, {"name"=>"Johnny Pequeno", "id"=>"100001773781004"}, {"name"=>"Alexandra Peixoto", "id"=>"749059638"}, {"name"=>"Rafael Pops Barbosa Moraes", "id"=>"1533873688"}, {"name"=>"Fernando Silva Soares Silva", "id"=>"1578450483"}, {"name"=>"Carlos Lobo", "id"=>"763893285"}], "paging"=>{"cursors"=>{"after"=>"NzYzODkzMjg1", "before"=>"MTAwMDAwNjY0OTYyNTQ0"}}}, "picture"=>"https://fbcdn-photos-b-a.akamaihd.net/hphotos-ak-prn2/t1.0-0/10171045_670783762980459_9192964314133703634_s.jpg"}
  22 +{"shares"=>{"count"=>17}, "actions"=>[{"name"=>"Comment", "link"=>"https://www.facebook.com/584831918242311/posts/670756449649857"}, {"name"=>"Like", "link"=>"https://www.facebook.com/584831918242311/posts/670756449649857"}], "from"=>{"name"=>"Participabr", "category"=>"Community", "id"=>"584831918242311"}, "icon"=>"https://fbstatic-a.akamaihd.net/rsrc.php/v2/yz/r/StEh3RhPvjk.gif", "to"=>{"data"=>[{"name"=>"Centro Cultural S\303\243o Paulo", "category"=>"Public places", "id"=>"320942385642", "category_list"=>[{"name"=>"Art Gallery", "id"=>"197384240287028"}, {"name"=>"Theatre", "id"=>"173883042668223"}, {"name"=>"Library", "id"=>"169896676390222"}]}]}, "id"=>"584831918242311_670756449649857", "created_time"=>"2014-04-10T19:22:39+0000", "type"=>"photo", "updated_time"=>"2014-04-10T19:22:39+0000", "privacy"=>{"value"=>""}, "link"=>"https://www.facebook.com/photo.php?fbid=670756402983195&set=a.611370448921791.1073741828.584831918242311&type=1&relevant_count=1", "message_tags"=>{"86"=>[{"name"=>"Centro Cultural S\303\243o Paulo", "id"=>"320942385642", "type"=>"page", "length"=>25, "offset"=>86}]}, "object_id"=>"670756402983195", "status_type"=>"added_photos", "message"=>"\303\232LTIMA CHAMADA PARA O ENCONTRO ABERTO DA #ArenaNETmundial!\n\nAmanh\303\243, das 15 \303\240s 17h, no Centro Cultural S\303\243o Paulo, acontece o \303\272ltimo encontro aberto para a constru\303\247\303\243o da AGENDA do evento!\n\nBuscamos um esfor\303\247o COLETIVO para preservar o processo ABERTO, PARTICIPATIVO e DEMOCR\303\201TICO! N\303\243o fique de fora! PARTICIPE! SAIBA mais -> http://ow.ly/vEMvs\n\n#MarcaNaAgenda #ParticipaBR", "likes"=>{"data"=>[{"name"=>"Robson B. Sampaio", "id"=>"100000664962544"}, {"name"=>"Pepe Martini", "id"=>"1254030646"}, {"name"=>"Lia Paul", "id"=>"100005140505167"}, {"name"=>"Thiago Sk\303\241rnio", "id"=>"100000805004346"}, {"name"=>"Rosely Andreassa", "id"=>"100003614211549"}, {"name"=>"Alexandra Peixoto", "id"=>"749059638"}, {"name"=>"Adriana Martorano", "id"=>"100005369532256"}, {"name"=>"Jo\303\243o Baptista Pimentel Neto", "id"=>"1551520480"}, {"name"=>"Kely Rego", "id"=>"100000530478123"}, {"name"=>"Nanda Barreto", "id"=>"100000525584317"}, {"name"=>"Marcelo Branco", "id"=>"1260145727"}, {"name"=>"Everton Rodrigues", "id"=>"832259597"}, {"name"=>"Douglas Freitas", "id"=>"100001187262990"}, {"name"=>"Carlos Lobo", "id"=>"763893285"}, {"name"=>"Myrian Conor", "id"=>"100000262033394"}], "paging"=>{"cursors"=>{"after"=>"MTAwMDAwMjYyMDMzMzk0", "before"=>"MTAwMDAwNjY0OTYyNTQ0"}}}, "picture"=>"https://fbcdn-photos-c-a.akamaihd.net/hphotos-ak-frc1/t1.0-0/10151311_670756402983195_7092075331556696204_s.png"}
  23 +{"shares"=>{"count"=>25}, "actions"=>[{"name"=>"Comment", "link"=>"https://www.facebook.com/584831918242311/posts/670664639659038"}, {"name"=>"Like", "link"=>"https://www.facebook.com/584831918242311/posts/670664639659038"}], "from"=>{"name"=>"Participabr", "category"=>"Community", "id"=>"584831918242311"}, "icon"=>"https://fbstatic-a.akamaihd.net/rsrc.php/v2/yz/r/StEh3RhPvjk.gif", "id"=>"584831918242311_670664639659038", "created_time"=>"2014-04-10T15:49:18+0000", "type"=>"photo", "updated_time"=>"2014-04-10T15:49:18+0000", "privacy"=>{"value"=>""}, "link"=>"https://www.facebook.com/photo.php?fbid=670663609659141&set=a.611370448921791.1073741828.584831918242311&type=1&relevant_count=1", "object_id"=>"670663609659141", "status_type"=>"added_photos", "message"=>"HOJE, \303\240s 14 tem TUITA\303\207O da #ArenaNETmundial! \n\nUse a hashtag #ArenaNETmundial e vamos invadir o Twitter! Acompanhe, participe e fique por dentro de tudo o que rolar\303\241 no evento! \n\n#ParticipaBR", "likes"=>{"data"=>[{"name"=>"Robson B. Sampaio", "id"=>"100000664962544"}, {"name"=>"Fernando Silva Soares Silva", "id"=>"1578450483"}, {"name"=>"Rosely Andreassa", "id"=>"100003614211549"}, {"name"=>"Adriana Martorano", "id"=>"100005369532256"}, {"name"=>"Usuarios de Internet del Ecuador", "id"=>"96481988151"}, {"name"=>"Manoel Lages Filho", "id"=>"100000020201492"}, {"name"=>"Everton Rodrigues", "id"=>"832259597"}, {"name"=>"Marcelo Branco", "id"=>"1260145727"}, {"name"=>"Nanda Barreto", "id"=>"100000525584317"}, {"name"=>"Myrian Conor", "id"=>"100000262033394"}, {"name"=>"Carlos Lobo", "id"=>"763893285"}, {"name"=>"Leoncio Nascimento", "id"=>"100000680460377"}, {"name"=>"Janaina Spode", "id"=>"579251019"}, {"name"=>"Thiago Sk\303\241rnio", "id"=>"100000805004346"}], "paging"=>{"cursors"=>{"after"=>"MTAwMDAwODA1MDA0MzQ2", "before"=>"MTAwMDAwNjY0OTYyNTQ0"}}}, "picture"=>"https://fbcdn-photos-h-a.akamaihd.net/hphotos-ak-frc3/t1.0-0/1558385_670663609659141_6538204679475681502_s.jpg"}
  24 +{"shares"=>{"count"=>76}, "actions"=>[{"name"=>"Comment", "link"=>"https://www.facebook.com/584831918242311/posts/670625762996259"}, {"name"=>"Like", "link"=>"https://www.facebook.com/584831918242311/posts/670625762996259"}], "comments"=>{"data"=>[{"like_count"=>5, "user_likes"=>false, "can_remove"=>false, "from"=>{"name"=>"Henrique Parra Parra Filho", "id"=>"100000747904691"}, "id"=>"670619366330232_2155057", "created_time"=>"2014-04-10T13:52:01+0000", "message_tags"=>[{"name"=>"Frederico Bortolato", "id"=>"1289479599", "type"=>"user", "length"=>19, "offset"=>242}, {"name"=>"Ricardo Poppi", "id"=>"100000099352333", "type"=>"user", "length"=>13, "offset"=>264}], "message"=>"Tim Berners-Lee, Manuel Castells e Gilberto Gil \303\251 programa\303\247\303\243o das mais interessantes. Tom Z\303\251, Fernando Anitelli, Emicida e Jorge Mautner \303\251 balada das melhores. N\303\243o sei se chamo de festa ou de aprendizado, mas sei que n\303\243o d\303\241 para perder heim Frederico Bortolato e Ricardo Poppi! ;)"}, {"like_count"=>3, "user_likes"=>false, "can_remove"=>false, "from"=>{"name"=>"Frederico Bortolato", "id"=>"1289479599"}, "id"=>"670619366330232_2155222", "created_time"=>"2014-04-10T15:17:19+0000", "message_tags"=>[{"name"=>"Henrique", "id"=>"100000747904691", "type"=>"user", "length"=>8, "offset"=>22}], "message"=>"Sem chance de perder, Henrique!"}, {"like_count"=>2, "user_likes"=>false, "can_remove"=>false, "from"=>{"name"=>"Lorac Mustaine", "id"=>"1083326546"}, "id"=>"670619366330232_2155143", "created_time"=>"2014-04-10T14:29:48+0000", "message"=>"Agora come\303\247ou ficar interessante... =)"}, {"like_count"=>1, "user_likes"=>false, "can_remove"=>false, "from"=>{"name"=>"Nestor Ribas Leite Filho", "id"=>"100003572810075"}, "id"=>"670619366330232_2155778", "created_time"=>"2014-04-10T21:59:28+0000", "message"=>"ISTO \303\211 JOIA RARA"}, {"like_count"=>1, "user_likes"=>false, "can_remove"=>false, "from"=>{"name"=>"Fa Conti", "id"=>"600679756"}, "id"=>"670619366330232_2155755", "created_time"=>"2014-04-10T21:27:47+0000", "message"=>"oba!"}, {"like_count"=>0, "user_likes"=>false, "can_remove"=>false, "from"=>{"name"=>"Ana Mirtes Fouro", "id"=>"100002265340422"}, "id"=>"670619366330232_2156470", "created_time"=>"2014-04-11T10:33:57+0000", "message"=>"(Y)"}, {"like_count"=>0, "user_likes"=>false, "can_remove"=>false, "from"=>{"name"=>"Ri At Uw", "id"=>"1071851267"}, "id"=>"670619366330232_2156197", "created_time"=>"2014-04-11T03:38:06+0000", "message_tags"=>[{"name"=>"Javier", "id"=>"528937139", "type"=>"user", "length"=>6, "offset"=>11}, {"name"=>"Otto", "id"=>"100002294062950", "type"=>"user", "length"=>4, "offset"=>18}, {"name"=>"Daniel", "id"=>"100000218054052", "type"=>"user", "length"=>6, "offset"=>23}, {"name"=>"Vitor", "id"=>"100002236271320", "type"=>"user", "length"=>5, "offset"=>30}], "message"=>"Vamos n\303\251?! Javier Otto Daniel Vitor"}, {"like_count"=>1, "user_likes"=>false, "can_remove"=>false, "from"=>{"name"=>"Lincoln Aoki", "id"=>"100000049366725"}, "id"=>"670619366330232_2155726", "created_time"=>"2014-04-10T20:59:38+0000", "message"=>"OK OK .. Valeu mestre Sergio Amadeu. A Internet n\303\243o pode ter dono, a Internet \303\251 do povo, precisamos ter mais democracia na era Digital. O Brasil j\303\241 supera mais linhas de celular habilitada que o n\303\272mero de habitantes do pa\303\255s. Estamos na era digital, por isso, o povo brasileiro precisa ter pelo menos acesso a Internet com pre\303\247os mais acess\303\255veis."}], "paging"=>{"cursors"=>{"after"=>"MQ==", "before"=>"OA=="}}}, "from"=>{"name"=>"Participabr", "category"=>"Community", "id"=>"584831918242311"}, "icon"=>"https://fbstatic-a.akamaihd.net/rsrc.php/v2/yz/r/StEh3RhPvjk.gif", "to"=>{"data"=>[{"name"=>"Tim Berners-Lee", "category"=>"Public figure", "id"=>"108177502537793"}, {"name"=>"Manuel Castells", "category"=>"Author", "id"=>"112735342073078"}, {"name"=>"Gilberto Gil", "category"=>"Musician/band", "id"=>"104152332963030"}, {"name"=>"Tom Z\303\251", "category"=>"Musician/band", "id"=>"26030117065"}, {"name"=>"Fernando Anitelli", "category"=>"Musician/band", "id"=>"132110136857273"}, {"name"=>"Emicida", "category"=>"Musician/band", "id"=>"145578725499808"}, {"name"=>"Jorge Mautner", "category"=>"Musician/band", "id"=>"24050959127"}]}, "id"=>"584831918242311_670625762996259", "created_time"=>"2014-04-10T13:49:53+0000", "type"=>"photo", "updated_time"=>"2014-04-11T10:33:57+0000", "privacy"=>{"value"=>""}, "link"=>"https://www.facebook.com/photo.php?fbid=670619366330232&set=a.611370448921791.1073741828.584831918242311&type=1&relevant_count=1", "message_tags"=>{"534"=>[{"name"=>"Jorge Mautner", "id"=>"24050959127", "type"=>"page", "length"=>13, "offset"=>534}], "524"=>[{"name"=>"Emicida", "id"=>"145578725499808", "type"=>"page", "length"=>7, "offset"=>524}], "35"=>[{"name"=>"Gilberto Gil", "id"=>"104152332963030", "type"=>"page", "length"=>12, "offset"=>35}], "505"=>[{"name"=>"Fernando Anitelli", "id"=>"132110136857273", "type"=>"page", "length"=>17, "offset"=>505}], "0"=>[{"name"=>"Tim Berners-Lee", "id"=>"108177502537793", "type"=>"page", "length"=>15, "offset"=>0}], "17"=>[{"name"=>"Manuel Castells", "id"=>"112735342073078", "type"=>"page", "length"=>15, "offset"=>17}], "497"=>[{"name"=>"Tom Z\303\251", "id"=>"26030117065", "type"=>"page", "length"=>6, "offset"=>497}]}, "object_id"=>"670619366330232", "status_type"=>"added_photos", "message"=>"Tim Berners-Lee, Manuel Castells e Gilberto Gil juntos, para discutir os rumos da Internet no Brasil e no mundo, a democracia na era digital e a sociedade em rede?? \n\n#Sim e al\303\251m dessas personalidades, a #ArenaNETmundial #ParticipaBR trar\303\241 outros grandes pensadores, ativistas, gestores p\303\272blicos e comunicadores de diversos pa\303\255ses. Para unir a cultura popular com a cultura digital, grandes artistas que s\303\243o ativistas do conhecimento livre far\303\243o apresenta\303\247\303\265es musicais no evento. Entre eles est\303\243o Tom Z\303\251, Fernando Anitelli, Emicida e Jorge Mautner. T\303\241 bom pra caramba! ;) \n\nVenha discutir o futuro da internet na #ArenaNETmundial! Confirme sua presen\303\247a no evento! http://bit.ly/ArenaNETmundial", "likes"=>{"data"=>[{"name"=>"Robson B. Sampaio", "id"=>"100000664962544"}, {"name"=>"Esmeralda Medeiros", "id"=>"100007760560534"}, {"name"=>"Nonatto Vieira", "id"=>"100003632488645"}, {"name"=>"Luiz S\303\251rgio Pires Guimar\303\243es", "id"=>"100004080441032"}, {"name"=>"Violeta Cross", "id"=>"100000784826227"}, {"name"=>"Tais Falc\303\243o", "id"=>"100001393874437"}, {"name"=>"Mary Oliveira", "id"=>"100006774454711"}, {"name"=>"Jane Celia Santos", "id"=>"100004278401016"}, {"name"=>"Eliana Santos", "id"=>"100004708982012"}, {"name"=>"Rodrigo Mantovani", "id"=>"100004036951692"}, {"name"=>"Aluizio Matias Santos", "id"=>"100000096283728"}, {"name"=>"Rosa Meire", "id"=>"1654472213"}, {"name"=>"Alzira Higino", "id"=>"100000838728858"}, {"name"=>"Carolina Rovai", "id"=>"1032733783"}, {"name"=>"Maria Barbosa Aparecida", "id"=>"100007490796202"}, {"name"=>"Pepe Martini", "id"=>"1254030646"}, {"name"=>"Everton Rodrigues", "id"=>"832259597"}, {"name"=>"S\303\251rgio Ant\303\264nio Mota Furtado", "id"=>"100003767543014"}, {"name"=>"Zeca Teodoro", "id"=>"1679641558"}, {"name"=>"Rafael Araujo", "id"=>"100004001539572"}, {"name"=>"Karoline Holanda", "id"=>"100000236542676"}, {"name"=>"Monick Passos", "id"=>"100007925590237"}, {"name"=>"Ana Maria Riva da Silva", "id"=>"100005727553477"}, {"name"=>"Luanacristina Simoes", "id"=>"100004173271257"}, {"name"=>"Iracema Ferreira", "id"=>"100005909612048"}], "paging"=>{"next"=>"https://graph.facebook.com/584831918242311_670625762996259/likes?access_token=CAAD8cd4tMVkBAO3sh2DrzwZCDfeQq9ZAvTz7Jz24ZC26KtMfBoljqaXhD2vBV1zpP0bjrpxXUBzJvKKcFzOm6rMG9Sok7iNVUaxt5iwr7dfMqCvHpMboKpqrqgeLrfCH5ITVTAdezA6ZBSr9iOJrqyCSOYfui0zTmbXJ3FqtshwNRrRy4NPH&limit=25&after=MTAwMDA1OTA5NjEyMDQ4", "cursors"=>{"after"=>"MTAwMDA1OTA5NjEyMDQ4", "before"=>"MTAwMDAwNjY0OTYyNTQ0"}}}, "picture"=>"https://fbcdn-photos-a-a.akamaihd.net/hphotos-ak-prn2/t1.0-0/1982044_670619366330232_6311457266477121189_s.jpg"}
  25 +{"story"=>"Participabr posted a link to F\303\263rum Internacional de Software Livre (FISL)'s timeline.", "from"=>{"name"=>"Participabr", "category"=>"Community", "id"=>"584831918242311"}, "story_tags"=>{"0"=>[{"name"=>"Participabr", "id"=>"584831918242311", "type"=>"page", "length"=>11, "offset"=>0}], "29"=>[{"name"=>"F\303\263rum Internacional de Software Livre (FISL)", "id"=>"53901836593", "type"=>"page", "length"=>44, "offset"=>29}]}, "id"=>"584831918242311_670616209663881", "created_time"=>"2014-04-10T13:12:38+0000", "type"=>"status", "updated_time"=>"2014-04-10T13:12:38+0000", "privacy"=>{"value"=>""}}
  26 +{"story"=>"Participabr posted a link to FNDC Democratiza\303\247\303\243o da Comunica\303\247\303\243o's timeline.", "from"=>{"name"=>"Participabr", "category"=>"Community", "id"=>"584831918242311"}, "story_tags"=>{"0"=>[{"name"=>"Participabr", "id"=>"584831918242311", "type"=>"page", "length"=>11, "offset"=>0}], "29"=>[{"name"=>"FNDC Democratiza\303\247\303\243o da Comunica\303\247\303\243o", "id"=>"645544058821361", "type"=>"page", "length"=>34, "offset"=>29}]}, "id"=>"584831918242311_670616169663885", "created_time"=>"2014-04-10T13:12:29+0000", "type"=>"status", "updated_time"=>"2014-04-10T13:12:29+0000", "privacy"=>{"value"=>""}}
  27 +{"story"=>"\"Hoje sai a programa\303\247\303\243o completa com os debatedores da #ArenaNETMundial! Logo mais compartilharemos em nossa p\303\241gina e aqui no face! Um time de peso e antenado com as principais quest\303\265es sobre governan\303\247a da internet, desafios no Brasil e as novas formas de participa\303\247\303\243o pol\303\255tica que emergem com a internet! Contamos com ajuda para divulgar! http://www.participa.br/arena/arena-net-mundial/dialogos\n\" on CISL's timeline.", "from"=>{"name"=>"Participabr", "category"=>"Community", "id"=>"584831918242311"}, "story_tags"=>{"402"=>[{"name"=>"CISL", "id"=>"432297343526878", "type"=>"page", "length"=>4, "offset"=>402}]}, "id"=>"584831918242311_670616156330553", "created_time"=>"2014-04-10T13:12:27+0000", "type"=>"status", "updated_time"=>"2014-04-10T13:12:27+0000", "privacy"=>{"value"=>""}, "status_type"=>"wall_post"}
  28 +{"story"=>"Participabr posted a link to CISL's timeline.", "from"=>{"name"=>"Participabr", "category"=>"Community", "id"=>"584831918242311"}, "story_tags"=>{"0"=>[{"name"=>"Participabr", "id"=>"584831918242311", "type"=>"page", "length"=>11, "offset"=>0}], "29"=>[{"name"=>"CISL", "id"=>"432297343526878", "type"=>"page", "length"=>4, "offset"=>29}]}, "id"=>"584831918242311_670616082997227", "created_time"=>"2014-04-10T13:12:05+0000", "type"=>"status", "updated_time"=>"2014-04-10T13:12:05+0000", "privacy"=>{"value"=>""}}
  29 +{"story"=>"Participabr posted a link to Intervozes's timeline.", "from"=>{"name"=>"Participabr", "category"=>"Community", "id"=>"584831918242311"}, "story_tags"=>{"0"=>[{"name"=>"Participabr", "id"=>"584831918242311", "type"=>"page", "length"=>11, "offset"=>0}], "29"=>[{"name"=>"Intervozes", "id"=>"266806120012638", "type"=>"page", "length"=>10, "offset"=>29}]}, "id"=>"584831918242311_670616066330562", "created_time"=>"2014-04-10T13:12:00+0000", "type"=>"status", "updated_time"=>"2014-04-10T13:12:00+0000", "privacy"=>{"value"=>""}}
  30 +{"story"=>"Participabr posted a link to Open Government Partnership's timeline.", "from"=>{"name"=>"Participabr", "category"=>"Community", "id"=>"584831918242311"}, "story_tags"=>{"0"=>[{"name"=>"Participabr", "id"=>"584831918242311", "type"=>"page", "length"=>11, "offset"=>0}], "29"=>[{"name"=>"Open Government Partnership", "id"=>"194822890570242", "type"=>"page", "length"=>27, "offset"=>29}]}, "id"=>"584831918242311_670616046330564", "created_time"=>"2014-04-10T13:11:58+0000", "type"=>"status", "updated_time"=>"2014-04-10T13:11:58+0000", "privacy"=>{"value"=>""}}
  31 +{"story"=>"\"Hoje sai a programa\303\247\303\243o completa com os debatedores da #ArenaNETMundial! Logo mais compartilharemos em nossa p\303\241gina e aqui no face! Um time de peso e antenado com as principais quest\303\265es sobre governan\303\247a da internet, desafios no Brasil e as novas formas de participa\303\247\303\243o pol\303\255tica que emergem com a internet! Contamos com ajuda para divulgar! http://www.participa.br/arena/arena-net-mundial/dialogos\" on Gabinete Digital's timeline.", "from"=>{"name"=>"Participabr", "category"=>"Community", "id"=>"584831918242311"}, "story_tags"=>{"401"=>[{"name"=>"Gabinete Digital", "id"=>"175059972609953", "type"=>"page", "length"=>16, "offset"=>401}]}, "id"=>"584831918242311_670615772997258", "created_time"=>"2014-04-10T13:11:00+0000", "type"=>"status", "updated_time"=>"2014-04-10T13:11:00+0000", "privacy"=>{"value"=>""}, "status_type"=>"wall_post"}
  32 +{"story"=>"\"Hoje sai a programa\303\247\303\243o completa com os debatedores da #ArenaNETMundial! Logo mais compartilharemos em nossa p\303\241gina e aqui no face! Um time de peso e antenado com as principais quest\303\265es sobre governan\303\247a da internet, desafios no Brasil e as novas formas de participa\303\247\303\243o pol\303\255tica que emergem com a internet! Contamos com ajuda para divulgar! http://www.participa.br/arena/arena-net-mundial/dialogos\" on Participat\303\263rio's timeline.", "from"=>{"name"=>"Participabr", "category"=>"Community", "id"=>"584831918242311"}, "story_tags"=>{"401"=>[{"name"=>"Participat\303\263rio", "id"=>"493847487360819", "type"=>"page", "length"=>14, "offset"=>401}]}, "id"=>"584831918242311_670615199663982", "created_time"=>"2014-04-10T13:10:06+0000", "type"=>"status", "updated_time"=>"2014-04-10T13:10:06+0000", "privacy"=>{"value"=>""}, "status_type"=>"wall_post"}
  33 +{"story"=>"\"Hoje sai a programa\303\247\303\243o completa com os debatedores da #ArenaNETMundial! Logo mais compartilharemos em nossa p\303\241gina e aqui no face! Um time de peso e antenado com as principais quest\303\265es sobre governan\303\247a da internet, desafios no Brasil e as novas formas de participa\303\247\303\243o pol\303\255tica que emergem com a internet! Contamos com ajuda para divulgar! http://www.participa.br/arena/arena-net-mundial/dialogos\" on Meu Rio's timeline.", "from"=>{"name"=>"Participabr", "category"=>"Community", "id"=>"584831918242311"}, "story_tags"=>{"401"=>[{"name"=>"Meu Rio", "id"=>"241897672509479", "type"=>"page", "length"=>7, "offset"=>401}]}, "id"=>"584831918242311_670615149663987", "created_time"=>"2014-04-10T13:09:55+0000", "type"=>"status", "updated_time"=>"2014-04-10T13:09:55+0000", "privacy"=>{"value"=>""}, "status_type"=>"wall_post"}
  34 +{"shares"=>{"count"=>18}, "actions"=>[{"name"=>"Comment", "link"=>"https://www.facebook.com/584831918242311/posts/670609036331265"}, {"name"=>"Like", "link"=>"https://www.facebook.com/584831918242311/posts/670609036331265"}], "name"=>"Dilma anunciar\303\241 \342\200\230Marco Civil mundial\342\200\231 em evento na capital paulista", "from"=>{"name"=>"Participabr", "category"=>"Community", "id"=>"584831918242311"}, "application"=>{"name"=>"Links", "id"=>"2309869772"}, "icon"=>"https://fbstatic-a.akamaihd.net/rsrc.php/v2/yD/r/aS8ecmYRys0.gif", "id"=>"584831918242311_670609036331265", "created_time"=>"2014-04-10T12:47:11+0000", "type"=>"link", "caption"=>"blogs.estadao.com.br", "updated_time"=>"2014-04-10T12:47:11+0000", "privacy"=>{"value"=>""}, "description"=>"Presidente abrir\303\241 o NETmundial, evento internacional de governan\303\247a da internet, com o an\303\272ncio do texto que contar\303\241 com princ\303\255pios da internet", "link"=>"http://blogs.estadao.com.br/link/dilma-anunciara-marco-civil-mundial-em-evento-na-capital-paulista/", "status_type"=>"shared_story", "message"=>"Texto que ir\303\241 para a NETmundial, que acontece em S\303\243o Paulo neste m\303\252s, foi vazado pelo Wikileaks e d\303\241 princ\303\255pios para governan\303\247a e uso da internet\n\nJ\303\241 confirmou presen\303\247a no evento? Ent\303\243o n\303\243o perca tempo! http://bit.ly/ArenaNETmundial", "likes"=>{"data"=>[{"name"=>"Robson B. Sampaio", "id"=>"100000664962544"}, {"name"=>"Luiz Augusto Lisb\303\264a", "id"=>"100002956996510"}, {"name"=>"Celia Maria Rodrigues Silva", "id"=>"100001451747299"}, {"name"=>"Vinicius Russo", "id"=>"1058306283"}, {"name"=>"Uir\303\241 Por\303\243 Maia Do Carmo", "id"=>"582803802"}, {"name"=>"Marcelo Branco", "id"=>"1260145727"}, {"name"=>"Laura De Castro", "id"=>"662017885"}, {"name"=>"Janaina Spode", "id"=>"579251019"}, {"name"=>"Lorac Mustaine", "id"=>"1083326546"}, {"name"=>"Adriana Martorano Comunica\303\247\303\243o", "id"=>"453793871359065"}, {"name"=>"Rosely Arantes", "id"=>"100002116761841"}, {"name"=>"Alex Garcia", "id"=>"100001852385999"}, {"name"=>"Daniel Astone", "id"=>"100000127763008"}, {"name"=>"Carlos Lobo", "id"=>"763893285"}, {"name"=>"Henrique Parra Parra Filho", "id"=>"100000747904691"}, {"name"=>"Myrian Conor", "id"=>"100000262033394"}, {"name"=>"Natascha Castro", "id"=>"1792307671"}], "paging"=>{"cursors"=>{"after"=>"MTc5MjMwNzY3MQ==", "before"=>"MTAwMDAwNjY0OTYyNTQ0"}}}, "picture"=>"https://fbexternal-a.akamaihd.net/safe_image.php?d=AQBeW57V3bbvkwYZ&w=154&h=154&url=http%3A%2F%2Fblogs.estadao.com.br%2Flink%2Ffiles%2F2014%2F02%2FDilma630.jpg"}
  35 +{"story"=>"\";) Agora \303\251 a hora de...\" on their own photo.", "from"=>{"name"=>"Participabr", "category"=>"Community", "id"=>"584831918242311"}, "application"=>{"name"=>"Photos", "id"=>"2305272732"}, "id"=>"584831918242311_670606639664838", "created_time"=>"2014-04-10T12:38:21+0000", "type"=>"status", "updated_time"=>"2014-04-10T12:38:21+0000", "privacy"=>{"value"=>""}}
  36 +{"story"=>"Participabr likes a photo.", "from"=>{"name"=>"Participabr", "category"=>"Community", "id"=>"584831918242311"}, "story_tags"=>{"0"=>[{"name"=>"Participabr", "id"=>"584831918242311", "type"=>"page", "length"=>11, "offset"=>0}]}, "id"=>"584831918242311_670606496331519", "created_time"=>"2014-04-10T12:37:45+0000", "type"=>"status", "updated_time"=>"2014-04-10T12:37:45+0000", "privacy"=>{"value"=>""}}
  37 +{"shares"=>{"count"=>4}, "actions"=>[{"name"=>"Comment", "link"=>"https://www.facebook.com/584831918242311/posts/670587879666714"}, {"name"=>"Like", "link"=>"https://www.facebook.com/584831918242311/posts/670587879666714"}], "comments"=>{"data"=>[{"like_count"=>1, "user_likes"=>false, "can_remove"=>false, "from"=>{"name"=>"Participabr", "category"=>"Community", "id"=>"584831918242311"}, "id"=>"670251893033646_2154947", "created_time"=>"2014-04-10T12:38:21+0000", "message"=>";) Agora \303\251 a hora de aproveitarmos os bons ventos e impulsionar uma #Arena transformadora!!"}], "paging"=>{"cursors"=>{"after"=>"MQ==", "before"=>"MQ=="}}}, "from"=>{"name"=>"Participabr", "category"=>"Community", "id"=>"584831918242311"}, "icon"=>"https://fbstatic-a.akamaihd.net/rsrc.php/v2/yz/r/StEh3RhPvjk.gif", "id"=>"584831918242311_670587879666714", "created_time"=>"2014-04-10T11:30:00+0000", "type"=>"photo", "updated_time"=>"2014-04-10T12:38:21+0000", "privacy"=>{"value"=>""}, "link"=>"https://www.facebook.com/photo.php?fbid=670251893033646&set=a.611370448921791.1073741828.584831918242311&type=1&relevant_count=1", "object_id"=>"670251893033646", "status_type"=>"added_photos", "message"=>"BOM DIA pra voc\303\252 que nos acompanha! \n\nO futuro da INTERNET est\303\241 em nossas m\303\243os e \303\251 nossa responsabilidade lutar por uma rede LIVRE, COLABORATIVA e PLURAL! \n\nVenha debater a governan\303\247a da rede e vamos, juntos, construir a internet que queremos! \n\nConfirma presen\303\247a l\303\241! http://bit.ly/ArenaNETmundial\n\n#ArenaNETmundial #ParticipaBR", "likes"=>{"data"=>[{"name"=>"Murutinga Abaetetuba Murutinga", "id"=>"100008004282653"}, {"name"=>"Robson B. Sampaio", "id"=>"100000664962544"}, {"name"=>"Elly Marlley", "id"=>"100005663351771"}, {"name"=>"Nanda Barreto", "id"=>"100000525584317"}, {"name"=>"Maria Eug\303\252nia Mour\303\243o", "id"=>"1588972379"}, {"name"=>"Rosely Arantes", "id"=>"100002116761841"}, {"name"=>"Adriana Martorano Comunica\303\247\303\243o", "id"=>"453793871359065"}, {"name"=>"Janaina Spode", "id"=>"579251019"}, {"name"=>"Alexandra Peixoto", "id"=>"749059638"}, {"name"=>"Participabr", "id"=>"584831918242311"}, {"name"=>"Natascha Castro", "id"=>"1792307671"}, {"name"=>"Myrian Conor", "id"=>"100000262033394"}, {"name"=>"Henrique Parra Parra Filho", "id"=>"100000747904691"}, {"name"=>"Fernando Silva Soares Silva", "id"=>"1578450483"}], "paging"=>{"cursors"=>{"after"=>"MTU3ODQ1MDQ4Mw==", "before"=>"MTAwMDA4MDA0MjgyNjUz"}}}, "picture"=>"https://fbcdn-photos-h-a.akamaihd.net/hphotos-ak-prn1/t1.0-0/10175049_670251893033646_3173567516434002075_s.jpg"}
... ...
plugins/community_hub/lib/community_hub_plugin.rb 0 → 100644
... ... @@ -0,0 +1,30 @@
  1 +class CommunityHubPlugin < Noosfero::Plugin
  2 +
  3 + def self.plugin_name
  4 + 'Community Hub'
  5 + end
  6 +
  7 + def self.plugin_description
  8 + _("New kind of content for communities.")
  9 + end
  10 +
  11 + def stylesheet?
  12 + true
  13 + end
  14 +
  15 + def content_types
  16 + if context.respond_to?(:params) && context.params
  17 + types = []
  18 + parent_id = context.params[:parent_id]
  19 + types << CommunityHubPlugin::Hub if context.profile.community? && !parent_id
  20 + types
  21 + else
  22 + [CommunityHubPlugin::Hub]
  23 + end
  24 + end
  25 +
  26 + def content_remove_new(page)
  27 + page.kind_of?(CommunityHubPlugin::Hub)
  28 + end
  29 +
  30 +end
... ...
plugins/community_hub/lib/community_hub_plugin/hub.rb 0 → 100644
... ... @@ -0,0 +1,51 @@
  1 +require File.dirname(__FILE__) + '/../../twitter/stream.rb'
  2 +require File.dirname(__FILE__) + '/../../facebook_stream/lib_facebook_stream'
  3 +
  4 +class CommunityHubPlugin::Hub < Folder
  5 +
  6 + settings_items :twitter_enabled, :type => :boolean, :default => false
  7 + settings_items :twitter_hashtags, :type => :string, :default => ""
  8 + settings_items :twitter_consumer_key, :type => :string, :default => ""
  9 + settings_items :twitter_consumer_secret, :type => :string, :default => ""
  10 + settings_items :twitter_access_token, :type => :string, :default => ""
  11 + settings_items :twitter_access_token_secret, :type => :string, :default => ""
  12 + settings_items :facebook_enabled, :type => :boolean, :default => false
  13 + settings_items :facebook_page_id, :type => :string, :default => ""
  14 + settings_items :facebook_pooling_time, :type => :integer, :default => 5 # Time in seconds
  15 + settings_items :facebook_access_token, :type => :string, :default => ''
  16 + settings_items :pinned_messages, :type => Array, :default => []
  17 + settings_items :pinned_mediations, :type => Array, :default => []
  18 + settings_items :mediators, :type => Array, :default => []
  19 +
  20 + before_create do |hub|
  21 + hub.mediators = [hub.author.id]
  22 + end
  23 +
  24 + def notify_comments
  25 + false
  26 + end
  27 +
  28 + def self.icon_name(article = nil)
  29 + 'community-hub'
  30 + end
  31 +
  32 + def self.short_description
  33 + _("Hub")
  34 + end
  35 +
  36 + def self.description
  37 + _('Defines a hub.')
  38 + end
  39 +
  40 + def accept_comments?
  41 + true
  42 + end
  43 +
  44 + def view_page
  45 + "content_viewer/hub.rhtml"
  46 + end
  47 +
  48 + def mediator?(user)
  49 + self.author.id == user.id || self.mediators.include?(user.id) ? true : false
  50 + end
  51 +end
... ...
plugins/community_hub/lib/community_hub_plugin/hub_helper.rb 0 → 100644
... ... @@ -0,0 +1,23 @@
  1 +module CommunityHubPlugin::HubHelper
  2 +
  3 + def mediator?(hub)
  4 + logged_in? && (hub.author.id == user.id || hub.mediators.include?(user.id)) ? true : false
  5 + end
  6 +
  7 + def promoted?(hub, user_id)
  8 + logged_in? && (hub.author.id == user_id || hub.mediators.include?(user_id)) ? true : false
  9 + end
  10 +
  11 + def pinned_message?(hub, message_id)
  12 + hub.pinned_messages.include?(message_id) ? true : false
  13 + end
  14 +
  15 + def pinned_mediation?(hub, mediation_id)
  16 + hub.pinned_mediations.include?(mediation_id) ? true : false
  17 + end
  18 +
  19 + def post_time(time)
  20 + _('%{hour}:%{minutes}') % { :hour => time.hour, :minutes => time.strftime("%M") } rescue ''
  21 + end
  22 +
  23 +end
... ...
plugins/community_hub/lib/community_hub_plugin/listener.rb 0 → 100644
... ... @@ -0,0 +1,49 @@
  1 +require 'ftools'
  2 +
  3 +class CommunityHubPlugin::Listener
  4 +
  5 + class << self
  6 +
  7 + def twitter_service(hub)
  8 + listen_twitter_stream(hub, nil)
  9 + end
  10 +
  11 + def facebook_service(hub)
  12 + facebook_comments(hub, nil, hub.facebook_page_id, hub.facebook_pooling_time, hub.facebook_access_token, hub.proxy_url)
  13 + end
  14 +
  15 + def run
  16 + hubs = {}
  17 + loop do
  18 + log "searching for hubs"
  19 + CommunityHubPlugin::Hub.all.each do |hub|
  20 + hub_conf = hubs[hub.id]
  21 + if hub_conf.nil? || hub_conf[:hub].updated_at < hub.updated_at
  22 + hub_conf[:threads].each {|t| t.terminate} if hub_conf
  23 + log "hub #{hub.id} found!!!!!!"
  24 + threads = []
  25 + threads << Thread.new { twitter_service(hub) } if hub.twitter_enabled
  26 + threads << Thread.new { facebook_service(hub) } if hub.facebook_enabled
  27 + hubs[hub.id] = {:threads => threads, :hub => hub}
  28 + end
  29 + end
  30 + sleep(10)
  31 + end
  32 + end
  33 +
  34 + def initialize_logger
  35 + logdir = File.join(RAILS_ROOT, 'log', CommunityHubPlugin::Listener.name.underscore)
  36 + File.makedirs(logdir) if !File.exist?(logdir)
  37 + logpath = File.join(logdir, "#{ENV['RAILS_ENV']}_#{Time.now.strftime('%F')}.log")
  38 + @logger = Logger.new(logpath)
  39 + end
  40 +
  41 + def log(message)
  42 + initialize_logger unless @initiated
  43 + @initiated ||= true
  44 + @logger << "[#{Time.now.strftime('%F %T %z')}] #{message}\n"
  45 + end
  46 +
  47 + end
  48 +
  49 +end
... ...
plugins/community_hub/lib/community_hub_plugin/mediation.rb 0 → 100644
... ... @@ -0,0 +1,15 @@
  1 +class CommunityHubPlugin::Mediation < Article
  2 +
  3 + before_save do |mediation|
  4 + mediation.advertise = false
  5 + mediation.notify_comments = false
  6 + nil
  7 + end
  8 +
  9 + settings_items :profile_picture, :type => :string, :default => ""
  10 +
  11 + def self.timestamp
  12 + "hub-mediation-#{(Time.now.to_f * 1000).to_i}"
  13 + end
  14 +
  15 +end
... ...
plugins/community_hub/lib/ext/comment.rb 0 → 100644
... ... @@ -0,0 +1,5 @@
  1 +require_dependency 'comment'
  2 +
  3 +class Comment
  4 + settings_items :profile_picture, :type => :string, :default => ""
  5 +end
... ...
plugins/community_hub/public/icons/community-hub.png 0 → 100644

442 Bytes

plugins/community_hub/public/icons/hub-arrow-right.png 0 → 100644

349 Bytes

plugins/community_hub/public/icons/hub-not-pinned-icon.png 0 → 100644

772 Bytes

plugins/community_hub/public/icons/hub-not-promote-icon.png 0 → 100644

674 Bytes

plugins/community_hub/public/icons/hub-pinned-icon.png 0 → 100644

772 Bytes

plugins/community_hub/public/icons/hub-promote-icon.png 0 → 100644

674 Bytes

plugins/community_hub/public/icons/hub-remove-icon.png 0 → 100644

567 Bytes

plugins/community_hub/public/icons/hub-samarelo-a.png 0 → 100644

424 Bytes

plugins/community_hub/public/icons/hub-samarelo-b.png 0 → 100644

426 Bytes

plugins/community_hub/public/icons/hub-samarelo.gif 0 → 100644

357 Bytes

plugins/community_hub/public/icons/hub-sverde-a.png 0 → 100644

438 Bytes

plugins/community_hub/public/icons/hub-sverde-b.png 0 → 100644

438 Bytes

plugins/community_hub/public/icons/hub-svermelho-a.png 0 → 100644

373 Bytes

plugins/community_hub/public/icons/hub-svermelho-b.png 0 → 100644

374 Bytes

plugins/community_hub/public/icons/hub-time-bg.gif 0 → 100644

807 Bytes

plugins/community_hub/public/icons/logo_facebook_50x50.png 0 → 100644

905 Bytes

plugins/community_hub/public/icons/logo_twitter_50x50.png 0 → 100644

1.73 KB

plugins/community_hub/public/icons/logo_twitter_bird_blue_50x50.png 0 → 100644

1.08 KB

plugins/community_hub/public/icons/logo_twitter_bird_white_50x50.png 0 → 100644

1.02 KB

plugins/community_hub/public/javascripts/community_hub.js 0 → 100644
... ... @@ -0,0 +1,372 @@
  1 +var latest_post_id = 0;
  2 +var oldest_post_id = 0;
  3 +live_scroll_position = 0;
  4 +var mediations = [];
  5 +var message_interval_id;
  6 +
  7 +function load_more(tab) {
  8 + switch (tab) {
  9 + case 'live':
  10 + load_more_messages();
  11 + break;
  12 + }
  13 +}
  14 +
  15 +
  16 +function load_more_messages() {
  17 + var hub_id = jQuery(".hub").attr('id');
  18 + var oldest_id = jQuery("#live-posts li.post").last().attr("id");
  19 +
  20 + jQuery.ajax({
  21 + url: '/plugin/community_hub/public/older_comments',
  22 + type: 'get',
  23 + data: { oldest_id: oldest_id, hub: hub_id },
  24 + success: function(data) {
  25 + if (data.trim().length > 0) {
  26 + jQuery("#live-posts").append(data);
  27 + }
  28 + },
  29 + error: function(ajax, stat, errorThrown) {
  30 + }
  31 + });
  32 +}
  33 +
  34 +
  35 +function validate_textarea(txt) {
  36 + return (txt.search(/[^\n\s]/)!=-1);
  37 +}
  38 +
  39 +
  40 +function toogle_mediation_comments(mediation) {
  41 + jQuery("#mediation-comment-list-" + mediation ).toggle();
  42 + jQuery("#mediation-comment-form-" + mediation ).toggle();
  43 +}
  44 +
  45 +
  46 +function new_mediation_comment(button, mediation) {
  47 +
  48 + if (!validate_textarea(jQuery("#mediation-comment-form-" + mediation + " textarea").val())) {
  49 + return false;
  50 + }
  51 +
  52 + for (var i = 0; i < mediations.length; i++) {
  53 + mediation_id = mediations[i][0];
  54 + if (mediation_id == mediation) {
  55 + interval_id = mediations[i][1];
  56 + clearInterval( interval_id );
  57 + break;
  58 + }
  59 +
  60 + }
  61 +
  62 + mediations.splice(i, 1);
  63 +
  64 + var form = jQuery(button).parents("form");
  65 +
  66 + jQuery("#mediation-comment-form-" + mediation + " .submit").attr("disabled", true);
  67 +
  68 + jQuery("body").addClass("hub-loading");
  69 +
  70 + jQuery.post(form.attr("action"), form.serialize(), function(data) {
  71 + jQuery("body").removeClass("hub-loading");
  72 + if (data.ok) {
  73 + jQuery("#mediation-comment-form-" + mediation + " textarea").val('');
  74 + jQuery("#mediation-comment-form-" + mediation + " .submit").attr("disabled", false);
  75 + update_mediation_comments(mediation, false);
  76 + mediations.push( [ mediation, setInterval(function() { update_mediation_comments(mediation, false)}, 5000) ] );
  77 + }
  78 + else {
  79 + jQuery("#mediation-comment-form-" + mediation + " .submit").attr("disabled", false);
  80 + mediations.push( [ mediation, setInterval(function() { update_mediation_comments(mediation, false)}, 5000) ] );
  81 + }
  82 + }, 'json');
  83 +
  84 +}
  85 +
  86 +
  87 +function new_message(button) {
  88 +
  89 + if (!validate_textarea(jQuery(".hub .form-message #message_body").val())) {
  90 + return false;
  91 + }
  92 +
  93 + clearInterval( message_interval_id );
  94 +
  95 + var form = jQuery(button).parents("form");
  96 +
  97 + jQuery(".hub .form-message .submit").attr("disabled", true);
  98 +
  99 + jQuery("body").addClass("hub-loading");
  100 +
  101 + jQuery.post(form.attr("action"), form.serialize(), function(data) {
  102 + jQuery("body").removeClass("hub-loading");
  103 + if (data.ok) {
  104 + jQuery(".hub .form-message #message_body").val('');
  105 + jQuery(".hub .form-message .submit").attr("disabled", false);
  106 + update_live_stream(false);
  107 + message_interval_id = setInterval(function() { update_live_stream(false)}, 5000);
  108 + }
  109 + else {
  110 + jQuery(".hub .form-message .submit").attr("disabled", false);
  111 + message_interval_id = setInterval(function() { update_live_stream(false)}, 5000);
  112 + }
  113 + }, 'json');
  114 +
  115 +}
  116 +
  117 +
  118 +function new_mediation(button) {
  119 +
  120 + if (!validate_textarea(tinymce.get('article_body').getContent(''))) {
  121 + return false;
  122 + }
  123 +
  124 + var form = jQuery(button).parents("form");
  125 +
  126 + jQuery(".hub .form-mediation .submit").attr("disabled", true);
  127 +
  128 + jQuery("body").addClass("hub-loading");
  129 +
  130 + tinymce.triggerSave();
  131 + jQuery.post(form.attr("action"), form.serialize(), function(data) {
  132 + jQuery("body").removeClass("hub-loading");
  133 + if (data.ok) {
  134 + jQuery(".hub .form-mediation .submit").attr("disabled", false);
  135 + tinymce.get('article_body').setContent('');
  136 + update_mediations();
  137 + }
  138 + else {
  139 + jQuery(".hub .form-mediation .submit").attr("disabled", false);
  140 + }
  141 + }, 'json');
  142 +
  143 +}
  144 +
  145 +
  146 +function promote_user(mediation, user_id) {
  147 +
  148 + if (confirm(DEFAULT_PROMOTE_QUESTION)) {
  149 +
  150 + var hub_id = jQuery(".hub").attr('id');
  151 +
  152 + jQuery.ajax({
  153 + url: '/plugin/community_hub/public/promote_user',
  154 + type: 'get',
  155 + dataType: 'json',
  156 + data: { user: user_id, hub: hub_id },
  157 + success: function(data) {
  158 + jQuery(".promote a").filter("#" + mediation).replaceWith( '<img class="promoted" src="/plugins/community_hub/icons/hub-not-promote-icon.png" title="User promoted">' );
  159 + },
  160 + error: function(ajax, stat, errorThrown) {
  161 + }
  162 + });
  163 +
  164 + }
  165 +
  166 +}
  167 +
  168 +
  169 +function pin_message(post_id) {
  170 +
  171 + if (confirm(DEFAULT_PIN_QUESTION)) {
  172 +
  173 + var hub_id = jQuery(".hub").attr('id');
  174 +
  175 + jQuery.ajax({
  176 + url: '/plugin/community_hub/public/pin_message',
  177 + type: 'get',
  178 + dataType: 'json',
  179 + data: { message: post_id, hub: hub_id },
  180 + success: function(data) {
  181 + jQuery(".pin a").filter("#" + post_id).replaceWith( '<img class="pinned" src="/plugins/community_hub/icons/hub-not-pinned-icon.png" title="Message pinned">' );
  182 + },
  183 + error: function(ajax, stat, errorThrown) {
  184 + }
  185 + });
  186 +
  187 + }
  188 +
  189 +}
  190 +
  191 +
  192 +function update_mediation_comments(mediation, recursive) {
  193 +
  194 + if (jQuery("#right-tab.show").size() != 0) {
  195 +
  196 + if (jQuery(".hub #mediation-comment-list-" + mediation).css('display') != "none") {
  197 +
  198 + var hub_id = jQuery(".hub").attr('id');
  199 +
  200 + if (jQuery("#mediation-comment-list-" + mediation + " li").first().length == 0) {
  201 + var latest_post_id = 0;
  202 + }
  203 + else {
  204 + var latest_post_id = jQuery("#mediation-comment-list-" + mediation + " li.mediation-comment").last().attr('id');
  205 + }
  206 +
  207 + jQuery.ajax({
  208 + url: '/plugin/community_hub/public/newer_mediation_comment',
  209 + type: 'get',
  210 + data: { latest_post: latest_post_id, mediation: mediation },
  211 + success: function(data) {
  212 + if (data.trim().length > 0) {
  213 + jQuery("#mediation-comment-list-" + mediation + "").append(data);
  214 + jQuery("#mediation-comment-total-" + mediation).html(jQuery("#mediation-comment-list-" + mediation + " li.mediation-comment").size());
  215 + }
  216 + },
  217 + error: function(ajax, stat, errorThrown) {
  218 + }
  219 + });
  220 +
  221 + }
  222 +
  223 + }
  224 +
  225 + if (recursive) {
  226 + setTimeout(function() {
  227 + update_mediation_comments(mediation, true);
  228 + }, 5000);
  229 + }
  230 +}
  231 +
  232 +
  233 +function update_mediations() {
  234 +
  235 + if (jQuery("#right-tab.show").size() != 0) {
  236 +
  237 + var hub_id = jQuery(".hub").attr('id');
  238 +
  239 + if (jQuery("#mediation-posts li").first().length == 0) {
  240 + var latest_post_id = 0;
  241 + }
  242 + else {
  243 + var latest_post_id = jQuery("#mediation-posts li").first().attr('id');
  244 + }
  245 +
  246 + jQuery.ajax({
  247 + url: '/plugin/community_hub/public/newer_articles',
  248 + type: 'get',
  249 + data: { latest_post: latest_post_id, hub: hub_id },
  250 + success: function(data) {
  251 + jQuery("body").removeClass("hub-loading");
  252 + if (data.trim().length > 0) {
  253 + jQuery("#mediation-posts").prepend(data);
  254 + }
  255 + },
  256 + error: function(ajax, stat, errorThrown) {
  257 + }
  258 + });
  259 +
  260 + }
  261 +
  262 + setTimeout(update_mediations, 10000);
  263 +}
  264 +
  265 +
  266 +function update_live_stream(recursive) {
  267 +
  268 + if (jQuery("#left-tab.show").size() != 0) {
  269 +
  270 + var hub_id = jQuery(".hub").attr('id');
  271 +
  272 + if (jQuery("#live-posts li").first().length == 0) {
  273 + var latest_post_id = 0;
  274 + }
  275 + else {
  276 + var latest_post_id = jQuery("#live-posts li").first().attr('id');
  277 + }
  278 +
  279 + jQuery.ajax({
  280 + url: '/plugin/community_hub/public/newer_comments',
  281 + type: 'get',
  282 + data: { latest_post: latest_post_id, hub: hub_id },
  283 + success: function(data) {
  284 + if (data.trim().length > 0) {
  285 + jQuery("#live-posts").prepend(data);
  286 + if (jQuery("#auto_scrolling").attr('checked')) {
  287 + jQuery("#live-posts").scrollTop(0);
  288 + }
  289 + else {
  290 + jQuery("#live-posts").scrollTop(live_scroll_position);
  291 + }
  292 + if (first_hub_load) {
  293 + jQuery("body").removeClass("hub-loading");
  294 + first_hub_load = false;
  295 + }
  296 + }
  297 + },
  298 + error: function(ajax, stat, errorThrown) {
  299 + }
  300 + });
  301 +
  302 + }
  303 +
  304 + if (recursive) {
  305 + setTimeout(function() {
  306 + update_live_stream(true);
  307 + }, 5000);
  308 + }
  309 +
  310 +}
  311 +
  312 +function hub_left_tab_click() {
  313 + jQuery("#right-tab").removeClass('show');
  314 + jQuery("#right-tab").addClass('hide');
  315 + jQuery("#left-tab").removeClass('hide');
  316 + jQuery("#left-tab").addClass('show');
  317 +}
  318 +
  319 +function hub_right_tab_click() {
  320 + jQuery("#left-tab").removeClass('show');
  321 + jQuery("#left-tab").addClass('hide');
  322 + jQuery("#right-tab").removeClass('hide');
  323 + jQuery("#right-tab").addClass('show');
  324 + jQuery(".hub #right-tab.show h1.live").click(hub_left_tab_click);
  325 + if (first_mediations_load) {
  326 + jQuery("body").addClass("hub-loading");
  327 + first_mediations_load = false;
  328 + update_mediations();
  329 + }
  330 +}
  331 +
  332 +first_hub_load = true;
  333 +first_mediations_load = true;
  334 +
  335 +jQuery(".hub .envelope").scroll(function() {
  336 + jQuery("#auto_scrolling").attr('checked', false);
  337 +
  338 + // live stream tab...
  339 + if (jQuery("#left-tab.show").size() != 0) {
  340 + current_envelope = jQuery(".hub .live .envelope");
  341 + current_list_posts = jQuery(".hub ul#live-posts");
  342 + tab = 'live';
  343 + }
  344 + else {
  345 + // mediation tab...
  346 + if (jQuery("#right-tab.show").size() != 0) {
  347 + current_envelope = jQuery(".hub .mediation .envelope");
  348 + current_list_posts = jQuery(".hub ul#mediation-posts");
  349 + tab = 'mediation';
  350 + }
  351 + }
  352 +
  353 + if (current_envelope.scrollTop() == (current_list_posts.height() - current_envelope.height() + 23)) {
  354 + load_more(tab);
  355 + }
  356 +
  357 +});
  358 +
  359 +
  360 +jQuery(document).ready(function() {
  361 +
  362 + jQuery("#live-posts").scroll(function() {
  363 + live_scroll_position = jQuery("#live-posts").scrollTop();
  364 + });
  365 +
  366 + jQuery(".hub #left-tab.show h1.mediation").click(hub_right_tab_click);
  367 +
  368 + jQuery("body").addClass("hub-loading");
  369 +
  370 + message_interval_id = setInterval(function() { update_live_stream(false) }, 5000);
  371 +
  372 +});
... ...
plugins/community_hub/public/style.css 0 → 100644
... ... @@ -0,0 +1,648 @@
  1 +#banner-embed-container {
  2 + width: 49%;
  3 + float: right;
  4 +}
  5 +
  6 +#input-panel {
  7 + width: 100%;
  8 + padding-top: 10px;
  9 + display: inline-block;
  10 +}
  11 +
  12 +#hub-loading {
  13 + float: right;
  14 +}
  15 +
  16 +.hub-loading {
  17 + cursor: wait;
  18 +}
  19 +
  20 +.icon-newcommunity-hub,
  21 +.icon-community-hub {
  22 + background-image: url(/plugins/community_hub/icons/community-hub.png)
  23 +}
  24 +
  25 +.hub ul {padding-left: 0px; margin-top: 0;}
  26 +
  27 +#content .hub h1{
  28 + margin-bottom: 0;
  29 +}
  30 +
  31 +#content .hub .content-tab h1{
  32 + border-color: #D71410 #CCCCCC -moz-use-text-color;
  33 + border-left: 1px solid #CCCCCC;
  34 + border-right: 1px solid #CCCCCC;
  35 + border-style: solid solid none;
  36 + border-width: 1px 1px 0;
  37 + border-top: 1px solid #D71410;
  38 +}
  39 +
  40 +#content .hub .title {
  41 + font-size: 33px;
  42 + font-weight: normal;
  43 + padding-right: 70px;
  44 + color: #4b7421;
  45 + font-variant: normal;
  46 +}
  47 +
  48 +.hub .description {
  49 + font-size: 14px;
  50 +}
  51 +
  52 +.hub .post {
  53 + border-top: 1px solid #ddd;
  54 + background: url("images/hub-time-bg.gif") repeat-y left top #fff;
  55 + padding: 5px 0;
  56 +}
  57 +
  58 +
  59 +.hub .time{
  60 + display: inline-block;
  61 + font-size: 8px;
  62 + padding-top: 10px;
  63 + text-align: center;
  64 + vertical-align: top;
  65 + width: 35px;
  66 +}
  67 +
  68 +.hub .avatar{
  69 + background-color: lightGray;
  70 + display: inline-block;
  71 + height: 43px;
  72 + margin: 0 10px;
  73 + vertical-align: top;
  74 + width: 43px;
  75 + text-align: center;
  76 +}
  77 +
  78 +.hub .avatar img{
  79 + max-height: 43px;
  80 + max-width: 43px;
  81 +}
  82 +
  83 +.hub .message {
  84 + display: inline-block;
  85 + width: 65%;
  86 + float: none;
  87 + clear: both;
  88 +}
  89 +
  90 +.hub .show .message {
  91 + width: 80%;
  92 +}
  93 +
  94 +.hub .message .author {
  95 + font-weight: bold;
  96 + display: inline-block;
  97 + margin-right: 5px;
  98 + padding-bottom: 0px;
  99 +}
  100 +
  101 +.hub .mediation-bar {
  102 + display: inline-block;
  103 + margin: 10px 0 10px 104px;
  104 + width: 83%;
  105 +}
  106 +
  107 +.hub .mediation-bar ul {}
  108 +
  109 +.hub .mediation-bar ul li {
  110 + display: inline-block;
  111 + overflow: hidden;
  112 + width: 16px;
  113 +}
  114 +
  115 +.hub .mediation-bar ul li.likes-dislikes{
  116 + overflow: visible;
  117 + text-indent: 0px;
  118 + width: auto;
  119 + vertical-align: top;
  120 +}
  121 +
  122 +.hub .mediation-bar ul li.pin {
  123 + height: 25px;
  124 + /*margin-right: 15px;*/
  125 +}
  126 +
  127 +.hub .remove{}
  128 +
  129 +.hub .mediation-bar ul li a{
  130 + text-indent: -10000px;
  131 +}
  132 +
  133 +.hub .not-promoted {
  134 + opacity: 0.5;
  135 + filter: alpha(opacity=50);
  136 +}
  137 +
  138 +.hub .pin .not-pinned {
  139 + opacity: 0.5;
  140 + filter: alpha(opacity=50);
  141 +}
  142 +
  143 +.hub .mediation-bar ul li.pin {
  144 + float: right;
  145 +}
  146 +
  147 +.hub ul.mediation-comment-list{
  148 + margin-left: 80px;
  149 + display: inline-block;
  150 + padding: 10px 0;
  151 + background-color: #fff;
  152 + margin-bottom: 10px;
  153 +}
  154 +
  155 +.hub ul.mediation-comment-list li {
  156 + margin-bottom: 2px;
  157 +}
  158 +
  159 +.hub .mediation-comment-form {
  160 + margin-left: 70px;
  161 + margin-top: 10px;
  162 +}
  163 +
  164 +.hub input.button.with-text.icon-add.submit{
  165 + display: block;
  166 +}
  167 +
  168 +.hub .live {
  169 + border: 0px solid lightGray;
  170 + display: inline-block;
  171 + float: left;
  172 + width: 49%;
  173 + margin-bottom: 2em;
  174 +}
  175 +
  176 +.hub .envelope {
  177 + height: 500px;
  178 + overflow-x: hidden;
  179 + overflow-y: scroll;
  180 + margin-top: -1px;
  181 + margin-bottom: 14px;
  182 + border: 1px solid lightgray;
  183 + /*border-bottom: 1px solid lightgray;
  184 + border-left: 1px solid lightgray;*/
  185 + /*display: inline-block;*/
  186 + width: 100%;
  187 +}
  188 +
  189 +.hub ul#live-posts, .hub ul#mediation-posts{
  190 + /*border-width: 0 1px 1px;*/
  191 + /*border-style: solid;*/
  192 + /*border-color: lightGray;*/
  193 + border-bottom: 1px solid lightgray;
  194 + padding-top: 10px;
  195 + /*clear: both;*/
  196 + /*height: 475px;*/
  197 + /*overflow-y: scroll;*/
  198 +
  199 +}
  200 +
  201 +/*modificação da scroll bar*/
  202 +.hub div.envelope::-webkit-scrollbar-button /*,
  203 +.hub ul#live-posts::-webkit-scrollbar-button,
  204 +.hub ul#mediation-posts::-webkit-scrollbar-button */ {
  205 + height: 0;
  206 + width: 0;
  207 +}
  208 +
  209 +.hub div.envelope::-webkit-scrollbar-thumb /*,
  210 +.hub ul#live-posts::-webkit-scrollbar-thumb,
  211 +.hub ul#mediation-posts::-webkit-scrollbar-thumb */ {
  212 + background-clip: padding-box;
  213 + background-color: rgba(0,0,0,.3);
  214 + border: 5px solid transparent;
  215 + border-radius: 10px;
  216 + min-height: 20px;
  217 + min-width: 20px;
  218 + height: 5px;
  219 + width: 5px;
  220 +}
  221 +
  222 +.hub div.envelope::-webkit-scrollbar /*,
  223 +.hub ul#live-posts::-webkit-scrollbar,
  224 +.hub ul#mediation-posts::-webkit-scrollbar */ {
  225 + height: 15px;
  226 + width: 15px;
  227 +}
  228 +
  229 +/*fim de modificação da scroll bar*/
  230 +
  231 +.hub #live-posts .post {
  232 + background-color:#fff;
  233 +}
  234 +
  235 +.hub ul#mediation-posts .post{
  236 + background-color:#eee;
  237 + border-color: #fff;
  238 + padding-bottom: 10px;
  239 +}
  240 +
  241 +/*novos elementos: h1.live - h1.mediation*/
  242 +#content .main-block .hub .live h1.live,
  243 +#content .main-block .hub .mediation h1.mediation {
  244 + /*background-color: #f4f4f4;*/
  245 + border: 1px solid lightGray;
  246 + border-top: 1px solid #96110D;
  247 + border-bottom: 0px solid #FFFFFF;
  248 + top: 1px;
  249 + float: left;
  250 + font-weight: normal;
  251 + margin-bottom: -1px;
  252 + position: relative;
  253 + width: 60%;
  254 +background-color: white;
  255 +z-index: 99;
  256 +}
  257 +
  258 +#content .main-block .hub .live h1.live{
  259 + float: left;
  260 + margin-right: 20px;
  261 + margin-left: 0px;
  262 +}
  263 +
  264 +#content .main-block .hub .mediation h1.mediation{
  265 + float: right;
  266 + margin-right: 0px;
  267 + margin-left: 20px;
  268 + top: 2px;
  269 + left: 2px;
  270 +}
  271 +
  272 +#content .main-block .hub .live h1.mediation,
  273 +#content .main-block .hub .mediation h1.live {
  274 + display: inline-block;
  275 + background-color: #EEEEEE;
  276 + border-bottom: 1px solid #CCCCCC;
  277 + border-top-color: #CCCCCC;
  278 + color: gray;
  279 + position: relative;
  280 + width: 30%;
  281 + text-align: center;
  282 + margin-top: 8px;
  283 + line-height: 27px;
  284 + cursor: pointer;
  285 +
  286 +}
  287 +
  288 +#content .main-block .hub .live h1.mediation {}
  289 +
  290 +#content .main-block .hub .mediation h1.live {
  291 + margin-left: 20px;
  292 + top:1px;
  293 + /*border-bottom: 0px;*/
  294 +}
  295 +
  296 +
  297 +/*fim de novos elementos: h1.live - h1.mediation*/
  298 +
  299 +
  300 +#content .hub .live .title {
  301 + color: #D71410;
  302 + display: inline-block;
  303 + font-size: 14px;
  304 + font-family: /*Arial Black, */arial, sans-serif;
  305 + padding-right: 0;
  306 + width: 70%;
  307 +}
  308 +#content .hub .live .on-air {
  309 + background-color: #96110D;
  310 + border-radius: 10px 10px 10px 10px;
  311 + color: white;
  312 + display: inline-block;
  313 + font-size: 16px;
  314 + font-weight: bold;
  315 + padding: 0 0.5em;
  316 + text-align: center;
  317 + /*text-transform: uppercase;*/
  318 + vertical-align: top;
  319 + width: 20%;
  320 +
  321 +}
  322 +#content .hub .live .off-air {
  323 + background-color: gray;
  324 + border-radius: 10px 10px 10px 10px;
  325 + color: black;
  326 + display: inline-block;
  327 + font-size: 16px;
  328 + font-weight: bold;
  329 + padding: 0 0.5em;
  330 + text-align: center;
  331 + text-transform: uppercase;
  332 + vertical-align: top;
  333 + width: 20%;
  334 +}
  335 +
  336 +/****aba live fechada****/
  337 +
  338 +
  339 +.hub .live.hide {
  340 + width: 10%;
  341 +}
  342 +
  343 +.hub .live.hide ul#live-posts{
  344 + overflow-x: visible;
  345 + overflow-y: visible;
  346 + background-color: lightGray;
  347 +}
  348 +
  349 +.hub .live.hide ul#live-posts li{
  350 + display: none;
  351 +}
  352 +
  353 +#content .hub .live.hide h1 {
  354 + text-align: center;
  355 + cursor: pointer;
  356 +}
  357 +
  358 +#content .hub .live.hide h1 .title {
  359 + display: none;
  360 +}
  361 +#content .hub .live.hide .on-air,
  362 +#content .hub .live.hide .off-air {
  363 + width: auto;
  364 +}
  365 +
  366 +/****fim aba live fechada****/
  367 +
  368 +/****aba live aberta****/
  369 +
  370 +.hub .live.show {
  371 + /*width: 85%;*/
  372 + width: 100%;
  373 +}
  374 +
  375 +.hub .live.show ul#live-posts .li{
  376 +
  377 +}
  378 +
  379 +#content .hub .live.show .on-air,
  380 +#content .hub .live.show .off-air{
  381 +float: right;
  382 +margin-right: 10px;
  383 +}
  384 +
  385 +/****fim aba mlive aberta****/
  386 +
  387 +
  388 +/**************************************/
  389 +
  390 +
  391 +.hub .mediation {
  392 + border: 0px solid lightGray;
  393 + display: inline-block;
  394 + clear: right;
  395 + float: none;
  396 + margin-left: 1%;
  397 + width: 50%;
  398 + margin-bottom: 2em;
  399 +}
  400 +
  401 +#content .main-block .hub .mediation h1{
  402 + /* background-color: #ed8e01;*/
  403 + border: 1px solid lightGray
  404 +}
  405 +
  406 +#content .hub .mediation .title {
  407 + color: gray;
  408 + display: inline-block;
  409 + font-size: 14px;
  410 + font-family: Arial, sans-serif;
  411 + padding-right: 0;
  412 + /* width: 100%;*/
  413 +}
  414 +.hub .mediation .expand {
  415 + float: right;
  416 + padding-right: 1em;
  417 +}
  418 +
  419 +/****aba mediation fechada****/
  420 +
  421 +.hub .mediation.hide {
  422 + border: 0px solid lightGray;
  423 + display: inline-block;
  424 + clear: right;
  425 + float: none;
  426 + margin-left: 1%;
  427 + width: 10%;
  428 + margin-bottom: 0em;
  429 +}
  430 +
  431 +#content .main-block .hub .mediation.hide h1{
  432 +/*
  433 + background-color: #ed8e01;
  434 + border: 1px solid lightGray;
  435 + text-align: center;
  436 + padding-left: 0;
  437 +*/
  438 + cursor: pointer;
  439 +}
  440 +
  441 +#content .hub .mediation.hide .title {
  442 +/* color: white;*/
  443 + display: inline-block;
  444 + font-size: 14px;
  445 + font-family: /*Arial Black, */arial, sans-serif;
  446 + padding-right: 0;
  447 + width: 100%;
  448 +}
  449 +.hub .mediation.hide .expand {
  450 + display: none;
  451 +}
  452 +
  453 +
  454 +.hub .mediation.hide ul#mediation-posts {
  455 +height: 500px;
  456 +overflow-x: visible;
  457 +overflow-y: visible;
  458 +border-width: 0 1px 1px;
  459 +border-style: solid;
  460 +border-color: lightGray;
  461 +padding-top: 10px;
  462 +background-color: lightgray;
  463 +}
  464 +
  465 +.hub .mediation.hide ul#mediation-posts li{
  466 +display: none;
  467 +}
  468 +
  469 +/****fim aba mediation fechada****/
  470 +
  471 +/****aba mediation aberta****/
  472 +
  473 +.hub .mediation.show {
  474 +/* border: 0px solid lightGray;
  475 + display: inline-block;
  476 + clear: right;
  477 + float: none;
  478 + margin-left: 1%;
  479 + margin-bottom: 2em;
  480 +*/
  481 + /*width: 85%;*/
  482 + width: 100%;
  483 +}
  484 +
  485 +#content .main-block .hub .mediation.show h1{
  486 +/* background-color: #ed8e01;*/
  487 +/* border: 1px solid lightGray*/
  488 +}
  489 +
  490 +#content .hub .mediation.show .title {
  491 + /*color: white;*/
  492 + display: inline-block;
  493 +/* font-size: 20px;*/
  494 + font-family: /*Arial Black, */arial, sans-serif;
  495 + padding-right: 0;
  496 +/* width: 60%;*/
  497 +}
  498 +
  499 +/*
  500 +.hub .mediation.show .expand {
  501 + float: right;
  502 + padding-right: 1em;
  503 + display: block;
  504 +}*/
  505 +
  506 +
  507 +.hub .mediation.show ul#mediation-posts {
  508 +/*
  509 + height: 500px;
  510 + overflow-x: hidden;
  511 + overflow-y: scroll;
  512 + border-width: 0 1px 1px;
  513 + border-style: solid;
  514 + border-color: lightGray;
  515 + padding-top: 10px;
  516 + background-color: #f9f9f9;
  517 +*/
  518 +}
  519 +
  520 +.hub .mediation.show ul#mediation-posts li{
  521 +
  522 +}
  523 +
  524 +/****fim aba mediation aberta****/
  525 +
  526 +.hub .mediation.hide,
  527 +.hub .live.hide {
  528 + display: none;
  529 + visibility: hidden;
  530 +}
  531 +
  532 +.hub .mediation.show,
  533 +.hub .live.show {
  534 + display: inline-block;
  535 + visibility: visible;
  536 +}
  537 +
  538 +.hub .form-mediation {
  539 + /*width: 93%;*/
  540 + /*width: 426px;*/
  541 + width: 60%;
  542 + display: inline-block;
  543 + /*height: 376px;*/
  544 + padding: 10px;
  545 + border: 1px solid #c0c0c0;
  546 + overflow-x: hidden;
  547 +}
  548 +
  549 +.hub .form-message {
  550 + height: 148px;
  551 + padding: 10px;
  552 + border: 1px solid #c0c0c0;
  553 +}
  554 +
  555 +
  556 +.hub div.settings {
  557 + /*width: 96%;*/
  558 + /*margin-top: 10px;*/
  559 + /*margin-left: 10px;*/
  560 + /*width: 240px;*/
  561 + display: inline-block;
  562 + margin-left: 1%;
  563 + margin-top: 10px;
  564 + vertical-align: top;
  565 + width: 35%;
  566 +}
  567 +
  568 +.hub ul.settings li {
  569 + height: 50px;
  570 + line-height: 50px;
  571 + margin-bottom: 10px;
  572 + padding: 0 10px;
  573 + background: url("images/hub-arrow-right.png") no-repeat 90% top #ed8e01;
  574 +}
  575 +
  576 +.hub ul.settings span.collapse {
  577 + padding-right: 0.5em;
  578 + float: right;
  579 +}
  580 +
  581 +.hub div.banner {
  582 + height: 70px;
  583 + background-color: #6d6d6d;
  584 + text-align: center;
  585 + padding-top: 30px;
  586 +}
  587 +
  588 +.hub div.banner span {
  589 + color: white;
  590 + font-family: Arial Black, arial, sans-serif;
  591 + font-size: large;
  592 + font-weight: normal;
  593 + display: block;
  594 +}
  595 +
  596 +.hub div.embed {
  597 + margin-top: 10px;
  598 + padding: 8px;
  599 + border: 1px solid #c0c0c0;
  600 +}
  601 +
  602 +.hub div.embed textarea.code {
  603 + background-color: #f0f0f0;
  604 + border: 1px solid #f0f0f0;
  605 + height: 195px;
  606 + resize: none;
  607 +}
  608 +
  609 +#content .hub ul.settings li a{
  610 + color: white;
  611 + font-family: Arial Black, arial, sans-serif;
  612 + font-size: large;
  613 + font-weight: normal;
  614 +}
  615 +
  616 +#content .hub ul.settings li a:hover {
  617 + text-decoration: none;
  618 +}
  619 +
  620 +#content .hub form input.button.submit {
  621 + font-family: Arial Black, arial, sans-serif;
  622 + font-size: small;
  623 + font-weight: normal;
  624 + color: #333;
  625 + margin-top: 10px;
  626 +}
  627 +
  628 +textarea#message_body {
  629 + width: auto;
  630 + margin-left: 80px;
  631 +}
  632 +
  633 +.comment-count {
  634 + margin-left: 80px;
  635 + padding: 5px 10px;
  636 + background-color: white;
  637 + display: inline-block;
  638 + border-radius: 5px;
  639 + font-weight: bold;
  640 + display: block;
  641 + margin-bottom: -5px;
  642 + margin-top: 10px;
  643 + max-width: 100px;
  644 +}
  645 +
  646 +.hub ul.mediation-comment-list {
  647 + width: 80%;
  648 +}
... ...
plugins/community_hub/script/hub_updater 0 → 100755
... ... @@ -0,0 +1,15 @@
  1 +#!/usr/bin/env ruby
  2 +
  3 +require 'daemons'
  4 +require 'optparse'
  5 +
  6 +NOOSFERO_ROOT = File.expand_path(File.dirname(__FILE__) + '/../../../')
  7 +
  8 +Daemons.run_proc('hub') do
  9 + require NOOSFERO_ROOT + '/config/environment'
  10 + unless ENV['PROXY'].blank?
  11 + ENV['NO_PROXY'] ||= 'localhost'
  12 + require 'proxifier/env'
  13 + end
  14 + CommunityHubPlugin::Listener.run
  15 +end
... ...
plugins/community_hub/test/test_helper.rb 0 → 100644
... ... @@ -0,0 +1,14 @@
  1 +require File.dirname(__FILE__) + '/../../../test/test_helper'
  2 +
  3 +def create_hub(name, community, user)
  4 + hub = CommunityHubPlugin::Hub.new(:abstract => 'abstract', :body => 'body', :name => name, :profile => community, :last_changed_by_id => user.id )
  5 + hub.save!
  6 + hub
  7 +end
  8 +
  9 +def create_mediation(hub, community)
  10 + mediation = CommunityHubPlugin::Mediation.new(:profile => community)
  11 + mediation.name = CommunityHubPlugin::Mediation.timestamp
  12 + mediation.save!
  13 + mediation
  14 +end
... ...
plugins/community_hub/test/unit/community_hub_plugin/hub_helper_test.rb 0 → 100644
... ... @@ -0,0 +1,18 @@
  1 +require File.dirname(__FILE__) + '/../../test_helper'
  2 +
  3 +class HubHelperTest < ActiveSupport::TestCase
  4 +
  5 + include CommunityHubPlugin::HubHelper
  6 + include NoosferoTestHelper
  7 +
  8 + should 'return time formated to hh:mm' do
  9 + t = Time.utc(2014,"jan",1,17,40,0)
  10 + assert_equal post_time(t), "17:40"
  11 + end
  12 +
  13 + should 'return empty string if param is not time' do
  14 + i = 1
  15 + assert_equal post_time(i), ''
  16 + end
  17 +
  18 +end
... ...
plugins/community_hub/test/unit/community_hub_plugin/hub_test.rb 0 → 100644
... ... @@ -0,0 +1,136 @@
  1 +require File.dirname(__FILE__) + '/../../test_helper'
  2 +
  3 +class HubTest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + @env = fast_create(Environment)
  7 + @user = create_user('testuser', :environment => @env).person
  8 + @comm = fast_create(Community, :environment_id => @env.id)
  9 + @hub = create_hub('hub', @comm, @user)
  10 + end
  11 +
  12 + should 'has setting twitter_enable' do
  13 + assert_respond_to @hub, :twitter_enabled
  14 + end
  15 +
  16 + should 'default value of setting twitter_enabled is false' do
  17 + assert_equal @hub.twitter_enabled, false
  18 + end
  19 +
  20 + should 'has setting twitter_hashtags' do
  21 + assert_respond_to @hub, :twitter_hashtags
  22 + end
  23 +
  24 + should 'default value of setting twitter_hashtags is blank' do
  25 + assert_equal @hub.twitter_hashtags, ""
  26 + end
  27 +
  28 + should 'has setting twitter_consumer_key' do
  29 + assert_respond_to @hub, :twitter_consumer_key
  30 + end
  31 +
  32 + should 'default value of setting twitter_consumer is blank' do
  33 + assert_equal @hub.twitter_consumer_key, ""
  34 + end
  35 +
  36 + should 'has setting twitter_consumer_secret' do
  37 + assert_respond_to @hub, :twitter_consumer_secret
  38 + end
  39 +
  40 + should 'default value of setting twitter_consumer_secret is blank' do
  41 + assert_equal @hub.twitter_consumer_secret, ""
  42 + end
  43 +
  44 + should 'has setting twitter_access_token' do
  45 + assert_respond_to @hub, :twitter_access_token
  46 + end
  47 +
  48 + should 'default value of setting twitter_access_token is blank' do
  49 + assert_equal @hub.twitter_access_token, ""
  50 + end
  51 +
  52 + should 'has setting twitter_access_token_secret' do
  53 + assert_respond_to @hub, :twitter_access_token_secret
  54 + end
  55 +
  56 + should 'default value of setting twitter_access_token_secret' do
  57 + assert_equal @hub.twitter_access_token_secret, ""
  58 + end
  59 +
  60 + should 'has setting facebook_enabled' do
  61 + assert_respond_to @hub, :facebook_enabled
  62 + end
  63 +
  64 + should 'default value of setting facebook_enabled is false' do
  65 + assert_equal @hub.facebook_enabled, false
  66 + end
  67 +
  68 + should 'has setting facebook_page_id' do
  69 + assert_respond_to @hub, :facebook_page_id
  70 + end
  71 +
  72 + should 'default value of setting facebook_page_id' do
  73 + assert_equal @hub.facebook_page_id, ""
  74 + end
  75 +
  76 + should 'has setting facebook_pooling_time' do
  77 + assert_respond_to @hub, :facebook_pooling_time
  78 + end
  79 +
  80 + should 'default value of setting facebook_pooling_time id five (5)' do
  81 + assert_equal @hub.facebook_pooling_time, 5
  82 + end
  83 +
  84 + should 'has setting facebook_access_token' do
  85 + assert_respond_to @hub, :facebook_access_token
  86 + end
  87 +
  88 + should 'default value of setting facebook_access_token is blank' do
  89 + assert_equal @hub.facebook_access_token, ""
  90 + end
  91 +
  92 + should 'has pinned_messages' do
  93 + assert_respond_to @hub, :pinned_messages
  94 + end
  95 +
  96 + should 'default value of pinned_messags' do
  97 + assert_equal @hub.pinned_messages, []
  98 + end
  99 +
  100 + should 'has pinned_mediations' do
  101 + assert_respond_to @hub, :pinned_mediations
  102 + end
  103 +
  104 + should 'default value of pinned_mediations' do
  105 + assert_equal @hub.pinned_mediations, []
  106 + end
  107 +
  108 + should 'has mediators' do
  109 + assert_respond_to @hub, :mediators
  110 + end
  111 +
  112 + should 'hub creator is mediator by default' do
  113 + assert @hub.mediators.include?(@user.id)
  114 + end
  115 +
  116 + should 'describe yourself' do
  117 + assert CommunityHubPlugin::Hub.description
  118 + end
  119 +
  120 + should 'has a short descriptionf' do
  121 + assert CommunityHubPlugin::Hub.short_description
  122 + end
  123 +
  124 + should 'accept comments by default' do
  125 + assert @hub.accept_comments?
  126 + end
  127 +
  128 + should 'do not notify comments by default' do
  129 + assert !@hub.notify_comments
  130 + end
  131 +
  132 + should 'has a view page' do
  133 + assert @hub.view_page
  134 + end
  135 +
  136 +end
... ...
plugins/community_hub/test/unit/community_hub_plugin/listener_test.rb 0 → 100644
... ... @@ -0,0 +1,31 @@
  1 +require File.dirname(__FILE__) + '/../../test_helper'
  2 +
  3 +class ListenerTest < ActiveSupport::TestCase
  4 +
  5 + should 'initialize logger' do
  6 + logger = CommunityHubPlugin::Listener.initialize_logger
  7 + logfile = logger.instance_variable_get(:@logdev).instance_variable_get(:@filename)
  8 + assert_instance_of(Logger, logger)
  9 + assert File.exists?(logfile)
  10 + end
  11 +
  12 + should 'log message' do
  13 + logdir = File.join(RAILS_ROOT, 'log', CommunityHubPlugin::Listener.name.underscore)
  14 +
  15 + if File.exists?(logdir)
  16 + Dir.foreach(logdir) { |f|
  17 + fn = File.join(logdir, f);
  18 + File.delete(fn) if f != '.' && f != '..'
  19 + }
  20 + end
  21 +
  22 + logger = CommunityHubPlugin::Listener.initialize_logger
  23 + CommunityHubPlugin::Listener.log('testmessage')
  24 +
  25 + logfile = logger.instance_variable_get(:@logdev).instance_variable_get(:@filename)
  26 + text = File.open(logfile).read
  27 +
  28 + assert_match /testmessage/, text
  29 + end
  30 +
  31 +end
... ...
plugins/community_hub/test/unit/community_hub_plugin/mediation_test.rb 0 → 100644
... ... @@ -0,0 +1,33 @@
  1 +require File.dirname(__FILE__) + '/../../test_helper'
  2 +
  3 +class MediationTest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + @env = fast_create(Environment)
  7 + @user = create_user('testuser', :environment => @env).person
  8 + @comm = fast_create(Community, :environment_id => @env.id)
  9 + @hub = create_hub('hub', @comm, @user)
  10 + @mediation = create_mediation(@hub, @comm)
  11 + end
  12 +
  13 + should 'has setting profile_picture' do
  14 + assert_respond_to @mediation, :profile_picture
  15 + end
  16 +
  17 + should 'default value of setting profile_picture is blank' do
  18 + assert_equal @mediation.profile_picture, ""
  19 + end
  20 +
  21 + should 'generate timestamp for mediation' do
  22 + assert CommunityHubPlugin::Mediation.timestamp
  23 + end
  24 +
  25 + should 'default value of advertise is false' do
  26 + assert !@mediation.advertise
  27 + end
  28 +
  29 + should 'default value of notify comments is false' do
  30 + assert !@mediation.notify_comments
  31 + end
  32 +
  33 +end
... ...
plugins/community_hub/test/unit/community_hub_plugin_test.rb 0 → 100644
... ... @@ -0,0 +1,49 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class CommunityHubPluginTest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + @plugin = CommunityHubPlugin.new
  7 + @profile = fast_create(Community)
  8 + @params = {}
  9 + @plugin.stubs(:context).returns(self)
  10 + end
  11 +
  12 + attr_reader :profile, :params
  13 +
  14 + should 'has name' do
  15 + assert CommunityHubPlugin.plugin_name
  16 + end
  17 +
  18 + should 'describe yourself' do
  19 + assert CommunityHubPlugin.plugin_description
  20 + end
  21 +
  22 + should 'has stylesheet' do
  23 + assert @plugin.stylesheet?
  24 + end
  25 +
  26 + should 'return Hub as a content type if profile is a community' do
  27 + assert_includes @plugin.content_types, CommunityHubPlugin::Hub
  28 + end
  29 +
  30 + should 'do not return Hub as a content type if profile is not a community' do
  31 + @profile = Organization.new
  32 + assert_not_includes @plugin.content_types, CommunityHubPlugin::Hub
  33 + end
  34 +
  35 + should 'do not return Hub as a content type if there is a parent' do
  36 + parent = fast_create(Blog, :profile_id => @profile.id)
  37 + @params[:parent_id] = parent.id
  38 + assert_not_includes @plugin.content_types, CommunityHubPlugin::Hub
  39 + end
  40 +
  41 + should 'return true at content_remove_new if page is a Hub' do
  42 + assert @plugin.content_remove_new(CommunityHubPlugin::Hub.new)
  43 + end
  44 +
  45 + should 'return false at content_remove_new if page is not a Hub' do
  46 + assert !@plugin.content_remove_new(Article.new)
  47 + end
  48 +
  49 +end
... ...
plugins/community_hub/twitter/stream.rb 0 → 100644
... ... @@ -0,0 +1,65 @@
  1 +require 'rubygems'
  2 +require 'twitter'
  3 +require 'iconv'
  4 +
  5 +#Filters non-UTF8 octets
  6 +def UTF8Filter(string)
  7 + ic = Iconv.new('UTF-8//IGNORE', 'UTF-8')
  8 + #Attention please, don't remove + ' ')[0..-2] it is used for UTF8 validation
  9 + ic.iconv(string + ' ')[0..-2]
  10 +end
  11 +
  12 +def listen_twitter_stream(hub, author_id)
  13 +
  14 + connected = false
  15 + tries = 0
  16 + while !connected
  17 + begin
  18 + tries += 1
  19 + client = Twitter::Streaming::Client.new do |config|
  20 + config.consumer_key = hub.twitter_consumer_key
  21 + config.consumer_secret = hub.twitter_consumer_secret
  22 + config.access_token = hub.twitter_access_token
  23 + config.access_token_secret = hub.twitter_access_token_secret
  24 + end
  25 + puts client.inspect
  26 + connected = true
  27 + tries = 0
  28 + rescue => e
  29 + puts "Error connecting to twitter stream: #{e.inspect}"
  30 + sleep (10 + 2 ** tries)
  31 + end
  32 + end
  33 +
  34 + tries = 0
  35 + while true
  36 + begin
  37 + tries += 1
  38 + client.filter(:track => hub.twitter_hashtags) do |object|
  39 + if object.is_a?(Twitter::Tweet)
  40 +# puts '@' + object.user.screen_name + ' said: ' + object.text
  41 +# puts object.user.profile_image_url
  42 + comment = Comment.new
  43 + comment.title = 'hub-message-twitter'
  44 + comment.source = hub
  45 + comment.body = UTF8Filter(object.text)
  46 + comment.profile_picture = object.user.profile_image_url.to_s
  47 + comment.author_id = author_id
  48 + comment.name = UTF8Filter(object.user.screen_name)
  49 + comment.email = 'admin@localhost.local'
  50 +
  51 + tries = 0
  52 + begin
  53 + comment.save!
  54 + rescue => e
  55 + puts "Erro gravando comentário twitter #{e.inspect}"
  56 + end
  57 + end
  58 + end
  59 + rescue => e
  60 + puts "Erro lendo stream #{e.inspect}"
  61 + sleep (10 + 2 ** tries)
  62 + break
  63 + end
  64 + end
  65 +end
... ...
plugins/community_hub/views/cms/community_hub_plugin/_hub.rhtml 0 → 100644
... ... @@ -0,0 +1,37 @@
  1 +<div class='hub'>
  2 + <h1><%= _("HUB Settings:") %></h1>
  3 + <%= required_fields_message %>
  4 + <div>
  5 + <%= required labelled_form_field(_('Title'), text_field(:article, 'name', :size => '64', :maxlength => 150)) %>
  6 + </div>
  7 + <div>
  8 + <%= render :file => 'shared/tiny_mce' %>
  9 + <%= required labelled_form_field(_('Description'), text_area(:article, 'body', :style => 'width: 100%;', :class => 'mceEditor')) %>
  10 + </div>
  11 + <br />
  12 + <div>
  13 + <%= _('General Streaming Settings:') %>
  14 + </div>
  15 + <br />
  16 + <div>
  17 + <%= _('Twitter Settings:') %>
  18 + </div>
  19 + <br />
  20 + <%= check_box(:article, :twitter_enabled) %> <span><%= _("Turn on TWITTER") %></span>
  21 + <br />
  22 + <br />
  23 + <span><%= required labelled_form_field(_('Twitter\'s Hashtags, comma separated words<br>(example: participa.br,participabr,arenanetmundial,netmundial'), text_field(:article, :twitter_hashtags)) %></span>
  24 + <br />
  25 + <br />
  26 + <span><%= required labelled_form_field(_('Twitter\'s consumer key'), text_field(:article, :twitter_consumer_key)) %></span>
  27 + <br />
  28 + <br />
  29 + <span><%= required labelled_form_field(_('Twitter\'s consumer secret'), text_field(:article, :twitter_consumer_secret)) %></span>
  30 + <br />
  31 + <br />
  32 + <span><%= required labelled_form_field(_('Twitter\'s access token'), text_field(:article, :twitter_access_token)) %></span>
  33 + <br />
  34 + <br />
  35 + <span><%= required labelled_form_field(_('Twitter\'s access token secret'), text_field(:article, :twitter_access_token_secret)) %></span>
  36 + <br />
  37 +</div>
... ...
plugins/community_hub/views/community_hub_plugin_public/_banner.rhtml 0 → 100644
... ... @@ -0,0 +1,3 @@
  1 +<div class="banner">
  2 + <span><%= _("BANNER SPACE") %></span>
  3 +</div>
0 4 \ No newline at end of file
... ...
plugins/community_hub/views/community_hub_plugin_public/_embed.rhtml 0 → 100644
... ... @@ -0,0 +1,11 @@
  1 +<% extend CommunityHubPlugin::HubHelper %>
  2 +
  3 +<div class="embed">
  4 + <span class="label">Embed / <%= _("Embed") %></span>
  5 + <textarea cols="38"
  6 + id="comment_body"
  7 + name="comment[body]"
  8 + rows="10"
  9 + class="code"
  10 + style="width: 99%;"><%= embed_code(@page) %></textarea>
  11 +</div>
0 12 \ No newline at end of file
... ...
plugins/community_hub/views/community_hub_plugin_public/_mediation.rhtml 0 → 100644
... ... @@ -0,0 +1,87 @@
  1 +<% extend CommunityHubPlugin::HubHelper %>
  2 +
  3 +<li id="<%= mediation.id %>" class="post">
  4 +
  5 + <ul>
  6 + <li class="time"><%= post_time(mediation.created_at) %></li>
  7 +
  8 + <li class="avatar">
  9 + <% if mediation.source == 'twitter' %>
  10 + <%= image_tag(mediation.profile_picture, :alt => "Twitter") %>
  11 + <% elsif mediation.source == 'facebook' %>
  12 + <%= image_tag('/plugins/community_hub/icons/logo_facebook_50x50.png', :alt => "Facebook") %>
  13 + <% else %>
  14 + <%= image_tag(profile_icon(mediation.author, :minor)) if mediation.author %>
  15 + <% end %>
  16 + </li>
  17 + <li class="message"><span class="author"><%= mediation.setting[:author_name] %>:</span> <%= mediation.body %></li>
  18 +
  19 + <% if mediator?(hub) %>
  20 + <li class="mediation-bar">
  21 +
  22 + <ul>
  23 +
  24 + <% if mediation.source != 'twitter' && mediation.source != 'facebook' %>
  25 +
  26 + <li class="promote">
  27 + <% if !promoted?(hub, mediation.author.id) %>
  28 + <a id="<%= mediation.id %>" href="#" onclick="promote_user(<%= mediation.id %>,<%= mediation.author.id %>); return false;">
  29 + <img class="not-promoted" src="/plugins/community_hub/icons/hub-not-promote-icon.png" title="<%= _("User not promoted") %>" />
  30 + </a>
  31 + <% else %>
  32 + <img class="promoted" src="/plugins/community_hub/icons/hub-not-promote-icon.png" title="<%= _("User promoted") %>" />
  33 + <% end %>
  34 + </li>
  35 +
  36 + <% end %>
  37 +
  38 + <% if pinned_mediation?(hub, mediation.id) %>
  39 + <li class="pin">
  40 + <img class="pinned" src="/plugins/community_hub/icons/hub-not-pinned-icon.png" title="<%= _("Message pinned")%>" />
  41 + </li>
  42 + <% end %>
  43 +
  44 + </ul>
  45 +
  46 + </li>
  47 + <% end %>
  48 +
  49 + </ul>
  50 +
  51 + <% total_mediation_comments = mediation.comments.count %>
  52 +
  53 + <span class="comment-count">
  54 + <%= link_to( "<span id='mediation-comment-total-#{mediation.id}'>#{total_mediation_comments}</span> " + _("Comments") , '#',
  55 + :class => 'display-comment-form',
  56 + :id => 'top-post-comment-button',
  57 + :onclick => "toogle_mediation_comments(#{mediation.id}); return false;") %>
  58 + </span>
  59 +
  60 + <script type="text/javascript">
  61 + mediations.push( [ <%= mediation.id %>, setInterval(function() { update_mediation_comments('<%= mediation.id %>', false)}, 5000) ] );
  62 + </script>
  63 +
  64 + <ul id="mediation-comment-list-<%=mediation.id%>" class="mediation-comment-list" style="display:none;">
  65 + <% if mediation.accept_comments? && mediation.comments.count > 0 %>
  66 + <%= render :partial => 'community_hub_plugin_public/mediation_comment', :collection => mediation.comments %>
  67 + <% end %>
  68 + </ul>
  69 +
  70 + <% if logged_in? && mediation.accept_comments? %>
  71 + <div id='mediation-comment-form-<%=mediation.id%>' class='mediation-comment-form' style="display:none;">
  72 + <%= render :partial => 'community_hub_plugin_public/mediation_comment_form',
  73 + :locals => {
  74 + :hub => hub,
  75 + :mediation => mediation,
  76 + :comment => Comment.new,
  77 + :url => {
  78 + :controller => :comment,
  79 + :action => :create
  80 + },
  81 + :display_link => true,
  82 + :cancel_triggers_hide => true
  83 + } %>
  84 + </div>
  85 + <% end %>
  86 +
  87 +</li>
... ...
plugins/community_hub/views/community_hub_plugin_public/_mediation_comment.rhtml 0 → 100644
... ... @@ -0,0 +1,6 @@
  1 +<li id="<%= mediation_comment.id %>" class="mediation-comment">
  2 + <ul>
  3 + <li class="avatar"><%= image_tag(profile_icon(mediation_comment.author, :minor)) %></li>
  4 + <li class="message"><span class="author"><%= mediation_comment.author_name %>:</span> <%= mediation_comment.body %></li>
  5 + </ul>
  6 +</li>
0 7 \ No newline at end of file
... ...
plugins/community_hub/views/community_hub_plugin_public/_mediation_comment_form.rhtml 0 → 100644
... ... @@ -0,0 +1,12 @@
  1 +<% form_for :message,
  2 + :method => 'post',
  3 + :url => {
  4 + :controller => 'community_hub_plugin_public',
  5 + :action => 'new_message',
  6 + :article_id => mediation.id
  7 + } do |f| %>
  8 + <%= f.text_area(:body,
  9 + :rows => 4,
  10 + :placeholder => _('Type your comment here')) %>
  11 + <%= submit_button('add', _('Post'), :onclick => "new_mediation_comment(this,#{mediation.id}); return false;") %>
  12 +<% end %>
... ...
plugins/community_hub/views/community_hub_plugin_public/_post.rhtml 0 → 100644
... ... @@ -0,0 +1,34 @@
  1 +<% extend CommunityHubPlugin::HubHelper %>
  2 +
  3 +<li id="<%= post.id %>" class="post">
  4 + <ul>
  5 + <li class="time"><%= post_time(post.created_at) %></li>
  6 + <li class="avatar">
  7 + <% if post.title == 'hub-message-twitter' %>
  8 + <%= image_tag(post.profile_picture, :alt => "Twitter") %>
  9 + <% elsif post.title == 'hub-message-facebook' %>
  10 + <%= image_tag('/plugins/community_hub/icons/logo_facebook_50x50.png', :alt => "Facebook") %>
  11 + <% else %>
  12 + <%= image_tag(profile_icon(post.author, :minor)) if post.author %>
  13 + <% end %>
  14 + </li>
  15 + <li class="message"><span class="author"><%= post.author_name %>:</span> <%= post.body %></li>
  16 +
  17 + <% if mediator?(hub) && post.title != 'hub-message-facebook' %>
  18 + <li class="mediation-bar">
  19 + <ul>
  20 + <li class="pin">
  21 + <% if !pinned_message?(hub, post.id) %>
  22 + <a id="<%= post.id %>" href="#" onclick="pin_message(<%= post.id %>); return false;">
  23 + <img class="not-pinned" src="/plugins/community_hub/icons/hub-pinned-icon.png" title="<%= _("Pin message")%>" />
  24 + </a>
  25 + <% else %>
  26 + <img class="pinned" src="/plugins/community_hub/icons/hub-not-pinned-icon.png" title="<%= _("Message pinned")%>" />
  27 + <% end %>
  28 + </li>
  29 + </ul>
  30 + </li>
  31 + <% end %>
  32 +
  33 + </ul>
  34 +</li>
... ...
plugins/community_hub/views/community_hub_plugin_public/_settings.rhtml 0 → 100644
... ... @@ -0,0 +1,7 @@
  1 +<div class="settings">
  2 + <ul class="settings">
  3 + <li class="general">
  4 + <%= link_to _("General settings"), :controller => 'cms', :action => 'edit', :id => @page.id %>
  5 + </li>
  6 + </ul>
  7 +</div>
... ...
plugins/community_hub/views/content_viewer/hub.rhtml 0 → 100644
... ... @@ -0,0 +1,96 @@
  1 +<% extend CommunityHubPlugin::HubHelper %>
  2 +
  3 +<div id="<%=@page.id%>" class="hub">
  4 +
  5 + <div class="title"><%= @page.title %> HUB</div>
  6 +
  7 + <div class="description"><%= @page.body %></div>
  8 +
  9 + <br />
  10 +
  11 + <div id="left-tab" class="live content-tab show">
  12 +
  13 + <h1 class="live">
  14 + <span class="title"><%= @page.title %></span><span class="on-air"><%= _("Live") %></span>
  15 + </h1>
  16 +
  17 + <h1 class="mediation">
  18 + <span class="title"><%= _("Mediation") %></span>
  19 + </h1>
  20 +
  21 + <div class="envelope">
  22 + <ul id="live-posts"></ul>
  23 + </div>
  24 +
  25 + <span><%= check_box_tag 'auto_scrolling', 'yes', true %><%= _("Auto scrolling") %></span>
  26 +
  27 + <% if logged_in? %>
  28 + <div id="input-panel">
  29 + <div class="form-message">
  30 +
  31 + <% form_for :message,
  32 + :method => 'post',
  33 + :url => {
  34 + :controller => 'community_hub_plugin_public',
  35 + :action => 'new_message',
  36 + :article_id => @page.id
  37 + } do |f| %>
  38 + <span><%= _("Streaming") %></span>
  39 + <br />
  40 + <%= f.text_area :body, :style => "width: 99%;", :cols => "38", :rows => "5", :placeholder => _("Type your message here") %>
  41 + <%= submit_button('add', _('Post'), :onclick => 'new_message(this); return false;') %>
  42 + <% end %>
  43 +
  44 + </div>
  45 + </div>
  46 + <% end %>
  47 +
  48 + </div>
  49 +
  50 + <div id="right-tab" class="mediation content-tab hide">
  51 +
  52 + <h1 class="live">
  53 + <span class="title"><%= @page.title %></span><span class="on-air"><%= _("Live") %></span>
  54 + </h1>
  55 +
  56 + <h1 class="mediation">
  57 + <span class="title"><%= _("Mediation") %></span>
  58 + </h1>
  59 +
  60 + <div class="envelope">
  61 + <ul id="mediation-posts"></ul>
  62 + </div>
  63 +
  64 + <% if logged_in? && mediator?(@page) %>
  65 + <div class="form-mediation">
  66 +
  67 + <%= render :file => 'shared/tiny_mce' %>
  68 +
  69 + <% form_for :article,
  70 + :method => 'post',
  71 + :url => {
  72 + :controller => 'community_hub_plugin_public',
  73 + :action => 'new_mediation',
  74 + :profile_id => profile.id
  75 + } do |f| %>
  76 + <%= f.hidden_field :parent_id, :value => @page.id %>
  77 + <%= f.text_area :body, :style => "width: 100%;", :class => "mceEditor" %>
  78 + <%= submit_button('add', _('Post'), :onclick => 'new_mediation(this); return false;') %>
  79 + <% end %>
  80 +
  81 + </div>
  82 +
  83 + <%= render :partial => "community_hub_plugin_public/settings" %>
  84 +
  85 + <% end %>
  86 +
  87 + </div>
  88 +
  89 +</div>
  90 +
  91 +<script type="text/javascript">
  92 + DEFAULT_PIN_QUESTION = '<%= _("Are you sure that you want to pin this message?") %>';
  93 + DEFAULT_PROMOTE_QUESTION = '<%= _("Are you sure that you want to promote this user?") %>';
  94 +</script>
  95 +
  96 +<%= javascript_include_tag '/plugins/community_hub/javascripts/community_hub.js' %>
... ...