diff --git a/app/models/jobs/fetch_public_posts.rb b/app/models/jobs/fetch_public_posts.rb
new file mode 100644
index 000000000..df7f0e959
--- /dev/null
+++ b/app/models/jobs/fetch_public_posts.rb
@@ -0,0 +1,15 @@
+# Copyright (c) 2010-2012, Diaspora Inc. This file is
+# licensed under the Affero General Public License version 3 or later. See
+# the COPYRIGHT file.
+
+module Jobs
+ class FetchPublicPosts < Base
+ @queue = :http_service
+
+ def self.perform(diaspora_id)
+ require Rails.root.join('lib','diaspora','fetcher','public')
+
+ PublicFetcher.new.fetch!(diaspora_id)
+ end
+ end
+end
diff --git a/app/models/jobs/fetch_webfinger.rb b/app/models/jobs/fetch_webfinger.rb
index 3b387b6bf..9c96c41ee 100644
--- a/app/models/jobs/fetch_webfinger.rb
+++ b/app/models/jobs/fetch_webfinger.rb
@@ -1,4 +1,4 @@
-# Copyright (c) 2010-2011, Diaspora Inc. This file is
+# Copyright (c) 2010-2012, Diaspora Inc. This file is
# licensed under the Affero General Public License version 3 or later. See
# the COPYRIGHT file.
@@ -7,7 +7,10 @@ module Jobs
@queue = :socket_webfinger
def self.perform(account)
- Webfinger.new(account).fetch
+ person = Webfinger.new(account).fetch
+
+ # also, schedule to fetch a few public posts from that person
+ Resque.enqueue(Jobs::FetchPublicPosts, person.diaspora_handle) unless person.nil?
end
end
end
diff --git a/db/migrate/20120803143552_add_fetch_status_to_people.rb b/db/migrate/20120803143552_add_fetch_status_to_people.rb
new file mode 100644
index 000000000..20eca8f27
--- /dev/null
+++ b/db/migrate/20120803143552_add_fetch_status_to_people.rb
@@ -0,0 +1,5 @@
+class AddFetchStatusToPeople < ActiveRecord::Migration
+ def change
+ add_column :people, :fetch_status, :integer, :default => 0
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 7cb2c7b83..a118c3e64 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20120521191429) do
+ActiveRecord::Schema.define(:version => 20120803143552) do
create_table "account_deletions", :force => true do |t|
t.string "diaspora_handle"
@@ -229,6 +229,7 @@ ActiveRecord::Schema.define(:version => 20120521191429) do
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.boolean "closed_account", :default => false
+ t.integer "fetch_status", :default => 0
end
add_index "people", ["diaspora_handle"], :name => "index_people_on_diaspora_handle", :unique => true
diff --git a/lib/diaspora/fetcher/public.rb b/lib/diaspora/fetcher/public.rb
new file mode 100644
index 000000000..ea64f36ce
--- /dev/null
+++ b/lib/diaspora/fetcher/public.rb
@@ -0,0 +1,176 @@
+# Copyright (c) 2010-2012, Diaspora Inc. This file is
+# licensed under the Affero General Public License version 3 or later. See
+# the COPYRIGHT file.
+
+class PublicFetcher
+
+ # various states that can be assigned to a person to describe where
+ # in the process of fetching their public posts we're currently at
+ Status_Initial = 0
+ Status_Running = 1
+ Status_Fetched = 2
+ Status_Processed = 3
+ Status_Done = 4
+ Status_Failed = 5
+ Status_Unfetchable = 6
+
+ # perform all actions necessary to fetch the public posts of a person
+ # with the given diaspora_id
+ def fetch! diaspora_id
+ @person = Person.by_account_identifier diaspora_id
+ return unless qualifies_for_fetching?
+
+ begin
+ retrieve_and_process_posts
+ rescue => e
+ set_fetch_status PublicFetcher::Status_Failed
+ raise e
+ end
+
+ set_fetch_status PublicFetcher::Status_Done
+ end
+
+ private
+ # checks, that public posts for the person can be fetched,
+ # if it is reasonable to do so, and that they have not been fetched already
+ def qualifies_for_fetching?
+ raise ActiveRecord::RecordNotFound unless @person.present?
+ return false if @person.fetch_status == PublicFetcher::Status_Unfetchable
+
+ # local users don't need to be fetched
+ if @person.local?
+ set_fetch_status PublicFetcher::Status_Unfetchable
+ return false
+ end
+
+ # this record is already being worked on
+ return false if @person.fetch_status > PublicFetcher::Status_Initial
+
+ # ok, let's go
+ @person.remote? &&
+ @person.fetch_status == PublicFetcher::Status_Initial
+ end
+
+ # call the methods to fetch and process the public posts for the person
+ # does some error logging, in case of an exception
+ def retrieve_and_process_posts
+ begin
+ retrieve_posts
+ rescue => e
+ FEDERATION_LOGGER.error "unable to retrieve public posts for #{@person.diaspora_handle}"
+ raise e
+ end
+
+ begin
+ process_posts
+ rescue => e
+ FEDERATION_LOGGER.error "unable to process public posts for #{@person.diaspora_handle}"
+ raise e
+ end
+ end
+
+ # fetch the public posts of the person from their server and save the
+ # JSON response to `@data`
+ def retrieve_posts
+ set_fetch_status PublicFetcher::Status_Running
+
+ FEDERATION_LOGGER.info "fetching public posts for #{@person.diaspora_handle}"
+
+ conn = Faraday.new(:url => @person.url) do |c|
+ c.request :json
+ c.response :json
+ c.adapter :net_http
+ end
+ conn.headers[:user_agent] = 'diaspora-fetcher'
+ conn.headers[:accept] = 'application/json'
+
+ resp = conn.get "/people/#{@person.guid}"
+
+ FEDERATION_LOGGER.debug resp.body.to_s[0..250]
+
+ @data = resp.body
+ set_fetch_status PublicFetcher::Status_Fetched
+ end
+
+ # process the public posts that were previously fetched with `retrieve_posts`
+ # adds posts, which pass some basic sanity-checking
+ # @see validate
+ def process_posts
+ @data.each do |post|
+ next unless validate(post)
+
+ FEDERATION_LOGGER.info "saving fetched post (#{post['guid']}) to database"
+
+ FEDERATION_LOGGER.debug post.to_s[0..250]
+
+ entry = StatusMessage.diaspora_initialize(
+ :author => @person,
+ :public => true,
+ :guid => post['guid'],
+ :text => post['text'],
+ :provider_display_name => post['provider_display_name'],
+ :created_at => ActiveSupport::TimeZone.new('UTC').parse(post['created_at']),
+ :interacted_at => ActiveSupport::TimeZone.new('UTC').parse(post['interacted_at']),
+ :frame_name => post['frame_name']
+ )
+ entry.save
+ end
+ set_fetch_status PublicFetcher::Status_Processed
+ end
+
+ # set and save the fetch status for the current person
+ def set_fetch_status status
+ return if @person.nil?
+
+ @person.fetch_status = status
+ @person.save
+ end
+
+ # perform various validations to make sure the post can be saved without
+ # troubles
+ # @see check_existing
+ # @see check_author
+ # @see check_public
+ # @see check_type
+ def validate post
+ check_existing(post) && check_author(post) && check_public(post) && check_type(post)
+ end
+
+ # hopefully there is no post with the same guid somewhere already...
+ def check_existing post
+ new_post = (Post.find_by_guid(post['guid']).blank?)
+
+ FEDERATION_LOGGER.warn "a post with that guid (#{post['guid']}) already exists" unless new_post
+
+ new_post
+ end
+
+ # checks if the author of the given post is actually from the person
+ # we're currently processing
+ def check_author post
+ guid = post['author']['guid']
+ equal = (guid == @person.guid)
+
+ FEDERATION_LOGGER.warn "the author (#{guid}) does not match the person currently being processed (#{@person.guid})" unless equal
+
+ equal
+ end
+
+ # returns wether the given post is public
+ def check_public post
+ ispublic = (post['public'] == true)
+
+ FEDERATION_LOGGER.warn "the post (#{post['guid']}) is not public, this is not intended..." unless ispublic
+
+ ispublic
+ end
+
+ # see, if the type of the given post is something we can handle
+ def check_type post
+ type_ok = (post['post_type'] == "StatusMessage")
+
+ FEDERATION_LOGGER.warn "the post (#{post['guid']}) has a type, which cannot be handled (#{post['post_type']})" unless type_ok
+
+ type_ok
+ end
+end
\ No newline at end of file
diff --git a/lib/webfinger.rb b/lib/webfinger.rb
index 25f4002c3..d5d50b79f 100644
--- a/lib/webfinger.rb
+++ b/lib/webfinger.rb
@@ -1,3 +1,7 @@
+# Copyright (c) 2010-2012, Diaspora Inc. This file is
+# licensed under the Affero General Public License version 3 or later. See
+# the COPYRIGHT file.
+
require Rails.root.join('lib', 'hcard')
require Rails.root.join('lib', 'webfinger_profile')
diff --git a/spec/fixtures/public_posts.json b/spec/fixtures/public_posts.json
new file mode 100644
index 000000000..4d4cc1812
--- /dev/null
+++ b/spec/fixtures/public_posts.json
@@ -0,0 +1 @@
+[{"id":15086,"guid":"198095988ad26f21","text":"test of #left4dead on #linux results in \"faster zombies\" http://is.gd/uHeUC6 with linux outperforming windows","public":true,"created_at":"2012-08-02T22:13:16Z","interacted_at":"2012-08-03T15:02:59Z","provider_display_name":null,"post_type":"Reshare","image_url":null,"object_url":null,"favorite":false,"nsfw":false,"author":{"id":2,"guid":"7445f9a0a6c28ebb","name":"Florian Staudacher","diaspora_id":"raven24@pod.fulll.name","avatar":{"small":"https://pod.fulll.name/uploads/images/thumb_small_5f612f44a0a026b119f8.png","medium":"https://pod.fulll.name/uploads/images/thumb_medium_5f612f44a0a026b119f8.png","large":"https://pod.fulll.name/uploads/images/thumb_large_5f612f44a0a026b119f8.png"}},"o_embed_cache":null,"mentioned_people":[],"photos":[],"frame_name":"status","root":{"id":15028,"guid":"1b2a98db23582947","text":"test of #left4dead on #linux results in \"faster zombies\" http://is.gd/uHeUC6 with linux outperforming windows","public":true,"created_at":"2012-08-02T14:25:56Z","interacted_at":"2012-08-02T21:54:53Z","provider_display_name":null,"post_type":"StatusMessage","image_url":null,"object_url":null,"favorite":false,"nsfw":false,"author":{"id":1769,"guid":"a2f9a3a7cb3dcd5a","name":"el [spare pope] olmo","diaspora_id":"el_olmo@pod.fulll.name","avatar":{"small":"https://pod.fulll.name/uploads/images/thumb_small_343f6520778765c4b3f9.jpg","medium":"https://pod.fulll.name/uploads/images/thumb_medium_343f6520778765c4b3f9.jpg","large":"https://pod.fulll.name/uploads/images/thumb_large_343f6520778765c4b3f9.jpg"}},"o_embed_cache":null,"mentioned_people":[],"photos":[],"frame_name":"status","root":null,"title":"test of #left4dead on #linux results in \"faster zombies\" http://is.gd/uHeUC6 with linux outperforming windows","next_post":"/posts/15028/next","previous_post":"/posts/15028/previous","interactions":{"likes":[{"id":32638,"guid":"b2c1e789b1eec9ea","author":{"id":2,"guid":"7445f9a0a6c28ebb","name":"Florian Staudacher","diaspora_id":"raven24@pod.fulll.name","avatar":{"small":"https://pod.fulll.name/uploads/images/thumb_small_5f612f44a0a026b119f8.png","medium":"https://pod.fulll.name/uploads/images/thumb_medium_5f612f44a0a026b119f8.png","large":"https://pod.fulll.name/uploads/images/thumb_large_5f612f44a0a026b119f8.png"}},"created_at":"2012-08-02T21:54:53Z"}],"reshares":[{"reshare":{"actor_url":null,"author_id":2,"comments_count":0,"created_at":"2012-08-02T22:13:16Z","diaspora_handle":"raven24@pod.fulll.name","favorite":false,"frame_name":null,"guid":"198095988ad26f21","id":15086,"image_height":null,"image_url":null,"image_width":null,"interacted_at":"2012-08-03T15:02:59Z","likes_count":2,"o_embed_cache_id":null,"objectId":null,"object_url":null,"pending":false,"processed_image":null,"provider_display_name":null,"public":true,"random_string":null,"remote_photo_name":null,"remote_photo_path":null,"reshares_count":0,"root_guid":"1b2a98db23582947","status_message_guid":null,"text":null,"unprocessed_image":null,"updated_at":"2012-08-03T15:02:59Z"}}],"comments_count":0,"likes_count":6,"reshares_count":1}},"title":"A post from Florian Staudacher","next_post":"/posts/15086/next","previous_post":"/posts/15086/previous","interactions":{"likes":[],"reshares":[],"comments_count":0,"likes_count":2,"reshares_count":0,"comments":[]}},{"id":14755,"guid":"0ffef04549e81bfa","text":"... in case you ever need the network device name, ip and mac address, here you go: \r\nhttps://gist.github.com/3202188\r\n\r\n(uses ifconfig, grep and sed with some regular expression magic) \r\n#bash #script #network #ip #grep #sed #regexp #linux","public":true,"created_at":"2012-07-29T22:28:17Z","interacted_at":"2012-08-01T18:01:49Z","provider_display_name":null,"post_type":"StatusMessage","image_url":null,"object_url":null,"favorite":false,"nsfw":false,"author":{"id":2,"guid":"7445f9a0a6c28ebb","name":"Florian Staudacher","diaspora_id":"raven24@pod.fulll.name","avatar":{"small":"https://pod.fulll.name/uploads/images/thumb_small_5f612f44a0a026b119f8.png","medium":"https://pod.fulll.name/uploads/images/thumb_medium_5f612f44a0a026b119f8.png","large":"https://pod.fulll.name/uploads/images/thumb_large_5f612f44a0a026b119f8.png"}},"o_embed_cache":null,"mentioned_people":[],"photos":[],"frame_name":"note","root":null,"title":"... in case you ever need the network device name, ip and mac address, here you go: \r\nhttps://gist.github.com/3202188\r\n\r\n(uses ifconfig, grep and sed with some regular expression magic) \r\n#bash #script #network #ip #grep #sed #regexp #linux","next_post":"/posts/14755/next","previous_post":"/posts/14755/previous","interactions":{"likes":[],"reshares":[],"comments_count":8,"likes_count":4,"reshares_count":0,"comments":[{"id":20912,"guid":"ba86c52ca4d293c4","text":"It only shows network devices named eth* and doesn't work with localized versions of ifconfig in non-english language environments","author":{"id":6243,"guid":"c7bf295dae900b7a","name":"Florian Diesch","diaspora_id":"diesch@joindiaspora.com","avatar":{"small":"https://joindiaspora.s3.amazonaws.com/uploads/images/thumb_small_7f090bd1002004896464.png","medium":"https://joindiaspora.s3.amazonaws.com/uploads/images/thumb_medium_7f090bd1002004896464.png","large":"https://joindiaspora.s3.amazonaws.com/uploads/images/thumb_large_7f090bd1002004896464.png"}},"created_at":"2012-07-30T02:33:06Z"},{"id":21012,"guid":"81fc5d869de5ea05","text":"For now, I only need it just the way it is (in my collection of VM management scripts), but feel free to change it to work with whatever version or language of `ifconfig` you need. I leave that \"as an exercise to the reader\" ... it's always a good time to start learning `sed` regular expressions \n;)","author":{"id":2,"guid":"7445f9a0a6c28ebb","name":"Florian Staudacher","diaspora_id":"raven24@pod.fulll.name","avatar":{"small":"https://pod.fulll.name/uploads/images/thumb_small_5f612f44a0a026b119f8.png","medium":"https://pod.fulll.name/uploads/images/thumb_medium_5f612f44a0a026b119f8.png","large":"https://pod.fulll.name/uploads/images/thumb_large_5f612f44a0a026b119f8.png"}},"created_at":"2012-07-31T01:51:24Z"},{"id":21164,"guid":"d74aac53420cd66f","text":"[inxi](https://code.google.com/p/inxi/)","author":{"id":3920,"guid":"b636315dc6f90ece","name":"Kiridesce","diaspora_id":"iridesce@kosmospora.net","avatar":{"small":"https://kosmospora.net/uploads/images/thumb_small_7b3c16e2107449bf9717.jpeg","medium":"https://kosmospora.net/uploads/images/thumb_medium_7b3c16e2107449bf9717.jpeg","large":"https://kosmospora.net/uploads/images/thumb_large_7b3c16e2107449bf9717.jpeg"}},"created_at":"2012-08-01T18:01:49Z"}]}},{"id":14514,"guid":"c6b5e0a20421d719","text":"lol! \r\nhttp://youtu.be/6RrpGgaT5kk\r\n\r\n#acapella #movie #dub","public":true,"created_at":"2012-07-27T14:09:31Z","interacted_at":"2012-07-28T21:25:56Z","provider_display_name":null,"post_type":"StatusMessage","image_url":null,"object_url":null,"favorite":false,"nsfw":false,"author":{"id":2,"guid":"7445f9a0a6c28ebb","name":"Florian Staudacher","diaspora_id":"raven24@pod.fulll.name","avatar":{"small":"https://pod.fulll.name/uploads/images/thumb_small_5f612f44a0a026b119f8.png","medium":"https://pod.fulll.name/uploads/images/thumb_medium_5f612f44a0a026b119f8.png","large":"https://pod.fulll.name/uploads/images/thumb_large_5f612f44a0a026b119f8.png"}},"o_embed_cache":{"data":{"provider_url":"http://www.youtube.com/","thumbnail_url":"http://i3.ytimg.com/vi/6RrpGgaT5kk/hqdefault.jpg","title":"'The Matrix' Lobby Scene with A capella Multitrack - Matt Mulholland","html":"","author_name":"mattmulholland26","height":236,"thumbnail_width":480,"width":420,"version":"1.0","author_url":"http://www.youtube.com/user/mattmulholland26","provider_name":"YouTube","type":"video","thumbnail_height":360,"trusted_endpoint_url":"http://www.youtube.com/oembed"}},"mentioned_people":[],"photos":[],"frame_name":"status","root":null,"title":"lol! \r\nhttp://youtu.be/6RrpGgaT5kk\r\n\r\n#acapella #movie #dub","next_post":"/posts/14514/next","previous_post":"/posts/14514/previous","interactions":{"likes":[],"reshares":[],"comments_count":1,"likes_count":2,"reshares_count":0,"comments":[{"id":20833,"guid":"3c2d21708b6cfa29","text":"Inception Trailer A Capella Re-Dub: http://www.youtube.com/watch?v=d2yD4yDsiP4","author":{"id":2896,"guid":"24e82915d58368fe","name":"Alexey Andreyev","diaspora_id":"yetanotherandreyev@diasp.org","avatar":{"small":"https://diasp.org/uploads/images/thumb_small_9f29c5326741a32889fa.jpg","medium":"https://diasp.org/uploads/images/thumb_medium_9f29c5326741a32889fa.jpg","large":"https://diasp.org/uploads/images/thumb_large_9f29c5326741a32889fa.jpg"}},"created_at":"2012-07-28T21:25:56Z"}]}},{"id":14113,"guid":"4404d1bb88d36735","text":"Keep Calm and use #Linux [  ](http://goo.gl/HSS18) ","public":true,"created_at":"2012-07-23T15:50:00Z","interacted_at":"2012-07-24T15:16:25Z","provider_display_name":null,"post_type":"Reshare","image_url":null,"object_url":null,"favorite":false,"nsfw":false,"author":{"id":2,"guid":"7445f9a0a6c28ebb","name":"Florian Staudacher","diaspora_id":"raven24@pod.fulll.name","avatar":{"small":"https://pod.fulll.name/uploads/images/thumb_small_5f612f44a0a026b119f8.png","medium":"https://pod.fulll.name/uploads/images/thumb_medium_5f612f44a0a026b119f8.png","large":"https://pod.fulll.name/uploads/images/thumb_large_5f612f44a0a026b119f8.png"}},"o_embed_cache":null,"mentioned_people":[],"photos":[],"frame_name":"status","root":{"id":14099,"guid":"d1970bb173aae310","text":"Keep Calm and use #Linux [  ](http://goo.gl/HSS18) ","public":true,"created_at":"2012-07-23T13:12:51Z","interacted_at":"2012-07-23T13:37:24Z","provider_display_name":null,"post_type":"StatusMessage","image_url":null,"object_url":null,"favorite":false,"nsfw":false,"author":{"id":175,"guid":"4d11bd252c174338f2002a4c","name":"\u24b6\u24c5\u24c4\u24c1\u24c4\u24c3\u24be\u24c8 \u2301 \u24b6\u24c5\u24bd\u24c7\u24c4\u24b9\u24be\u24c8\u24be\u24b6","diaspora_id":"apolonisaphrodisia@joindiaspora.com","avatar":{"small":"https://joindiaspora.s3.amazonaws.com/uploads/images/thumb_small_8107d3419ac23bd16253.gif","medium":"https://joindiaspora.s3.amazonaws.com/uploads/images/thumb_medium_8107d3419ac23bd16253.gif","large":"https://pod.fulll.name/images/user/default.png"}},"o_embed_cache":null,"mentioned_people":[],"photos":[],"frame_name":"status","root":null,"title":"Keep Calm and use #Linux [  ](http://goo.gl/HSS18) ","next_post":"/posts/14099/next","previous_post":"/posts/14099/previous","interactions":{"likes":[],"reshares":[],"comments_count":0,"likes_count":0,"reshares_count":2}},"title":"A post from Florian Staudacher","next_post":"/posts/14113/next","previous_post":"/posts/14113/previous","interactions":{"likes":[],"reshares":[],"comments_count":0,"likes_count":2,"reshares_count":1,"comments":[]}},{"id":14110,"guid":"bb89c419e60fd801","text":"awesome #youtube #video \r\nhttp://youtu.be/daVDrGsaDME\r\n\r\n#car #engine #stopmotion","public":true,"created_at":"2012-07-23T15:05:36Z","interacted_at":"2012-07-24T12:48:48Z","provider_display_name":null,"post_type":"StatusMessage","image_url":null,"object_url":null,"favorite":false,"nsfw":false,"author":{"id":2,"guid":"7445f9a0a6c28ebb","name":"Florian Staudacher","diaspora_id":"raven24@pod.fulll.name","avatar":{"small":"https://pod.fulll.name/uploads/images/thumb_small_5f612f44a0a026b119f8.png","medium":"https://pod.fulll.name/uploads/images/thumb_medium_5f612f44a0a026b119f8.png","large":"https://pod.fulll.name/uploads/images/thumb_large_5f612f44a0a026b119f8.png"}},"o_embed_cache":{"data":{"provider_url":"http://www.youtube.com/","thumbnail_url":"http://i1.ytimg.com/vi/daVDrGsaDME/hqdefault.jpg","title":"11 Months, 3000 pictures and a lot of coffee.","html":"","author_name":"nothinghereok","height":315,"thumbnail_width":480,"width":420,"version":"1.0","author_url":"http://www.youtube.com/user/nothinghereok","provider_name":"YouTube","type":"video","thumbnail_height":360,"trusted_endpoint_url":"http://www.youtube.com/oembed"}},"mentioned_people":[],"photos":[],"frame_name":"status","root":null,"title":"awesome #youtube #video \r\nhttp://youtu.be/daVDrGsaDME\r\n\r\n#car #engine #stopmotion","next_post":"/posts/14110/next","previous_post":"/posts/14110/previous","interactions":{"likes":[],"reshares":[],"comments_count":0,"likes_count":1,"reshares_count":0,"comments":[]}},{"id":12830,"guid":"5a4089375be2db14","text":"jQuery Core: Version 1.9 and Beyond - http://blog.jquery.com/2012/06/28/jquery-core-version-1-9-and-beyond/ - \r\n_jQuery 2.0: This version will support the same APIs as jQuery 1.9 does, but removes support for IE 6/7/8 oddities such as borked event model, IE7 \u201cattroperties\u201d, HTML5 shims, etc. \r\nOur goal is for 1.9 and 2.0 to be interchangeable as far as the API set they support. When 2.0 comes out, your decision on which version to choose should be as simple as this: If you need IE 6/7/8 support, choose 1.9; otherwise you can use either 1.9 or 2.0._ \r\nI hope IE dies a quick but painfull death... \r\n#jquery #ie #browser #web","public":true,"created_at":"2012-07-13T20:36:35Z","interacted_at":"2012-07-13T20:36:35Z","provider_display_name":null,"post_type":"StatusMessage","image_url":null,"object_url":null,"favorite":false,"nsfw":false,"author":{"id":2,"guid":"7445f9a0a6c28ebb","name":"Florian Staudacher","diaspora_id":"raven24@pod.fulll.name","avatar":{"small":"https://pod.fulll.name/uploads/images/thumb_small_5f612f44a0a026b119f8.png","medium":"https://pod.fulll.name/uploads/images/thumb_medium_5f612f44a0a026b119f8.png","large":"https://pod.fulll.name/uploads/images/thumb_large_5f612f44a0a026b119f8.png"}},"o_embed_cache":null,"mentioned_people":[],"photos":[],"frame_name":"note","root":null,"title":"jQuery Core: Version 1.9 and Beyond - http://blog.jquery.com/2012/06/28/jquery-core-version-1-9-and-beyond/ - \r\n_jQuery 2.0: This version will support the same APIs as jQuery 1.9 does, but removes support for IE 6/7/8 oddities such as borked event model, IE7 \u201cattroperties\u201d, HTML5 shims, etc. \r\nOur goal is for 1.9 and 2.0 to be interchangeable as far as the API set they support. When 2.0 comes out, your decision on which version to choose should be as simple as this: If you need IE 6/7/8 support, choose 1.9; otherwise you can use either 1.9 or 2.0._ \r\nI hope IE dies a quick but painfull death... \r\n#jquery #ie #browser #web","next_post":"/posts/12830/next","previous_post":"/posts/12830/previous","interactions":{"likes":[],"reshares":[],"comments_count":0,"likes_count":0,"reshares_count":0,"comments":[]}},{"id":12763,"guid":"82adaf03843115e8","text":"http://www.evolutionoftheweb.com\r\n\r\n\r\n\r\n#www #web #ITNews #Browser #Internet #technology #IT","public":true,"created_at":"2012-07-13T09:30:02Z","interacted_at":"2012-07-29T23:46:30Z","provider_display_name":null,"post_type":"Reshare","image_url":null,"object_url":null,"favorite":false,"nsfw":false,"author":{"id":2,"guid":"7445f9a0a6c28ebb","name":"Florian Staudacher","diaspora_id":"raven24@pod.fulll.name","avatar":{"small":"https://pod.fulll.name/uploads/images/thumb_small_5f612f44a0a026b119f8.png","medium":"https://pod.fulll.name/uploads/images/thumb_medium_5f612f44a0a026b119f8.png","large":"https://pod.fulll.name/uploads/images/thumb_large_5f612f44a0a026b119f8.png"}},"o_embed_cache":null,"mentioned_people":[],"photos":[],"frame_name":"status","root":{"id":12751,"guid":"389f84ae16581df6","text":"http://www.evolutionoftheweb.com\r\n\r\n\r\n\r\n#www #web #ITNews #Browser #Internet #technology #IT","public":true,"created_at":"2012-07-12T17:34:10Z","interacted_at":"2012-07-13T05:49:09Z","provider_display_name":null,"post_type":"StatusMessage","image_url":null,"object_url":null,"favorite":false,"nsfw":false,"author":{"id":4079,"guid":"bfe281001b5a8561","name":"Anonymiss","diaspora_id":"anonymiss@despora.de","avatar":{"small":"https://despora.de/uploads/images/thumb_small_d25c7b27e7bbf307a8cc.jpg","medium":"https://despora.de/uploads/images/thumb_medium_d25c7b27e7bbf307a8cc.jpg","large":"https://despora.de/uploads/images/thumb_large_d25c7b27e7bbf307a8cc.jpg"}},"o_embed_cache":null,"mentioned_people":[],"photos":[],"frame_name":"status","root":null,"title":"http://www.evolutionoftheweb.com\r\n\r\n\r\n\r\n#www #web #ITNews #Browser #Internet #technology #IT","next_post":"/posts/12751/next","previous_post":"/posts/12751/previous","interactions":{"likes":[],"reshares":[],"comments_count":0,"likes_count":0,"reshares_count":1}},"title":"A post from Florian Staudacher","next_post":"/posts/12763/next","previous_post":"/posts/12763/previous","interactions":{"likes":[],"reshares":[],"comments_count":0,"likes_count":2,"reshares_count":0,"comments":[]}},{"id":12463,"guid":"cb0a304194c719d8","text":"Relativistic Baseball - http://what-if.xkcd.com/1/ - \r\nWhat would happen if you tried to hit a baseball pitched at 90% the speed of light? \r\n#xkcd #whatif","public":true,"created_at":"2012-07-10T09:31:54Z","interacted_at":"2012-07-29T23:52:08Z","provider_display_name":null,"post_type":"StatusMessage","image_url":null,"object_url":null,"favorite":false,"nsfw":false,"author":{"id":2,"guid":"7445f9a0a6c28ebb","name":"Florian Staudacher","diaspora_id":"raven24@pod.fulll.name","avatar":{"small":"https://pod.fulll.name/uploads/images/thumb_small_5f612f44a0a026b119f8.png","medium":"https://pod.fulll.name/uploads/images/thumb_medium_5f612f44a0a026b119f8.png","large":"https://pod.fulll.name/uploads/images/thumb_large_5f612f44a0a026b119f8.png"}},"o_embed_cache":null,"mentioned_people":[],"photos":[],"frame_name":"status","root":null,"title":"Relativistic Baseball - http://what-if.xkcd.com/1/ - \r\nWhat would happen if you tried to hit a baseball pitched at 90% the speed of light? \r\n#xkcd #whatif","next_post":"/posts/12463/next","previous_post":"/posts/12463/previous","interactions":{"likes":[],"reshares":[],"comments_count":0,"likes_count":3,"reshares_count":1,"comments":[]}},{"id":12349,"guid":"b16efb0fc6427338","text":"yay, new \"simon's cat\"! \r\n \r\nhttp://youtu.be/XrivBjlv6Mw \r\n#simonscat #cat","public":true,"created_at":"2012-07-09T12:03:38Z","interacted_at":"2012-07-10T21:59:32Z","provider_display_name":null,"post_type":"StatusMessage","image_url":null,"object_url":null,"favorite":false,"nsfw":false,"author":{"id":2,"guid":"7445f9a0a6c28ebb","name":"Florian Staudacher","diaspora_id":"raven24@pod.fulll.name","avatar":{"small":"https://pod.fulll.name/uploads/images/thumb_small_5f612f44a0a026b119f8.png","medium":"https://pod.fulll.name/uploads/images/thumb_medium_5f612f44a0a026b119f8.png","large":"https://pod.fulll.name/uploads/images/thumb_large_5f612f44a0a026b119f8.png"}},"o_embed_cache":{"data":{"provider_url":"http://www.youtube.com/","thumbnail_url":"http://i1.ytimg.com/vi/XrivBjlv6Mw/hqdefault.jpg","title":"Simon's Cat in 'Window Pain'","html":"","author_name":"simonscat","height":236,"thumbnail_width":480,"width":420,"version":"1.0","author_url":"http://www.youtube.com/user/simonscat","provider_name":"YouTube","type":"video","thumbnail_height":360,"trusted_endpoint_url":"http://www.youtube.com/oembed"}},"mentioned_people":[],"photos":[],"frame_name":"status","root":null,"title":"yay, new \"simon's cat\"! \r\n \r\nhttp://youtu.be/XrivBjlv6Mw \r\n#simonscat #cat","next_post":"/posts/12349/next","previous_post":"/posts/12349/previous","interactions":{"likes":[],"reshares":[],"comments_count":0,"likes_count":2,"reshares_count":1,"comments":[]}},{"id":12172,"guid":"198034364c7226a1","text":"Ex-Nokia staff to build MeeGo-based smartphones - http://www.theverge.com/2012/7/7/3143099/jolla-meego-startup-ex-nokia-employees - \r\n_A group of ex-Nokia staff and MeeGo enthusiasts has formed Jolla (Finnish for \"dinghy\"), a mobile startup with the aim of bringing new MeeGo devices to the market._ \r\nThank you, thank you so much!\r\n#nokia #meego #maemo #mer #linux #smartphone","public":true,"created_at":"2012-07-07T22:16:11Z","interacted_at":"2012-07-09T11:02:08Z","provider_display_name":null,"post_type":"StatusMessage","image_url":null,"object_url":null,"favorite":false,"nsfw":false,"author":{"id":2,"guid":"7445f9a0a6c28ebb","name":"Florian Staudacher","diaspora_id":"raven24@pod.fulll.name","avatar":{"small":"https://pod.fulll.name/uploads/images/thumb_small_5f612f44a0a026b119f8.png","medium":"https://pod.fulll.name/uploads/images/thumb_medium_5f612f44a0a026b119f8.png","large":"https://pod.fulll.name/uploads/images/thumb_large_5f612f44a0a026b119f8.png"}},"o_embed_cache":null,"mentioned_people":[],"photos":[],"frame_name":"note","root":null,"title":"Ex-Nokia staff to build MeeGo-based smartphones - http://www.theverge.com/2012/7/7/3143099/jolla-meego-startup-ex-nokia-employees - \r\n_A group of ex-Nokia staff and MeeGo enthusiasts has formed Jolla (Finnish for \"dinghy\"), a mobile startup with the aim of bringing new MeeGo devices to the market._ \r\nThank you, thank you so much!\r\n#nokia #meego #maemo #mer #linux #smartphone","next_post":"/posts/12172/next","previous_post":"/posts/12172/previous","interactions":{"likes":[],"reshares":[],"comments_count":5,"likes_count":9,"reshares_count":3,"comments":[{"id":18837,"guid":"e70d7b0bbb779547","text":"Can they join efforts with Mer and PlasmaActive? I don't really see a need to reinvent the wheel.","author":{"id":1864,"guid":"6d48d8a46633e586","name":"Shmerl","diaspora_id":"bahaltener@joindiaspora.com","avatar":{"small":"https://joindiaspora.s3.amazonaws.com/uploads/images/thumb_small_7d3b625db04eca524c67.png","medium":"https://joindiaspora.s3.amazonaws.com/uploads/images/thumb_medium_7d3b625db04eca524c67.png","large":"https://joindiaspora.s3.amazonaws.com/uploads/images/thumb_large_7d3b625db04eca524c67.png"}},"created_at":"2012-07-08T02:30:40Z"},{"id":18842,"guid":"421e799bef69f18b","text":"Looks like they do work with Mer. Good news!","author":{"id":1864,"guid":"6d48d8a46633e586","name":"Shmerl","diaspora_id":"bahaltener@joindiaspora.com","avatar":{"small":"https://joindiaspora.s3.amazonaws.com/uploads/images/thumb_small_7d3b625db04eca524c67.png","medium":"https://joindiaspora.s3.amazonaws.com/uploads/images/thumb_medium_7d3b625db04eca524c67.png","large":"https://joindiaspora.s3.amazonaws.com/uploads/images/thumb_large_7d3b625db04eca524c67.png"}},"created_at":"2012-07-08T06:02:18Z"},{"id":18944,"guid":"16320b7c377ebb5a","text":"Tizen has normal Linux stack (X.org or Wayland based), so if you build all the dependencies, you can run Qt based programs there. The downside will be, that Qt isn't included in Tizen by default so far. They promote using EFL.","author":{"id":1864,"guid":"6d48d8a46633e586","name":"Shmerl","diaspora_id":"bahaltener@joindiaspora.com","avatar":{"small":"https://joindiaspora.s3.amazonaws.com/uploads/images/thumb_small_7d3b625db04eca524c67.png","medium":"https://joindiaspora.s3.amazonaws.com/uploads/images/thumb_medium_7d3b625db04eca524c67.png","large":"https://joindiaspora.s3.amazonaws.com/uploads/images/thumb_large_7d3b625db04eca524c67.png"}},"created_at":"2012-07-09T02:59:06Z"}]}},{"id":11937,"guid":"2aad765debb1e80e","text":"to all podmins: \r\nplease read this announcement: https://groups.google.com/d/msg/diaspora-dev/kMOuJk5h_v4/5Gx1Dsib6EQJ \r\nthis hopefully provides the solution to clean the database from even the most stubborn mixed-case hashtags. \r\n#diaspora #podmin #hashtags #actionrequired","public":true,"created_at":"2012-07-06T11:56:30Z","interacted_at":"2012-07-06T16:32:38Z","provider_display_name":null,"post_type":"StatusMessage","image_url":null,"object_url":null,"favorite":false,"nsfw":false,"author":{"id":2,"guid":"7445f9a0a6c28ebb","name":"Florian Staudacher","diaspora_id":"raven24@pod.fulll.name","avatar":{"small":"https://pod.fulll.name/uploads/images/thumb_small_5f612f44a0a026b119f8.png","medium":"https://pod.fulll.name/uploads/images/thumb_medium_5f612f44a0a026b119f8.png","large":"https://pod.fulll.name/uploads/images/thumb_large_5f612f44a0a026b119f8.png"}},"o_embed_cache":null,"mentioned_people":[],"photos":[],"frame_name":"note","root":null,"title":"to all podmins: \r\nplease read this announcement: https://groups.google.com/d/msg/diaspora-dev/kMOuJk5h_v4/5Gx1Dsib6EQJ \r\nthis hopefully provides the solution to clean the database from even the most stubborn mixed-case hashtags. \r\n#diaspora #podmin #hashtags #actionrequired","next_post":"/posts/11937/next","previous_post":"/posts/11937/previous","interactions":{"likes":[],"reshares":[],"comments_count":3,"likes_count":2,"reshares_count":1,"comments":[{"id":18691,"guid":"8a907544696e4faf","text":"thanks!","author":{"id":365,"guid":"dfc51824b3a76b71","name":"Sven Fischer","diaspora_id":"strubbl@sxspora.de","avatar":{"small":"http://sxspora.de/uploads/images/thumb_small_5c105bceab19eff9b0a3.jpg","medium":"http://sxspora.de/uploads/images/thumb_medium_5c105bceab19eff9b0a3.jpg","large":"http://sxspora.de/uploads/images/thumb_large_5c105bceab19eff9b0a3.jpg"}},"created_at":"2012-07-06T14:53:56Z"},{"id":18695,"guid":"8547aa6d2738ecb4","text":"before 2589. now of course 0. I prepended the bundle command with RAILS_ENV=production DB=\"mysql\". Otherwise it didn't work because a diaspora_development does not exist.","author":{"id":365,"guid":"dfc51824b3a76b71","name":"Sven Fischer","diaspora_id":"strubbl@sxspora.de","avatar":{"small":"http://sxspora.de/uploads/images/thumb_small_5c105bceab19eff9b0a3.jpg","medium":"http://sxspora.de/uploads/images/thumb_medium_5c105bceab19eff9b0a3.jpg","large":"http://sxspora.de/uploads/images/thumb_large_5c105bceab19eff9b0a3.jpg"}},"created_at":"2012-07-06T15:10:44Z"},{"id":18704,"guid":"247b0520a7824450","text":"oh, sorry ... yeah I thought that was implied","author":{"id":2,"guid":"7445f9a0a6c28ebb","name":"Florian Staudacher","diaspora_id":"raven24@pod.fulll.name","avatar":{"small":"https://pod.fulll.name/uploads/images/thumb_small_5f612f44a0a026b119f8.png","medium":"https://pod.fulll.name/uploads/images/thumb_medium_5f612f44a0a026b119f8.png","large":"https://pod.fulll.name/uploads/images/thumb_large_5f612f44a0a026b119f8.png"}},"created_at":"2012-07-06T16:32:38Z"}]}},{"id":11934,"guid":"e75e4e4719bf9405","text":"qtruby is intriguing ... I think I'll need to build something with it ;) \r\n(writing this from a QWebView created by a ruby script ^^) \r\n#ruby #qt #programming","public":true,"created_at":"2012-07-06T11:15:04Z","interacted_at":"2012-07-06T11:15:05Z","provider_display_name":null,"post_type":"StatusMessage","image_url":null,"object_url":null,"favorite":false,"nsfw":false,"author":{"id":2,"guid":"7445f9a0a6c28ebb","name":"Florian Staudacher","diaspora_id":"raven24@pod.fulll.name","avatar":{"small":"https://pod.fulll.name/uploads/images/thumb_small_5f612f44a0a026b119f8.png","medium":"https://pod.fulll.name/uploads/images/thumb_medium_5f612f44a0a026b119f8.png","large":"https://pod.fulll.name/uploads/images/thumb_large_5f612f44a0a026b119f8.png"}},"o_embed_cache":null,"mentioned_people":[],"photos":[],"frame_name":"status","root":null,"title":"qtruby is intriguing ... I think I'll need to build something with it ;) \r\n(writing this from a QWebView created by a ruby script ^^) \r\n#ruby #qt #programming","next_post":"/posts/11934/next","previous_post":"/posts/11934/previous","interactions":{"likes":[],"reshares":[],"comments_count":0,"likes_count":0,"reshares_count":0,"comments":[]}},{"id":11782,"guid":"23416f5cd259bfcc","text":"can one or more podmins please test this pull request on a *copy* of their database? -> https://github.com/diaspora/diaspora/pull/3434 \r\nit's about hashtags mit mixed-case letters in them, and the PR ccontains some changes to the rake task that is supposed to clean those up, which should hopefully eliminate mixed-case hashtags one and for all. \r\nto verify the successful run, the rake task should complete and in your database there should be no more mixed-case hashtags. You can check this by running this statement before and after the rake task ran: \r\n\r\n SELECT * FROM tags WHERE LOWER(name) != name\r\n\r\nBefore, you should see a list of all hashtags that will be processed, and after, the query shoud return an empty result. \r\n\r\n#diaspora #podmin #pleasetest #hashtags","public":true,"created_at":"2012-07-05T10:01:50Z","interacted_at":"2012-07-08T19:18:00Z","provider_display_name":null,"post_type":"StatusMessage","image_url":null,"object_url":null,"favorite":false,"nsfw":false,"author":{"id":2,"guid":"7445f9a0a6c28ebb","name":"Florian Staudacher","diaspora_id":"raven24@pod.fulll.name","avatar":{"small":"https://pod.fulll.name/uploads/images/thumb_small_5f612f44a0a026b119f8.png","medium":"https://pod.fulll.name/uploads/images/thumb_medium_5f612f44a0a026b119f8.png","large":"https://pod.fulll.name/uploads/images/thumb_large_5f612f44a0a026b119f8.png"}},"o_embed_cache":null,"mentioned_people":[],"photos":[],"frame_name":"note","root":null,"title":"can one or more podmins please test this pull request on a *copy* of their database? -> https://github.com/diaspora/diaspora/pull/3434 \r\nit's about hashtags mit mixed-case letters in them, and the PR ccontains some changes to the rake task that is supposed to clean those up, which should hopefully eliminate mixed-case hashtags one and for all. \r\nto verify the successful run, the rake task should complete and in your database there should be no more mixed-case hashtags. You can check this by running this statement before and after the rake task ran: \r\n\r\n SELECT * FROM tags WHERE LOWER(name) != name\r\n\r\nBefore, you should see a list of all hashtags that will be processed, and after, the query shoud return an empty result. \r\n\r\n#diaspora #podmin #pleasetest #hashtags","next_post":"/posts/11782/next","previous_post":"/posts/11782/previous","interactions":{"likes":[],"reshares":[],"comments_count":6,"likes_count":2,"reshares_count":0,"comments":[{"id":18584,"guid":"217ad7b7ab5fa869","text":"Oh! Duhh! Sorry, let me merge that and try again.","author":{"id":5653,"guid":"7410329c39e6810f","name":"Hans","diaspora_id":"hans@hfase.com","avatar":{"small":"https://hfase.com/uploads/images/thumb_small_f2b2d6b041732c5f91eb.jpg","medium":"https://hfase.com/uploads/images/thumb_medium_f2b2d6b041732c5f91eb.jpg","large":"https://hfase.com/uploads/images/thumb_large_f2b2d6b041732c5f91eb.jpg"}},"created_at":"2012-07-05T10:36:46Z"},{"id":18586,"guid":"0268792e018c3ec3","text":"\"MySQL returned an empty result set (i.e. zero rows). ( Query took 0.0003 sec )\"\n\nMuch better! :D Thanks!!","author":{"id":5653,"guid":"7410329c39e6810f","name":"Hans","diaspora_id":"hans@hfase.com","avatar":{"small":"https://hfase.com/uploads/images/thumb_small_f2b2d6b041732c5f91eb.jpg","medium":"https://hfase.com/uploads/images/thumb_medium_f2b2d6b041732c5f91eb.jpg","large":"https://hfase.com/uploads/images/thumb_large_f2b2d6b041732c5f91eb.jpg"}},"created_at":"2012-07-05T10:39:12Z"},{"id":18587,"guid":"8b39d807abd7302e","text":"yeah, that looks good!","author":{"id":2,"guid":"7445f9a0a6c28ebb","name":"Florian Staudacher","diaspora_id":"raven24@pod.fulll.name","avatar":{"small":"https://pod.fulll.name/uploads/images/thumb_small_5f612f44a0a026b119f8.png","medium":"https://pod.fulll.name/uploads/images/thumb_medium_5f612f44a0a026b119f8.png","large":"https://pod.fulll.name/uploads/images/thumb_large_5f612f44a0a026b119f8.png"}},"created_at":"2012-07-05T10:44:19Z"}]}},{"id":11774,"guid":"dbcb53c18a1c40bc","text":"# Intro To Using Diaspora\\*\r\n\r\n## Federated Social Networking\r\n\r\nDiaspora\\* is a social network (socnet), similar in many ways to Facebook, #MySpace, #Orkut, and Google Plus ( #GPlus). In fact, those of us who were already using D\\* when GPlus came out were quite familiar with its layout and functionality. It was almost as if they had started developing by grabbing D\\* code and stripping out federation.\r\n\r\nWhen I say federated, I mean that there is not one central Diaspora\\* server (or server cluster) that all users belong to. Instead, there are many [Diaspora\\* servers](http://podupti.me/) to choose from, with different operators ( #podmin), privacy policies, terms of service, and so on. Federation works much like when you decide to mail someone. It doesn't matter to me whether you use Gmail, Hotmail, Ymail, or GMX. I can send messages to you because electronic mail is federated. It is the same way with Diaspora\\*. You may be on [JoinDiaspora](http://joindiaspora.com/), [Calispora](http://calispora.org/), [Diasp.org](http://diasp.org/), [Diasp.eu](http://diasp.eu/), [Serendipitous](http://ser.endipito.us/) or another pod. You can still connect to people whose accounts are on other pods.\r\n\r\nI have written before about [federation](https://joindiaspora.com/posts/1679098).\r\n\r\nThis is an advantage, because it means that you're not beholden to a single organization's policies. If you decide that you dislike the _podmin_ on Pod X, you can open an account on Pod Y instead or even set up your own pod. (_**Moving** your account is not yet implemented_, but I believe you can export your contacts and use the export to help you repopulate that list on your new pod.) If podmin X decides to shut down pod X, again you can open an account on another pod or host your own.\r\n\r\n## @ mentions\r\n\r\nHit the at-sign and the first few letters of the person's display name (it used to be the first few of the person's username, but then they decided to hide that ... personally, I wish they'd switch back)\r\n\r\nWhen you mention someone, make sure you set the privacy to include the group that person is in. There was a bug (possibly fixed) where you could mention someone in a post they weren't allowed to see. I do not believe that @ mentions work in comments yet.\r\n\r\nTwitter, where at-mentions were invented (by users and 3rd-party clients) doesn't have the problem of at-mentions affecting groups simply because it does not have any form of privacy groups.\r\n\r\n## Hashtags\r\n\r\nDiaspora\\* supports #hashtags. Because your pod intercepts them, being on a bigger pod means that clicking a hashtag will give a larger results set than if you clicked on the hashtag from a smaller pod. It is a known problem of the current federation mechanism, and is being fixed.\r\n\r\nTwitter, where hashtags were invented (by users and 3rd-party clients), doesn't have this problem only because everyone is one the same instance of T. #StatusNet, which is like a federated clone of #Twitter, also has the same issue to some degree.\r\n\r\n## Aspects\r\n\r\nPrivacy groups for posts; these were the obvious inspiration for #GPlus's circles, and they work similarly. For example, you may wish to place your boss and others that you know from work into a work aspect. You may also wish to place people you know from college, church, or other such activities into aspects specific to their roles in your life, and to place family members into aspects specific to people in that role.\r\n\r\nIf you didn't already understand aspects, consider this: if posts are wide-open, anyone who becomes a contact can see them. So if you have your boss as a contact, and you post a photo of your trip to the beach won a day you called in sick, _you may get fired for stupidity_. What you do is you put your boss into a work aspect, and only post things into that aspect that are acceptable in a work context.\r\n\r\n## Posting syntax\r\n\r\nDiaspora\\* uses something called [Markdown](http://www.simpleeditions.com/59001/markdown-an-introduction) for its posts. Most of the time, you can just post in plain text and not worry about it, but every once in a while, Markdown will distort what you've posted.\r\n\r\nMarkdown does give you the ability to _italicize_, **bold**, and otherwise decorate text and to embed links and images using a fairly simple syntax. I find, however, that I have to look up embedding every time I use it.\r\n\r\n(I personally prefer [Textile](http://textile.thresholdstate.com/). You still have to learn to use it effectively, but it more closely matches what experienced net users have grown to expect from applications like Outlook and Thunderbird. For instance, if I want bold text, surround it with single asterisks [\\*] rather than the double asterisks [\\*\\*] that Markdown requires.)\r\n\r\n## Pods\r\n\r\nA Diaspora\\* pod is the server or server cluster where your account resides. There are dozens or even hundreds of pods out there. Most of them are pretty similar in what they offer. A few offer experimental features, such as post previews, pod-only posts, or encrypted messaging. It is my hope that many of these features will be picked up by the main codebase, so that all pods will have them.\r\n\r\nYou'll rarely need to know this, but every Diaspora\\* account has an address that looks like username@podname.com. If you want people to be able to add you as a contact, publish your Diaspora\\* address. They'll be able to add you that way.\r\n\r\n## Facebook\r\n\r\nAll of the pods I have used have the ability to connect to certain external accounts, such as Twitter and #Facebook. This means that you can post from D\\* to FB or T. You don't have to abandon your \"friends\" on other #socnets because you join D\\*.\r\n\r\nIf you read many online articles, you will come across some that seem to believe that Diaspora\\*'s purpose is to become a Facebook-killer. Do not believe them. If and when people tire of Facebook, it will be because of something that FB does, not because socnet X is better. If you look at D\\* as a substitute for Facebook, it will be like a meat-eater who tries to replace meat with soy-based meat substitutes. You won't like it. Instead, I recommend that you get to know people who are on D\\* and that you invite your existing contacts, but that you **enjoy D\\* for its own value**. If you find that it then makes FB unnecessary, that is good. If, on the other hand, you still want to keep your FB account, that is also good.\r\n\r\n## Controversies\r\n\r\nThere are occasional squabbles over the directions the project is taking. Unlike the squabbles at Twitter, which took place behind closed doors and resulted in a number of highly-skilled people leaving and the recently announced restrictions on how client applications can display Twitter-sourced content, Diaspora\\*'s squabbles tend to happen in public. My advice is simple: stay out of the squabbles, find your own philosophical point of view, and support this and any other project that agrees with that point of view. If the time comes when this or any other project no longer fits your POV, leave quietly.\r\n\r\nWhen I felt that GPlus was hostile to my POV, I closed my accounts. When I felt that Facebook was hostile to my POV, I closed my account. I do not go around trash-talking either project, or assuming that anyone in said projects is intentionally \"evil,\" and I would not recommend doing that to D\\* or any other project.\r\n\r\n## Future\r\n\r\nAt some point in the future, the Diaspora\\* developers will be changing the federation protocol. Federation is what enables a user on Pod X to interact with users on pods Y, Z, etc. They are working to improve scalability (ability to handle more content posted from more users in the same period of time) and content dispersion (ability for content to travel between a wider number of pods seamlessly). It is a tough task. If you are interested in #Ruby programming or Ruby on Rails ( #RoR ), I would encourage you to get involved.\r\n\r\nThey are also planning to make D\\* a far more visual-oriented socnet. That means that posts with images, graphics, and video will be far more interesting, and will be displayed in a manner that caters to those things. There is an experimental pod where they test out many of the visual designs that may make it into the D* codebase. I will not link it here, because people may misunderstand that it is experimental and not really intended to be your home pod.\r\n\r\nIf you're interested in the technical side and the future directions, they have a moderated and directed code-chat on IRC every (other?) Thursday at 10AM Pacific in the room #diaspora-meeting on Freenode. Sean can jump in on the comments to correct me on this.\r\n\r\n## Conclusion\r\n\r\nThis is long, but I think this is a good intro to Diaspora\\*. I wish there had been someone who could write something like this when I joined. I should also put in a disclaimer. This is my personal opinion, and not the official stance of any podmin or of the Diaspora\\* developers. You are free to disagree, but please start a new thread for it. This is posted in the hope that people who newly join Diaspora\\* will get a head start.\r\n\r\nThere are a number of tutorials at [Diasporal](http://diasporial.com/). I would encourage you to visit the site and check them out. If you are a blogger, or if you write for a magazine (online or dead-tree), I would encourage you to write about Diaspora\\* once you've taken some time to get to know the place.","public":true,"created_at":"2012-07-05T09:37:15Z","interacted_at":"2012-07-05T09:37:15Z","provider_display_name":null,"post_type":"Reshare","image_url":null,"object_url":null,"favorite":false,"nsfw":false,"author":{"id":2,"guid":"7445f9a0a6c28ebb","name":"Florian Staudacher","diaspora_id":"raven24@pod.fulll.name","avatar":{"small":"https://pod.fulll.name/uploads/images/thumb_small_5f612f44a0a026b119f8.png","medium":"https://pod.fulll.name/uploads/images/thumb_medium_5f612f44a0a026b119f8.png","large":"https://pod.fulll.name/uploads/images/thumb_large_5f612f44a0a026b119f8.png"}},"o_embed_cache":null,"mentioned_people":[],"photos":[],"frame_name":"status","root":{"id":11730,"guid":"57288b4adf721900","text":"# Intro To Using Diaspora\\*\r\n\r\n## Federated Social Networking\r\n\r\nDiaspora\\* is a social network (socnet), similar in many ways to Facebook, #MySpace, #Orkut, and Google Plus ( #GPlus). In fact, those of us who were already using D\\* when GPlus came out were quite familiar with its layout and functionality. It was almost as if they had started developing by grabbing D\\* code and stripping out federation.\r\n\r\nWhen I say federated, I mean that there is not one central Diaspora\\* server (or server cluster) that all users belong to. Instead, there are many [Diaspora\\* servers](http://podupti.me/) to choose from, with different operators ( #podmin), privacy policies, terms of service, and so on. Federation works much like when you decide to mail someone. It doesn't matter to me whether you use Gmail, Hotmail, Ymail, or GMX. I can send messages to you because electronic mail is federated. It is the same way with Diaspora\\*. You may be on [JoinDiaspora](http://joindiaspora.com/), [Calispora](http://calispora.org/), [Diasp.org](http://diasp.org/), [Diasp.eu](http://diasp.eu/), [Serendipitous](http://ser.endipito.us/) or another pod. You can still connect to people whose accounts are on other pods.\r\n\r\nI have written before about [federation](https://joindiaspora.com/posts/1679098).\r\n\r\nThis is an advantage, because it means that you're not beholden to a single organization's policies. If you decide that you dislike the _podmin_ on Pod X, you can open an account on Pod Y instead or even set up your own pod. (_**Moving** your account is not yet implemented_, but I believe you can export your contacts and use the export to help you repopulate that list on your new pod.) If podmin X decides to shut down pod X, again you can open an account on another pod or host your own.\r\n\r\n## @ mentions\r\n\r\nHit the at-sign and the first few letters of the person's display name (it used to be the first few of the person's username, but then they decided to hide that ... personally, I wish they'd switch back)\r\n\r\nWhen you mention someone, make sure you set the privacy to include the group that person is in. There was a bug (possibly fixed) where you could mention someone in a post they weren't allowed to see. I do not believe that @ mentions work in comments yet.\r\n\r\nTwitter, where at-mentions were invented (by users and 3rd-party clients) doesn't have the problem of at-mentions affecting groups simply because it does not have any form of privacy groups.\r\n\r\n## Hashtags\r\n\r\nDiaspora\\* supports #hashtags. Because your pod intercepts them, being on a bigger pod means that clicking a hashtag will give a larger results set than if you clicked on the hashtag from a smaller pod. It is a known problem of the current federation mechanism, and is being fixed.\r\n\r\nTwitter, where hashtags were invented (by users and 3rd-party clients), doesn't have this problem only because everyone is one the same instance of T. #StatusNet, which is like a federated clone of #Twitter, also has the same issue to some degree.\r\n\r\n## Aspects\r\n\r\nPrivacy groups for posts; these were the obvious inspiration for #GPlus's circles, and they work similarly. For example, you may wish to place your boss and others that you know from work into a work aspect. You may also wish to place people you know from college, church, or other such activities into aspects specific to their roles in your life, and to place family members into aspects specific to people in that role.\r\n\r\nIf you didn't already understand aspects, consider this: if posts are wide-open, anyone who becomes a contact can see them. So if you have your boss as a contact, and you post a photo of your trip to the beach won a day you called in sick, _you may get fired for stupidity_. What you do is you put your boss into a work aspect, and only post things into that aspect that are acceptable in a work context.\r\n\r\n## Posting syntax\r\n\r\nDiaspora\\* uses something called [Markdown](http://www.simpleeditions.com/59001/markdown-an-introduction) for its posts. Most of the time, you can just post in plain text and not worry about it, but every once in a while, Markdown will distort what you've posted.\r\n\r\nMarkdown does give you the ability to _italicize_, **bold**, and otherwise decorate text and to embed links and images using a fairly simple syntax. I find, however, that I have to look up embedding every time I use it.\r\n\r\n(I personally prefer [Textile](http://textile.thresholdstate.com/). You still have to learn to use it effectively, but it more closely matches what experienced net users have grown to expect from applications like Outlook and Thunderbird. For instance, if I want bold text, surround it with single asterisks [\\*] rather than the double asterisks [\\*\\*] that Markdown requires.)\r\n\r\n## Pods\r\n\r\nA Diaspora\\* pod is the server or server cluster where your account resides. There are dozens or even hundreds of pods out there. Most of them are pretty similar in what they offer. A few offer experimental features, such as post previews, pod-only posts, or encrypted messaging. It is my hope that many of these features will be picked up by the main codebase, so that all pods will have them.\r\n\r\nYou'll rarely need to know this, but every Diaspora\\* account has an address that looks like username@podname.com. If you want people to be able to add you as a contact, publish your Diaspora\\* address. They'll be able to add you that way.\r\n\r\n## Facebook\r\n\r\nAll of the pods I have used have the ability to connect to certain external accounts, such as Twitter and #Facebook. This means that you can post from D\\* to FB or T. You don't have to abandon your \"friends\" on other #socnets because you join D\\*.\r\n\r\nIf you read many online articles, you will come across some that seem to believe that Diaspora\\*'s purpose is to become a Facebook-killer. Do not believe them. If and when people tire of Facebook, it will be because of something that FB does, not because socnet X is better. If you look at D\\* as a substitute for Facebook, it will be like a meat-eater who tries to replace meat with soy-based meat substitutes. You won't like it. Instead, I recommend that you get to know people who are on D\\* and that you invite your existing contacts, but that you **enjoy D\\* for its own value**. If you find that it then makes FB unnecessary, that is good. If, on the other hand, you still want to keep your FB account, that is also good.\r\n\r\n## Controversies\r\n\r\nThere are occasional squabbles over the directions the project is taking. Unlike the squabbles at Twitter, which took place behind closed doors and resulted in a number of highly-skilled people leaving and the recently announced restrictions on how client applications can display Twitter-sourced content, Diaspora\\*'s squabbles tend to happen in public. My advice is simple: stay out of the squabbles, find your own philosophical point of view, and support this and any other project that agrees with that point of view. If the time comes when this or any other project no longer fits your POV, leave quietly.\r\n\r\nWhen I felt that GPlus was hostile to my POV, I closed my accounts. When I felt that Facebook was hostile to my POV, I closed my account. I do not go around trash-talking either project, or assuming that anyone in said projects is intentionally \"evil,\" and I would not recommend doing that to D\\* or any other project.\r\n\r\n## Future\r\n\r\nAt some point in the future, the Diaspora\\* developers will be changing the federation protocol. Federation is what enables a user on Pod X to interact with users on pods Y, Z, etc. They are working to improve scalability (ability to handle more content posted from more users in the same period of time) and content dispersion (ability for content to travel between a wider number of pods seamlessly). It is a tough task. If you are interested in #Ruby programming or Ruby on Rails ( #RoR ), I would encourage you to get involved.\r\n\r\nThey are also planning to make D\\* a far more visual-oriented socnet. That means that posts with images, graphics, and video will be far more interesting, and will be displayed in a manner that caters to those things. There is an experimental pod where they test out many of the visual designs that may make it into the D* codebase. I will not link it here, because people may misunderstand that it is experimental and not really intended to be your home pod.\r\n\r\nIf you're interested in the technical side and the future directions, they have a moderated and directed code-chat on IRC every (other?) Thursday at 10AM Pacific in the room #diaspora-meeting on Freenode. Sean can jump in on the comments to correct me on this.\r\n\r\n## Conclusion\r\n\r\nThis is long, but I think this is a good intro to Diaspora\\*. I wish there had been someone who could write something like this when I joined. I should also put in a disclaimer. This is my personal opinion, and not the official stance of any podmin or of the Diaspora\\* developers. You are free to disagree, but please start a new thread for it. This is posted in the hope that people who newly join Diaspora\\* will get a head start.\r\n\r\nThere are a number of tutorials at [Diasporal](http://diasporial.com/). I would encourage you to visit the site and check them out. If you are a blogger, or if you write for a magazine (online or dead-tree), I would encourage you to write about Diaspora\\* once you've taken some time to get to know the place.","public":true,"created_at":"2012-07-04T23:41:33Z","interacted_at":"2012-07-05T04:21:21Z","provider_display_name":null,"post_type":"StatusMessage","image_url":null,"object_url":null,"favorite":false,"nsfw":false,"author":{"id":5508,"guid":"25d1ca8dd064f3dd","name":"lnxwalt@calispora.org","diaspora_id":"lnxwalt@calispora.org","avatar":{"small":"https://pod.fulll.name/images/user/default.png","medium":"https://pod.fulll.name/images/user/default.png","large":"https://pod.fulll.name/images/user/default.png"}},"o_embed_cache":null,"mentioned_people":[],"photos":[],"frame_name":"note","root":null,"title":"# Intro To Using Diaspora\\*\r\n\r\n## Federated Social Networking\r\n\r\nDiaspora\\* is a social network (socnet), similar in many ways to Facebook, #MySpace, #Orkut, and Google Plus ( #GPlus). In fact, those of us who were already using D\\* when GPlus came out were quite familiar with its layout and functionality. It was almost as if they had started developing by grabbing D\\* code and stripping out federation.\r\n\r\nWhen I say federated, I mean that there is not one central Diaspora\\* server (or server cluster) that all users belong to. Instead, there are many [Diaspora\\* servers](http://podupti.me/) to choose from, with different operators ( #podmin), privacy policies, terms of service, and so on. Federation works much like when you decide to mail someone. It doesn't matter to me whether you use Gmail, Hotmail, Ymail, or GMX. I can send messages to you because electronic mail is federated. It is the same way with Diaspora\\*. You may be on [JoinDiaspora](http://joindiaspora.com/), [Calispora](http://calispora.org/), [Diasp.org](http://diasp.org/), [Diasp.eu](http://diasp.eu/), [Serendipitous](http://ser.endipito.us/) or another pod. You can still connect to people whose accounts are on other pods.\r\n\r\nI have written before about [federation](https://joindiaspora.com/posts/1679098).\r\n\r\nThis is an advantage, because it means that you're not beholden to a single organization's policies. If you decide that you dislike the _podmin_ on Pod X, you can open an account on Pod Y instead or even set up your own pod. (_**Moving** your account is not yet implemented_, but I believe you can export your contacts and use the export to help you repopulate that list on your new pod.) If podmin X decides to shut down pod X, again you can open an account on another pod or host your own.\r\n\r\n## @ mentions\r\n\r\nHit the at-sign and the first few letters of the person's display name (it used to be the first few of the person's username, but then they decided to hide that ... personally, I wish they'd switch back)\r\n\r\nWhen you mention someone, make sure you set the privacy to include the group that person is in. There was a bug (possibly fixed) where you could mention someone in a post they weren't allowed to see. I do not believe that @ mentions work in comments yet.\r\n\r\nTwitter, where at-mentions were invented (by users and 3rd-party clients) doesn't have the problem of at-mentions affecting groups simply because it does not have any form of privacy groups.\r\n\r\n## Hashtags\r\n\r\nDiaspora\\* supports #hashtags. Because your pod intercepts them, being on a bigger pod means that clicking a hashtag will give a larger results set than if you clicked on the hashtag from a smaller pod. It is a known problem of the current federation mechanism, and is being fixed.\r\n\r\nTwitter, where hashtags were invented (by users and 3rd-party clients), doesn't have this problem only because everyone is one the same instance of T. #StatusNet, which is like a federated clone of #Twitter, also has the same issue to some degree.\r\n\r\n## Aspects\r\n\r\nPrivacy groups for posts; these were the obvious inspiration for #GPlus's circles, and they work similarly. For example, you may wish to place your boss and others that you know from work into a work aspect. You may also wish to place people you know from college, church, or other such activities into aspects specific to their roles in your life, and to place family members into aspects specific to people in that role.\r\n\r\nIf you didn't already understand aspects, consider this: if posts are wide-open, anyone who becomes a contact can see them. So if you have your boss as a contact, and you post a photo of your trip to the beach won a day you called in sick, _you may get fired for stupidity_. What you do is you put your boss into a work aspect, and only post things into that aspect that are acceptable in a work context.\r\n\r\n## Posting syntax\r\n\r\nDiaspora\\* uses something called [Markdown](http://www.simpleeditions.com/59001/markdown-an-introduction) for its posts. Most of the time, you can just post in plain text and not worry about it, but every once in a while, Markdown will distort what you've posted.\r\n\r\nMarkdown does give you the ability to _italicize_, **bold**, and otherwise decorate text and to embed links and images using a fairly simple syntax. I find, however, that I have to look up embedding every time I use it.\r\n\r\n(I personally prefer [Textile](http://textile.thresholdstate.com/). You still have to learn to use it effectively, but it more closely matches what experienced net users have grown to expect from applications like Outlook and Thunderbird. For instance, if I want bold text, surround it with single asterisks [\\*] rather than the double asterisks [\\*\\*] that Markdown requires.)\r\n\r\n## Pods\r\n\r\nA Diaspora\\* pod is the server or server cluster where your account resides. There are dozens or even hundreds of pods out there. Most of them are pretty similar in what they offer. A few offer experimental features, such as post previews, pod-only posts, or encrypted messaging. It is my hope that many of these features will be picked up by the main codebase, so that all pods will have them.\r\n\r\nYou'll rarely need to know this, but every Diaspora\\* account has an address that looks like username@podname.com. If you want people to be able to add you as a contact, publish your Diaspora\\* address. They'll be able to add you that way.\r\n\r\n## Facebook\r\n\r\nAll of the pods I have used have the ability to connect to certain external accounts, such as Twitter and #Facebook. This means that you can post from D\\* to FB or T. You don't have to abandon your \"friends\" on other #socnets because you join D\\*.\r\n\r\nIf you read many online articles, you will come across some that seem to believe that Diaspora\\*'s purpose is to become a Facebook-killer. Do not believe them. If and when people tire of Facebook, it will be because of something that FB does, not because socnet X is better. If you look at D\\* as a substitute for Facebook, it will be like a meat-eater who tries to replace meat with soy-based meat substitutes. You won't like it. Instead, I recommend that you get to know people who are on D\\* and that you invite your existing contacts, but that you **enjoy D\\* for its own value**. If you find that it then makes FB unnecessary, that is good. If, on the other hand, you still want to keep your FB account, that is also good.\r\n\r\n## Controversies\r\n\r\nThere are occasional squabbles over the directions the project is taking. Unlike the squabbles at Twitter, which took place behind closed doors and resulted in a number of highly-skilled people leaving and the recently announced restrictions on how client applications can display Twitter-sourced content, Diaspora\\*'s squabbles tend to happen in public. My advice is simple: stay out of the squabbles, find your own philosophical point of view, and support this and any other project that agrees with that point of view. If the time comes when this or any other project no longer fits your POV, leave quietly.\r\n\r\nWhen I felt that GPlus was hostile to my POV, I closed my accounts. When I felt that Facebook was hostile to my POV, I closed my account. I do not go around trash-talking either project, or assuming that anyone in said projects is intentionally \"evil,\" and I would not recommend doing that to D\\* or any other project.\r\n\r\n## Future\r\n\r\nAt some point in the future, the Diaspora\\* developers will be changing the federation protocol. Federation is what enables a user on Pod X to interact with users on pods Y, Z, etc. They are working to improve scalability (ability to handle more content posted from more users in the same period of time) and content dispersion (ability for content to travel between a wider number of pods seamlessly). It is a tough task. If you are interested in #Ruby programming or Ruby on Rails ( #RoR ), I would encourage you to get involved.\r\n\r\nThey are also planning to make D\\* a far more visual-oriented socnet. That means that posts with images, graphics, and video will be far more interesting, and will be displayed in a manner that caters to those things. There is an experimental pod where they test out many of the visual designs that may make it into the D* codebase. I will not link it here, because people may misunderstand that it is experimental and not really intended to be your home pod.\r\n\r\nIf you're interested in the technical side and the future directions, they have a moderated and directed code-chat on IRC every (other?) Thursday at 10AM Pacific in the room #diaspora-meeting on Freenode. Sean can jump in on the comments to correct me on this.\r\n\r\n## Conclusion\r\n\r\nThis is long, but I think this is a good intro to Diaspora\\*. I wish there had been someone who could write something like this when I joined. I should also put in a disclaimer. This is my personal opinion, and not the official stance of any podmin or of the Diaspora\\* developers. You are free to disagree, but please start a new thread for it. This is posted in the hope that people who newly join Diaspora\\* will get a head start.\r\n\r\nThere are a number of tutorials at [Diasporal](http://diasporial.com/). I would encourage you to visit the site and check them out. If you are a blogger, or if you write for a magazine (online or dead-tree), I would encourage you to write about Diaspora\\* once you've taken some time to get to know the place.","next_post":"/posts/11730/next","previous_post":"/posts/11730/previous","interactions":{"likes":[],"reshares":[],"comments_count":0,"likes_count":0,"reshares_count":4}},"title":"A post from Florian Staudacher","next_post":"/posts/11774/next","previous_post":"/posts/11774/previous","interactions":{"likes":[],"reshares":[],"comments_count":0,"likes_count":0,"reshares_count":0,"comments":[]}},{"id":11725,"guid":"909471c6070243be","text":"If you think you know of a #Diaspora #Bug please remember to be as specific as possible when describing it so we can help!!","public":true,"created_at":"2012-07-04T23:29:43Z","interacted_at":"2012-07-04T23:29:43Z","provider_display_name":null,"post_type":"Reshare","image_url":null,"object_url":null,"favorite":false,"nsfw":false,"author":{"id":2,"guid":"7445f9a0a6c28ebb","name":"Florian Staudacher","diaspora_id":"raven24@pod.fulll.name","avatar":{"small":"https://pod.fulll.name/uploads/images/thumb_small_5f612f44a0a026b119f8.png","medium":"https://pod.fulll.name/uploads/images/thumb_medium_5f612f44a0a026b119f8.png","large":"https://pod.fulll.name/uploads/images/thumb_large_5f612f44a0a026b119f8.png"}},"o_embed_cache":null,"mentioned_people":[],"photos":[],"frame_name":"status","root":{"id":11718,"guid":"c1770c590b097c28","text":"If you think you know of a #Diaspora #Bug please remember to be as specific as possible when describing it so we can help!!","public":true,"created_at":"2012-07-04T22:00:49Z","interacted_at":"2012-07-05T08:19:07Z","provider_display_name":null,"post_type":"StatusMessage","image_url":null,"object_url":null,"favorite":false,"nsfw":false,"author":{"id":5653,"guid":"7410329c39e6810f","name":"Hans","diaspora_id":"hans@hfase.com","avatar":{"small":"https://hfase.com/uploads/images/thumb_small_f2b2d6b041732c5f91eb.jpg","medium":"https://hfase.com/uploads/images/thumb_medium_f2b2d6b041732c5f91eb.jpg","large":"https://hfase.com/uploads/images/thumb_large_f2b2d6b041732c5f91eb.jpg"}},"o_embed_cache":null,"mentioned_people":[],"photos":[],"frame_name":"status","root":null,"title":"If you think you know of a #Diaspora #Bug please remember to be as specific as possible when describing it so we can help!!","next_post":"/posts/11718/next","previous_post":"/posts/11718/previous","interactions":{"likes":[],"reshares":[{"reshare":{"actor_url":null,"author_id":2,"comments_count":0,"created_at":"2012-07-04T23:29:43Z","diaspora_handle":"raven24@pod.fulll.name","favorite":false,"frame_name":null,"guid":"909471c6070243be","id":11725,"image_height":null,"image_url":null,"image_width":null,"interacted_at":"2012-07-04T23:29:43Z","likes_count":0,"o_embed_cache_id":null,"objectId":null,"object_url":null,"pending":false,"processed_image":null,"provider_display_name":null,"public":true,"random_string":null,"remote_photo_name":null,"remote_photo_path":null,"reshares_count":0,"root_guid":"c1770c590b097c28","status_message_guid":null,"text":null,"unprocessed_image":null,"updated_at":"2012-07-04T23:29:43Z"}}],"comments_count":0,"likes_count":2,"reshares_count":2}},"title":"A post from Florian Staudacher","next_post":"/posts/11725/next","previous_post":"/posts/11725/previous","interactions":{"likes":[],"reshares":[],"comments_count":0,"likes_count":0,"reshares_count":0,"comments":[]}}]
\ No newline at end of file
diff --git a/spec/lib/diaspora/fetcher/public_spec.rb b/spec/lib/diaspora/fetcher/public_spec.rb
new file mode 100644
index 000000000..5d21686f2
--- /dev/null
+++ b/spec/lib/diaspora/fetcher/public_spec.rb
@@ -0,0 +1,211 @@
+# Copyright (c) 2010-2012, Diaspora Inc. This file is
+# licensed under the Affero General Public License version 3 or later. See
+# the COPYRIGHT file.
+
+require Rails.root.join('lib','diaspora','fetcher','public')
+require 'spec_helper'
+
+# Tests fetching public posts of a person on a remote server
+describe PublicFetcher do
+ before do
+
+ # the fixture is taken from an actual json request.
+ # it contains 10 StatusMessages and 5 Reshares, all of them public
+ # the guid of the person is "7445f9a0a6c28ebb"
+ @fixture = File.open(Rails.root.join('spec', 'fixtures', 'public_posts.json')).read
+ @fetcher = PublicFetcher.new
+ @person = Factory(:person, {:guid => "7445f9a0a6c28ebb",
+ :url => "https://remote-testpod.net",
+ :diaspora_handle => "testuser@remote-testpod.net"})
+
+ stub_request(:get, /remote-testpod.net\/people\/.*/)
+ .with(:headers => {'Accept'=>'application/json'})
+ .to_return(:body => @fixture)
+ end
+
+ describe "#retrieve_posts" do
+ before do
+ person = @person
+ @fetcher.instance_eval {
+ @person = person
+ retrieve_posts
+ }
+ end
+
+ it "sets the operation status on the person" do
+ @person.reload
+ @person.fetch_status.should_not eql(PublicFetcher::Status_Initial)
+ @person.fetch_status.should eql(PublicFetcher::Status_Fetched)
+ end
+
+ it "sets the @data variable to the parsed JSON data" do
+ data = @fetcher.instance_eval {
+ @data
+ }
+ data.should_not be_nil
+ data.size.should eql JSON.parse(@fixture).size
+ end
+ end
+
+ describe "#process_posts" do
+ before do
+ person = @person
+ data = JSON.parse(@fixture)
+
+ @fetcher.instance_eval {
+ @person = person
+ @data = data
+ }
+ end
+
+ it 'creates 10 new posts in the database' do
+ before_count = Post.count
+ @fetcher.instance_eval {
+ process_posts
+ }
+ after_count = Post.count
+ after_count.should eql(before_count + 10)
+ end
+
+ it 'sets the operation status on the person' do
+ @fetcher.instance_eval {
+ process_posts
+ }
+
+ @person.reload
+ @person.fetch_status.should_not eql(PublicFetcher::Status_Initial)
+ @person.fetch_status.should eql(PublicFetcher::Status_Processed)
+ end
+ end
+
+ context "private methods" do
+ let(:public_fetcher) { PublicFetcher.new }
+
+ describe '#qualifies_for_fetching?' do
+ it "raises an error if the person doesn't exist" do
+ lambda {
+ public_fetcher.instance_eval {
+ @person = Person.by_account_identifier "someone@unknown.com"
+ qualifies_for_fetching?
+ }
+ }.should raise_error ActiveRecord::RecordNotFound
+ end
+
+ it 'returns false if the person is unfetchable' do
+ public_fetcher.instance_eval {
+ @person = Factory(:person, {:fetch_status => PublicFetcher::Status_Unfetchable})
+ qualifies_for_fetching?
+ }.should be_false
+ end
+
+ it 'returns false and sets the person unfetchable for a local account' do
+ user = Factory(:user)
+ public_fetcher.instance_eval {
+ @person = user.person
+ qualifies_for_fetching?
+ }.should be_false
+ user.person.fetch_status.should eql PublicFetcher::Status_Unfetchable
+ end
+
+ it 'returns false if the person is processing already (or has been processed)' do
+ person = Factory(:person)
+ person.fetch_status = PublicFetcher::Status_Fetched
+ person.save
+ public_fetcher.instance_eval {
+ @person = person
+ qualifies_for_fetching?
+ }.should be_false
+ end
+
+ it "returns true, if the user is remote and hasn't been fetched" do
+ person = Factory(:person, {:diaspora_handle => 'neo@theone.net'})
+ public_fetcher.instance_eval {
+ @person = person
+ qualifies_for_fetching?
+ }.should be_true
+ end
+ end
+
+ describe '#set_fetch_status' do
+ it 'sets the current status of fetching on the person' do
+ person = @person
+ public_fetcher.instance_eval {
+ @person = person
+ set_fetch_status PublicFetcher::Status_Unfetchable
+ }
+ @person.fetch_status.should eql PublicFetcher::Status_Unfetchable
+
+ public_fetcher.instance_eval {
+ set_fetch_status PublicFetcher::Status_Initial
+ }
+ @person.fetch_status.should eql PublicFetcher::Status_Initial
+ end
+ end
+
+ describe '#validate' do
+ it "calls all validation helper methods" do
+ public_fetcher.should_receive(:check_existing).and_return(true)
+ public_fetcher.should_receive(:check_author).and_return(true)
+ public_fetcher.should_receive(:check_public).and_return(true)
+ public_fetcher.should_receive(:check_type).and_return(true)
+
+ public_fetcher.instance_eval { validate({}) }.should be_true
+ end
+ end
+
+ describe '#check_existing' do
+ it 'returns false if a post with the same guid exists' do
+ post = {'guid' => Factory(:status_message).guid}
+ public_fetcher.instance_eval { check_existing post }.should be_false
+ end
+
+ it 'returns true if the guid cannot be found' do
+ post = {'guid' => SecureRandom.hex(8)}
+ public_fetcher.instance_eval { check_existing post }.should be_true
+ end
+ end
+
+ describe '#check_author' do
+ let!(:some_person) { Factory(:person) }
+
+ before do
+ person = some_person
+ public_fetcher.instance_eval { @person = person }
+ end
+
+ it "returns false if the person doesn't match" do
+ post = { 'author' => { 'guid' => SecureRandom.hex(8) } }
+ public_fetcher.instance_eval { check_author post }.should be_false
+ end
+
+ it "returns true if the persons match" do
+ post = { 'author' => { 'guid' => some_person.guid } }
+ public_fetcher.instance_eval { check_author post }.should be_true
+ end
+ end
+
+ describe '#check_public' do
+ it "returns false if the post is not public" do
+ post = {'public' => false}
+ public_fetcher.instance_eval { check_public post }.should be_false
+ end
+
+ it "returns true if the post is public" do
+ post = {'public' => true}
+ public_fetcher.instance_eval { check_public post }.should be_true
+ end
+ end
+
+ describe '#check_type' do
+ it "returns false if the type is anything other that 'StatusMessage'" do
+ post = {'post_type'=>'Reshare'}
+ public_fetcher.instance_eval { check_type post }.should be_false
+ end
+
+ it "returns true if the type is 'StatusMessage'" do
+ post = {'post_type'=>'StatusMessage'}
+ public_fetcher.instance_eval { check_type post }.should be_true
+ end
+ end
+ end
+end
\ No newline at end of file