This commit is contained in:
mishudark 2010-09-17 22:03:13 -05:00
commit 4d4adc91ee
48 changed files with 726 additions and 275 deletions

View file

@ -28,9 +28,12 @@ gem 'redfinger', :git => 'git://github.com/rsofaer/redfinger.git'
#EventMachine #EventMachine
gem 'em-http-request',:git => 'git://github.com/igrigorik/em-http-request.git', :require => 'em-http' gem 'em-http-request',:git => 'git://github.com/igrigorik/em-http-request.git', :require => 'em-http'
gem 'em-websocket'
gem 'thin' gem 'thin'
#Websocket
gem 'em-websocket'
gem 'magent', :git => 'http://github.com/dcu/magent.git'
#File uploading #File uploading
gem 'carrierwave', :git => 'git://github.com/rsofaer/carrierwave.git' , :branch => 'master' #Untested mongomapper branch gem 'carrierwave', :git => 'git://github.com/rsofaer/carrierwave.git' , :branch => 'master' #Untested mongomapper branch
gem 'mini_magick' gem 'mini_magick'

View file

@ -47,6 +47,14 @@ GIT
bcrypt-ruby (~> 2.1.2) bcrypt-ruby (~> 2.1.2)
warden (~> 0.10.7) warden (~> 0.10.7)
GIT
remote: http://github.com/dcu/magent.git
revision: 06513f3dac812469a55f2e365c349af4d2abc92a
specs:
magent (0.4.2)
mongo (>= 0.1.0)
uuidtools (>= 2.0.0)
GIT GIT
remote: http://github.com/jnunemaker/mongomapper.git remote: http://github.com/jnunemaker/mongomapper.git
revision: 931dab779011aa7acf60c1a4c7ad19e1ba838345 revision: 931dab779011aa7acf60c1a4c7ad19e1ba838345
@ -213,6 +221,7 @@ GEM
treetop (1.4.8) treetop (1.4.8)
polyglot (>= 0.3.1) polyglot (>= 0.3.1)
tzinfo (0.3.23) tzinfo (0.3.23)
uuidtools (2.1.1)
warden (0.10.7) warden (0.10.7)
rack (>= 1.0.0) rack (>= 1.0.0)
webmock (1.3.5) webmock (1.3.5)
@ -242,6 +251,7 @@ DEPENDENCIES
haml haml
jnunemaker-validatable (= 1.8.4)! jnunemaker-validatable (= 1.8.4)!
json json
magent!
mini_magick mini_magick
mocha mocha
mongo_mapper (= 0.8.4)! mongo_mapper (= 0.8.4)!

View file

@ -3,7 +3,7 @@ You are welcome to contribute, add and extend Diaspora however you see fit. We
We need you to fill out a [contributor agreement form](https://spreadsheets.google.com/a/joindiaspora.com/viewform?formkey=dGI2cHA3ZnNHLTJvbm10LUhXRTJjR0E6MQ&theme=0AX42CRMsmRFbUy1iOGYwN2U2Mi1hNWU0LTRlNjEtYWMyOC1lZmU4ODg1ODc1ODI&ifq) before we can accept your patches. The agreement gives Diaspora joint ownership of the patch so the copyright isn't scattered. You can find it [here](https://spreadsheets.google.com/a/joindiaspora.com/viewform?formkey=dGI2cHA3ZnNHLTJvbm10LUhXRTJjR0E6MQ&theme=0AX42CRMsmRFbUy1iOGYwN2U2Mi1hNWU0LTRlNjEtYWMyOC1lZmU4ODg1ODc1ODI&ifq). We need you to fill out a [contributor agreement form](https://spreadsheets.google.com/a/joindiaspora.com/viewform?formkey=dGI2cHA3ZnNHLTJvbm10LUhXRTJjR0E6MQ&theme=0AX42CRMsmRFbUy1iOGYwN2U2Mi1hNWU0LTRlNjEtYWMyOC1lZmU4ODg1ODc1ODI&ifq) before we can accept your patches. The agreement gives Diaspora joint ownership of the patch so the copyright isn't scattered. You can find it [here](https://spreadsheets.google.com/a/joindiaspora.com/viewform?formkey=dGI2cHA3ZnNHLTJvbm10LUhXRTJjR0E6MQ&theme=0AX42CRMsmRFbUy1iOGYwN2U2Mi1hNWU0LTRlNjEtYWMyOC1lZmU4ODg1ODc1ODI&ifq).
All commits must be tested, and after each commit, all tests should be green before a pull request is sent. Please write your tests in Rspec or Test-Unit. All commits must be tested, and after each commit, all tests should be green before a pull request is sent. Please write your tests in Rspec.
GEMS: We would like to keep external dependencies unduplicated. We're using Nokogiri, and Mongomapper, and EM::HttpRequest as much as possible. We have a few gems in the project we'd rather not use, but if you can, use dependencies we already have. GEMS: We would like to keep external dependencies unduplicated. We're using Nokogiri, and Mongomapper, and EM::HttpRequest as much as possible. We have a few gems in the project we'd rather not use, but if you can, use dependencies we already have.
@ -12,6 +12,13 @@ GEMS: We would like to keep external dependencies unduplicated. We're using No
The privacy aware, personally controlled, do-it-all, open source social network. The privacy aware, personally controlled, do-it-all, open source social network.
**DISCLAIMER: THIS IS PRE-ALPHA SOFTWARE AND SHOULD BE TREATED ACCORDINGLY.** **DISCLAIMER: THIS IS PRE-ALPHA SOFTWARE AND SHOULD BE TREATED ACCORDINGLY.**
**PLEASE, DO NOT RUN IN PRODUCTION. IT IS FUN TO GET RUNNING, BUT EXPECT THINGS TO BE BROKEN**
Also, we really want to continue to focus on features and improving the code base. When we think it is
ready for general use, we will post more detailed instructions.
These instructions are for machines running [Ubuntu](http://www.ubuntu.com/), [Fedora](http://www.fedoraproject.org) or Mac OS X. We are developing Diaspora for the latest and greatest browsers, so please update your Firefox, Chrome or Safari to the latest and greatest. These instructions are for machines running [Ubuntu](http://www.ubuntu.com/), [Fedora](http://www.fedoraproject.org) or Mac OS X. We are developing Diaspora for the latest and greatest browsers, so please update your Firefox, Chrome or Safari to the latest and greatest.
## Preparing your system ## Preparing your system
@ -49,6 +56,8 @@ To install Ruby 1.8.7 on **Ubuntu**, run the following command:
sudo apt-get install ruby-full sudo apt-get install ruby-full
Please note that you need to have Universe enabled in your /etc/apt/sources.list file to install ruby using apt-get.
At this time Fedora does not have Ruby 1.8.7. As a workaround it is possible to use [rvm](http://rvm.beginrescueend.com/) with a locally compiled Ruby installation. A semi automated method for doing this is available. It is highly recommended that you review the script before running it so you understand what will occur. The script can be executed by running the following command: At this time Fedora does not have Ruby 1.8.7. As a workaround it is possible to use [rvm](http://rvm.beginrescueend.com/) with a locally compiled Ruby installation. A semi automated method for doing this is available. It is highly recommended that you review the script before running it so you understand what will occur. The script can be executed by running the following command:
./script/bootstrap-fedora-diaspora.sh ./script/bootstrap-fedora-diaspora.sh
@ -64,7 +73,7 @@ To install MongoDB on **Ubuntu**, add the official MongoDB repository from this
http://www.mongodb.org/display/DOCS/Ubuntu+and+Debian+packages http://www.mongodb.org/display/DOCS/Ubuntu+and+Debian+packages
For Lucid, add the following line to your /etc/apt/sources.list: For Lucid, add the following line to your /etc/apt/sources.list (for other distros, see http://www.mongodb.org/display/DOCS/Ubuntu+and+Debian+packages):
deb http://downloads.mongodb.org/distros/ubuntu 10.4 10gen deb http://downloads.mongodb.org/distros/ubuntu 10.4 10gen
@ -110,6 +119,8 @@ If you're running a 32-bit system, run `wget http://fastdl.mongodb.org/linux/mon
To install MongoDB on **Mac OS X**, run the following: To install MongoDB on **Mac OS X**, run the following:
brew install mongo brew install mongo
sudo mkdir -p /data/db
sudo chmod -Rv 777 /data/
### OpenSSL ### OpenSSL
@ -147,13 +158,13 @@ To install Git on **Mac OS X**, run the following:
### Rubygems ### Rubygems
On **Ubuntu**, run the following: On **Ubuntu** 10.04, run the following:
wget http://production.cf.rubygems.org/rubygems/rubygems-1.3.7.tgz sudo add-apt-repository ppa:maco.m/ruby
tar -xf rubygems-1.3.7.tgz sudo apt-get update
cd rubygems-1.3.7 sudo apt-get install rubygems
sudo ruby setup.rb
sudo ln -s /usr/bin/gem1.8 /usr/bin/gem This PPA is maintained by an Ubuntu Developer. For Ubuntu 10.10, this version of rubygems is in the repositories.
On **Fedora**, run the following: On **Fedora**, run the following:
@ -164,7 +175,7 @@ On **Mac OS X**, RubyGems comes preinstalled; however, you might need to update
### Bundler ### Bundler
After RubyGems is updated, simply run `sudo gem install bundler` to get Bundler. After RubyGems is updated, simply run `sudo gem install bundler` to get Bundler. If you're using Ubuntu repository .debs, bundler is found at /var/lib/gems/1.8/bin/bundle
## Getting Diaspora ## Getting Diaspora
@ -184,11 +195,19 @@ If you installed the Ubuntu package, MongoDB should already be running (if not,
If you installed the Fedora package, MongoDB will need to be started via `service mongodb start`. If you installed the binary manually, run `sudo mongod` from where mongo is installed to start mongo. If you installed the Fedora package, MongoDB will need to be started via `service mongodb start`. If you installed the binary manually, run `sudo mongod` from where mongo is installed to start mongo.
If you installed the OsX package through "brew", MongoDB will need to be started via `sudo launchctl load /Library/LaunchDaemons/org.mongodb.mongod.plist`. (before you have to go to /Library/LaunchDaemons and add a symlink to /usr/local/Cellar/mongodb/1.6.2-x86_64/org.mongodb.mongod.plist)
Diaspora will not run unless mongo is running. Mongo will not run by default, and will need to be started every time you wish to use or run the test suite for Diaspora. Diaspora will not run unless mongo is running. Mongo will not run by default, and will need to be started every time you wish to use or run the test suite for Diaspora.
### Run the server
`./script/server` will start both thin and the websocket server. If you want to run a different app server, you will have to run them separately. See below for instructions.
### Run the app server ### Run the app server
Once mongo is running and bundler has finished, run `bundle exec thin start` from the root Diaspora directory. This will start the app server in development mode[.](http://bit.ly/9mwtUw) Once mongo is running and bundler has finished, run `bundle exec thin start` from the root Diaspora directory. This will start the app server in development mode[.](http://bit.ly/9mwtUw)
### Run the websocket server
run `bundle exec ruby ./script/websocket_server` to start the websocket server on port 8080. Change the port in config/app_config.yml.
### Logging in ### Logging in
Run `rake db:seed:tom`, then login with user `tom` and password `evankorth`. More details in db/seeds/tom.rb. Run `rake db:seed:tom`, then login with user `tom` and password `evankorth`. More details in db/seeds/tom.rb.
@ -201,9 +220,9 @@ Diaspora's test suite uses [rspec](http://rspec.info/), a behavior driven testin
We are maintaining a [public tracker project](http://www.pivotaltracker.com/projects/61641) and a [roadmap](https://github.com/diaspora/diaspora/wiki/Roadmap). Also, you can file [bug reports](https://github.com/diaspora/diaspora/issues) right here on github. We are maintaining a [public tracker project](http://www.pivotaltracker.com/projects/61641) and a [roadmap](https://github.com/diaspora/diaspora/wiki/Roadmap). Also, you can file [bug reports](https://github.com/diaspora/diaspora/issues) right here on github.
Ongoing discussion: Ongoing discussion:
- [Diaspora Developer Google Group](http://groups.google.com/group/diaspora-dev) - [Diaspora Developer Google Group](http://groups.google.com/group/diaspora-dev)
- [Diaspora Discussion Google Group](http://groups.google.com/group/diaspora-discuss) - [Diaspora Discussion Google Group](http://groups.google.com/group/diaspora-discuss)
- [Diaspora Q&A site](http://diaspora.shapado.com/)
- [#diaspora-dev](irc://irc.freenode.net/#diaspora-dev) - [#diaspora-dev](irc://irc.freenode.net/#diaspora-dev)
More general info and updates about the project can be found on our [blog](http://joindiaspora.com), [twitter](http://twitter.com/joindiaspora). Also, be sure to join the official [mailing list](http://http://eepurl.com/Vebk). More general info and updates about the project can be found on our [blog](http://joindiaspora.com), [twitter](http://twitter.com/joindiaspora). Also, be sure to join the official [mailing list](http://http://eepurl.com/Vebk).

View file

@ -26,7 +26,7 @@ class AlbumsController < ApplicationController
end end
def destroy def destroy
@album = Album.find_by_id params[:id] @album = current_user.album_by_id params[:id]
@album.destroy @album.destroy
flash[:notice] = "Album #{@album.name} deleted." flash[:notice] = "Album #{@album.name} deleted."
respond_with :location => albums_url respond_with :location => albums_url
@ -41,12 +41,12 @@ class AlbumsController < ApplicationController
end end
def edit def edit
@album = Album.find_by_id params[:id] @album = current_user.album_by_id params[:id]
redirect_to @album unless current_user.owns? @album redirect_to @album unless current_user.owns? @album
end end
def update def update
@album = Album.find_by_id params[:id] @album = current_user.album_by_id params[:id]
if @album.update_attributes params[:album] if @album.update_attributes params[:album]
flash[:notice] = "Album #{@album.name} successfully edited." flash[:notice] = "Album #{@album.name} successfully edited."
respond_with @album respond_with @album

View file

@ -26,9 +26,15 @@ class AspectsController < ApplicationController
def destroy def destroy
@aspect = Aspect.find_by_id params[:id] @aspect = Aspect.find_by_id params[:id]
@aspect.destroy
flash[:notice] = "You are no longer sharing the aspect called #{@aspect.name}." begin
respond_with :location => aspects_url current_user.drop_aspect @aspect
flash[:notice] = "#{@aspect.name} was successfully removed."
rescue RuntimeError => e
flash[:error] = e.message
end
respond_with :location => aspects_manage_path
end end
def show def show
@ -41,7 +47,7 @@ class AspectsController < ApplicationController
def manage def manage
@aspect = :manage @aspect = :manage
@remote_requests = Request.for_user current_user @remote_requests = Request.for_user(current_user).all
end end
def update def update

View file

@ -14,7 +14,7 @@ class SocketsController < ApplicationController
def outgoing(uid,object,opts={}) def outgoing(uid,object,opts={})
@_request = ActionDispatch::Request.new({}) @_request = ActionDispatch::Request.new({})
Diaspora::WebSocket.push_to_user(uid, action_hash(uid, object, opts)) Diaspora::WebSocket.queue_to_user(uid, action_hash(uid, object, opts))
end end
end end

View file

@ -7,13 +7,6 @@ class UsersController < ApplicationController
before_filter :authenticate_user!, :except => [:new, :create] before_filter :authenticate_user!, :except => [:new, :create]
respond_to :html respond_to :html
respond_to :json, :only => :show
def show
@user = User.find_by_id params[:id]
@user_profile = @user.person.profile
respond_with @user
end
def edit def edit
@user = current_user @user = current_user
@ -23,7 +16,7 @@ class UsersController < ApplicationController
end end
def update def update
@user = User.find_by_id params[:id] @user = current_user
prep_image_url(params[:user]) prep_image_url(params[:user])
@user.update_profile params[:user] @user.update_profile params[:user]

View file

@ -7,4 +7,12 @@ module AspectsHelper
def link_for_aspect( aspect ) def link_for_aspect( aspect )
link_to aspect.name, aspect link_to aspect.name, aspect
end end
def remove_link( aspect )
if aspect.people.size == 0
link_to "remove", aspect, :method => :delete
else
"<span class='grey' title='Aspect not empty'>remove</span>"
end
end
end end

View file

@ -85,9 +85,12 @@ class Person
local_person local_person
elsif !identifier.include?("localhost") && !opts[:local] elsif !identifier.include?("localhost") && !opts[:local]
begin begin
Rails.logger.info("Webfingering #{identifier}")
f = Redfinger.finger(identifier) f = Redfinger.finger(identifier)
rescue SocketError => e rescue SocketError => e
raise "Diaspora server for #{identifier} not found" if e.message =~ /Name or service not known/ raise "Diaspora server for #{identifier} not found" if e.message =~ /Name or service not known/
rescue Errno::ETIMEDOUT => e
raise "Connection timed out to Diaspora server for #{identifier}"
end end
raise "No webfinger profile found at #{identifier}" if f.nil? || f.links.empty? raise "No webfinger profile found at #{identifier}" if f.nil? || f.links.empty?
Person.from_webfinger_profile(identifier, f ) Person.from_webfinger_profile(identifier, f )

View file

@ -4,6 +4,7 @@
class Post class Post
require 'lib/diaspora/websocket'
require 'lib/encryptable' require 'lib/encryptable'
include MongoMapper::Document include MongoMapper::Document
include ApplicationHelper include ApplicationHelper
@ -17,7 +18,7 @@ class Post
key :person_id, ObjectId key :person_id, ObjectId
key :user_refs, Integer, :default => 0 key :user_refs, Integer, :default => 0
many :comments, :class_name => 'Comment', :foreign_key => :post_id many :comments, :class_name => 'Comment', :foreign_key => :post_id, :order => 'created_at ASC'
belongs_to :person, :class_name => 'Person' belongs_to :person, :class_name => 'Person'
timestamps! timestamps!

View file

@ -34,7 +34,6 @@ class User
many :aspects, :class_name => 'Aspect' many :aspects, :class_name => 'Aspect'
after_create :seed_aspects after_create :seed_aspects
before_validation_on_create :downcase_username before_validation_on_create :downcase_username
@ -65,6 +64,15 @@ class User
Aspect.create(opts) Aspect.create(opts)
end end
def drop_aspect( aspect )
if aspect.people.size == 0
aspect.destroy
else
raise "Aspect not empty"
end
end
def move_friend( opts = {}) def move_friend( opts = {})
return true if opts[:to] == opts[:from] return true if opts[:to] == opts[:from]
friend = Person.first(:_id => opts[:friend_id]) friend = Person.first(:_id => opts[:friend_id])
@ -230,8 +238,7 @@ class User
Rails.logger.info( "the person id is #{object.post_id} the friend found is #{visible_person_by_id(object.post_id).inspect}") Rails.logger.info( "the person id is #{object.post_id} the friend found is #{visible_person_by_id(object.post_id).inspect}")
unfriended_by visible_person_by_id(object.post_id) unfriended_by visible_person_by_id(object.post_id)
else
else
object.perform self.id object.perform self.id
aspects = self.aspects_with_person(object.person) aspects = self.aspects_with_person(object.person)
aspects.each{ |aspect| aspect.post_ids.delete(object.post_id.to_id) aspects.each{ |aspect| aspect.post_ids.delete(object.post_id.to_id)

View file

@ -12,7 +12,7 @@
Requests Requests
.requests .requests
%ul %ul.dropzone
- for request in @remote_requests - for request in @remote_requests
%li.requested_person{:id => request.person.id, :request_id => request.id} %li.requested_person{:id => request.person.id, :request_id => request.id}
= person_image_tag(request.person) = person_image_tag(request.person)
@ -22,7 +22,7 @@
Ignore/Remove Ignore/Remove
%li.remove %li.remove
%ul %ul.dropzone
- content_for :publish do - content_for :publish do
= link_to("add a new aspect", "#add_aspect_pane", :id => "add_aspect_button", :class => "new_aspect button", :title => "Add a new aspect") = link_to("add a new aspect", "#add_aspect_pane", :id => "add_aspect_button", :class => "new_aspect button", :title => "Add a new aspect")
@ -36,12 +36,12 @@
.aspect_name .aspect_name
%h1{:contenteditable => true}= aspect.name %h1{:contenteditable => true}= aspect.name
.tools %ul.tools
= link_to "add a new friend", "#add_request_pane_#{aspect.id}", :class => 'add_request_button' %li= link_to "add a new friend", "#add_request_pane_#{aspect.id}", :class => 'add_request_button'
| %li= link_to "show", aspect_path(aspect)
= link_to "show", aspect_path(aspect) %li!= remove_link(aspect)
%ul{:id => aspect.id} %ul.dropzone{:id => aspect.id}
-if aspect.people.size < 1 -if aspect.people.size < 1
%li.grey Drag to add people %li.grey Drag to add people

View file

@ -9,7 +9,7 @@
element: document.getElementById('file-upload'), element: document.getElementById('file-upload'),
params: {'album_id' : "#{@album.id}"}, params: {'album_id' : "#{@album.id}"},
allowedExtensions: ['jpg', 'jpeg', 'png'], allowedExtensions: ['jpg', 'jpeg', 'png'],
action: "/photos" action: "#{photos_path}"
}); });
} }
window.onload = createUploader; window.onload = createUploader;

View file

@ -7,6 +7,9 @@
%h5 DEBUG INFO %h5 DEBUG INFO
#debug_more{ :style => "display:none;" } #debug_more{ :style => "display:none;" }
%ul %ul
%li
%b
= GIT_INFO
%li %li
%b params %b params
= params.inspect = params.inspect
@ -14,3 +17,4 @@
%b websocket status %b websocket status
#debug #debug
.msg .msg

View file

@ -8,6 +8,7 @@ development:
debug: false debug: false
socket_debug : false socket_debug : false
socket_port: 8080 socket_port: 8080
socket_collection_name: 'websocket'
pubsub_server: 'https://pubsubhubbub.appspot.com/' pubsub_server: 'https://pubsubhubbub.appspot.com/'
test: test:

View file

@ -6,9 +6,9 @@
require File.expand_path('../boot', __FILE__) require File.expand_path('../boot', __FILE__)
require "action_controller/railtie" require 'action_controller/railtie'
require "action_mailer/railtie" require 'action_mailer/railtie'
require "active_resource/railtie" require 'active_resource/railtie'
# If you have a Gemfile, require the gems listed there, including any gems # If you have a Gemfile, require the gems listed there, including any gems
# you've limited to :test, :development, or :production. # you've limited to :test, :development, or :production.
Bundler.require(:default, Rails.env) if defined?(Bundler) Bundler.require(:default, Rails.env) if defined?(Bundler)

View file

@ -39,8 +39,6 @@ backers.each{ |backer|
# Start Nginx # Start Nginx
after "deploy:cold" do after "deploy:cold" do
run("nginx stop")
run("killall nginx")
#run("nginx") #run("nginx")
end end
@ -58,6 +56,11 @@ namespace :deploy do
task :start do task :start do
start_mongo start_mongo
start_thin start_thin
start_websocket
end
task :start_websocket do
run("cd #{current_path} && bundle exec ruby ./script/websocket_server.rb > /dev/null&")
end end
task :start_mongo do task :start_mongo do

View file

@ -7,6 +7,7 @@
# Load the rails application # Load the rails application
require File.expand_path('../application', __FILE__) require File.expand_path('../application', __FILE__)
Haml::Template.options[:format] = :html5 Haml::Template.options[:format] = :html5
Haml::Template.options[:escape_html] = true
# Initialize the rails application # Initialize the rails application
Diaspora::Application.initialize! Diaspora::Application.initialize!

View file

@ -21,8 +21,19 @@ Diaspora::Application.configure do
config.action_controller.perform_caching = false config.action_controller.perform_caching = false
# Don't care if the mailer can't send # Don't care if the mailer can't send
config.action_mailer.raise_delivery_errors = false config.action_mailer.raise_delivery_errors = true
config.active_support.deprecation = :log config.active_support.deprecation = :log
config.middleware.use MongoMapper::ClearDevMemory config.middleware.use MongoMapper::ClearDevMemory
#config.threadsafe! #config.threadsafe!
config.action_mailer.delivery_method = :smtp
config.action_mailer.default_url_options = {:host => 'localhost:3000'}
config.action_mailer.smtp_settings = {
:address => 'smtp.gmail.com',
:port => 587,
:domain => 'mail.joindiaspora.com',
:authentication => 'plain',
:user_name => 'diaspora-pivots@joindiaspora.com',
:password => "xy289|]G+R*-kA",
:enable_starttls_auto => true
}
end end

View file

@ -15,12 +15,12 @@ Diaspora::Application.configure do
config.action_controller.perform_caching = true config.action_controller.perform_caching = true
# Specifies the header that your server uses for sending files # Specifies the header that your server uses for sending files
config.action_dispatch.x_sendfile_header = "X-Sendfile" #config.action_dispatch.x_sendfile_header = "X-Sendfile"
config.active_support.deprecation = :notify config.active_support.deprecation = :notify
# For nginx: # For nginx:
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'
# If you have no front-end server that supports something like X-Sendfile, # If you have no front-end server that supports something like X-Sendfile,
# just comment this out and Rails will serve the files # just comment this out and Rails will serve the files
@ -36,7 +36,7 @@ Diaspora::Application.configure do
# Disable Rails's static asset server # Disable Rails's static asset server
# In production, Apache or nginx will already do this # In production, Apache or nginx will already do this
config.serve_static_assets = true #config.serve_static_assets = true
# Enable serving of images, stylesheets, and javascripts from an asset server # Enable serving of images, stylesheets, and javascripts from an asset server
# config.action_controller.asset_host = "http://assets.example.com" # config.action_controller.asset_host = "http://assets.example.com"
@ -44,12 +44,20 @@ Diaspora::Application.configure do
# Disable delivery errors, bad email addresses will be ignored # Disable delivery errors, bad email addresses will be ignored
# config.action_mailer.raise_delivery_errors = false # config.action_mailer.raise_delivery_errors = false
# Enable threaded mode
# config.threadsafe!
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation can not be found) # the I18n.default_locale when a translation can not be found)
config.i18n.fallbacks = true config.i18n.fallbacks = true
config.threadsafe! config.threadsafe!
config.action_mailer.delivery_method = :smtp
config.action_mailer.default_url_options = {:host => 'pivots.joindiaspora.com'}
config.action_mailer.smtp_settings = {
:address => 'smtp.gmail.com',
:port => 587,
:domain => 'mail.joindiaspora.com',
:authentication => 'plain',
:user_name => 'diaspora-pivots@joindiaspora.com',
:password => "xy289|]G+R*-kA",
:enable_starttls_auto => true
}
end end

View file

@ -0,0 +1,6 @@
# Copyright (c) 2010, Diaspora Inc. This file is
# licensed under the Affero General Public License version 3. See
# the COPYRIGHT file.
GIT_INFO = `git show`

View file

@ -0,0 +1,8 @@
# Copyright (c) 2010, Diaspora Inc. This file is
# licensed under the Affero General Public License version 3. See
# the COPYRIGHT file.
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
I18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
I18n.default_locale = :en

View file

@ -1,26 +0,0 @@
# Copyright (c) 2010, Diaspora Inc. This file is
# licensed under the Affero General Public License version 3. See
# the COPYRIGHT file.
require 'em-websocket'
require 'eventmachine'
require "lib/diaspora/websocket"
EM.next_tick {
Diaspora::WebSocket.initialize_channels
EventMachine::WebSocket.start(
:host => "0.0.0.0",
:port => APP_CONFIG[:socket_port],
:debug =>APP_CONFIG[:socket_debug]) do |ws|
ws.onopen {
sid = Diaspora::WebSocket.subscribe(ws.request['Path'].gsub('/',''), ws)
ws.onmessage { |msg| SocketsController.new.incoming(msg) }
ws.onclose { Diaspora::WebSocket.unsubscribe(ws.request['Path'].gsub('/',''), sid) }
}
end
}

View file

@ -0,0 +1,42 @@
es:
errors:
messages:
not_found: 'no encontrado'
already_confirmed: 'ya ha sido confirmada'
not_locked: 'no está bloqueada'
devise:
failure:
unauthenticated: 'Necesitas acceder a tu cuenta o registrarte antes de continuar.'
unconfirmed: 'Necesitas confirmar tu cuenta antes de continuar.'
locked: 'Tu cuenta esta bloqueada.'
invalid: 'Contraseña o Email incorrecto.'
invalid_token: 'Token de autenticación incorrecto.'
timeout: 'Tu sesión ha expirado, por favor accede de nuevo para continuar.'
inactive: 'Tu cuenta no ha sido activada.'
sessions:
signed_in: 'Has ingresado correctamente.'
signed_out: 'Has salido correctamente.'
passwords:
send_instructions: 'Recibirás un email con instrucciones para cambiar tu contraseña en poco minutos.'
updated: 'Tu contraseña ha sido modificada. Ya has accedido a tu cuenta.'
confirmations:
send_instructions: 'Recibirás un email con instrucciones para confirmar tu cuenta en poco minutos.'
confirmed: 'Tu cuenta ha sido confirmada. Ya has accedido a tu cuenta.'
registrations:
signed_up: 'Te has registrado correctamente. Si está disponible, te habremos enviado un email de confirmación.'
updated: 'Has actualizado tu cuenta correctamente.'
destroyed: '!Adiós! Tu cuenta ha sido cancelada. Esperamos verte pronto.'
unlocks:
send_instructions: 'Recibirás un email con instrucciones para desbloquear tu cuenta en pocos minutos.'
unlocked: 'Tu cuenta ha sido desbloqueada. Ya has accedido a tu cuenta.'
oauth_callbacks:
success: 'Has sido autorizado satisfactoriamente de la cuenta %{kind}.'
failure: 'No has sido autorizado en la cuenta %{kind} porque "%{reason}".'
mailer:
confirmation_instructions:
subject: 'Instrucciones de confirmación'
reset_password_instructions:
subject: 'Instrucciones para cambiar tu contraseña'
unlock_instructions:
subject: 'Instrucciones para desbloquear tu cuenta'

View file

@ -0,0 +1,41 @@
# Copyright (c) 2010, Diaspora Inc. This file is
# licensed under the Affero General Public License version 3. See
# the COPYRIGHT file.
en:
errors:
messages:
not_found: "nerasta"
already_confirmed: "jau patvirtinta"
not_locked: "nebuvo užrakinta"
devise:
failure:
unauthenticated: 'Norint tęsti, reikia prisijungti arba susikurti paskyrą.'
unconfirmed: 'Norint prisijungti, reikia patvirtinti savo paskyrą.'
locked: 'Jūsų paskyra yra užrakinta.'
invalid: 'Neteisingas el. pašto adresas arba slaptažodis.'
invalid_token: 'Neteisingas prisijungimo raktas.'
timeout: 'Sesija baigėsi. Norint tęsti, reikia prisijungti iš naujo.'
inactive: 'Paskyra dar neaktyvuota.'
sessions:
signed_in: 'Sėkmingai prisijungta.'
signed_out: 'Sėkmingai atsijungta.'
passwords:
send_instructions: 'Netrukus gausite el. laišką su nurodymais slaptažodžiui atstatyti.'
updated: 'Slaptažodis pakeistas sėkmingai. Jūs esate prisijungęs.'
confirmations:
send_instructions: 'Netrukus gausite el. laišką su nurodymais paskyros patvirtinimui.'
confirmed: 'Paskyra patvirtinta. Prisijungėte.'
registrations:
signed_up: 'Prisijungta sėkmingai. Jei nustatyta, patvirtinimas išsiųstas į jūsų el. paštą.'
updated: 'Paskyra atnaujinta sėkmingai.'
destroyed: 'Paskyra sėkmingai atšaukta. Iki pasimatymo!'
unlocks:
send_instructions: 'Netrukus gausite el. laišką su nurodymais paskyros atrakinimui.'
unlocked: 'Paskyra atrakinta. Prisijungėte.'
mailer:
confirmation_instructions: 'Nurodymai patvirtinimui'
reset_password_instructions: 'Nurodymai slaptažodžio atstatymui'
unlock_instructions: 'Nurodymai paskyros atrakinimui'

10
config/locales/lt.yml Normal file
View file

@ -0,0 +1,10 @@
# Copyright (c) 2010, Diaspora Inc. This file is
# licensed under the Affero General Public License version 3. See
# the COPYRIGHT file.
# Sample localization file for English. Add more files in this directory for other locales.
# See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
en:
hello: "Sveikas pasauli"

View file

@ -6,7 +6,7 @@
Diaspora::Application.routes.draw do Diaspora::Application.routes.draw do
resources :people, :only => [:index, :show, :destroy] resources :people, :only => [:index, :show, :destroy]
resources :users, :except => [:create, :new] resources :users, :except => [:create, :new, :show]
resources :status_messages, :only => [:create, :destroy, :show] resources :status_messages, :only => [:create, :destroy, :show]
resources :comments, :except => [:index] resources :comments, :except => [:index]
resources :requests, :except => [:edit, :update] resources :requests, :except => [:edit, :update]

View file

@ -33,12 +33,14 @@ http {
# gzip_disable "MSIE [1-6]\.(?!.*SV1)"; # gzip_disable "MSIE [1-6]\.(?!.*SV1)";
upstream thin_cluster { upstream thin_cluster {
server unix:/tmp/thin.0.sock; server unix:/tmp/thin.0.sock;
server unix:/tmp/thin.1.sock;
server unix:/tmp/thin.2.sock;
} }
server { server {
listen 80; listen 80;
server_name babycakes.sofaer.net www.babycakes.sofaer.net; server_name pivots.joindiaspora.com www.pivots.joindiaspora.com;
root /usr/local/app/diaspora/current; root /usr/local/app/diaspora/current;
location / { location / {

View file

@ -7,13 +7,13 @@
require "#{File.dirname(__FILE__)}/packages/essential" require '#{File.dirname(__FILE__)}/packages/essential'
require "#{File.dirname(__FILE__)}/packages/database" require '#{File.dirname(__FILE__)}/packages/database'
require "#{File.dirname(__FILE__)}/packages/server" require '#{File.dirname(__FILE__)}/packages/server'
require "#{File.dirname(__FILE__)}/packages/scm" require '#{File.dirname(__FILE__)}/packages/scm'
require "#{File.dirname(__FILE__)}/packages/ruby" require '#{File.dirname(__FILE__)}/packages/ruby'
policy :diaspora, :roles => [:tom,:backer] do policy :diaspora, :roles => [:pivots] do
# requires :clean_dreamhost # requires :clean_dreamhost
requires :tools requires :tools
requires :rubygems requires :rubygems

View file

@ -13,7 +13,7 @@ max_conns: 1024
require: [] require: []
max_persistent_conns: 512 max_persistent_conns: 512
environment: development environment: production
servers: 1 servers: 1
daemonize: true daemonize: true
#chdir: /usr/applications/localhash/current #chdir: /usr/applications/localhash/current

View file

@ -7,6 +7,7 @@
require 'config/environment' require 'config/environment'
remote_url = "http://tom.joindiaspora.com/" remote_url = "http://tom.joindiaspora.com/"
remote_url = "http://localhost:3000/"
# Create seed user # Create seed user
user = User.instantiate!( :email => "tom@tom.joindiaspora.com", user = User.instantiate!( :email => "tom@tom.joindiaspora.com",
:username => "tom", :username => "tom",

View file

@ -62,7 +62,7 @@ module Diaspora
def receive_friend_request(friend_request) def receive_friend_request(friend_request)
Rails.logger.info("receiving friend request #{friend_request.to_json}") Rails.logger.info("receiving friend request #{friend_request.to_json}")
if request_from_me?(friend_request) if request_from_me?(friend_request) && self.aspect_by_id(friend_request.aspect_id)
aspect = self.aspect_by_id(friend_request.aspect_id) aspect = self.aspect_by_id(friend_request.aspect_id)
activate_friend(friend_request.person, aspect) activate_friend(friend_request.person, aspect)

View file

@ -6,6 +6,11 @@
module Diaspora module Diaspora
module WebSocket module WebSocket
def self.queue_to_user(uid, data)
channel = Magent::GenericChannel.new('websocket')
channel.enqueue({:uid => uid, :data => data})
end
def self.initialize_channels def self.initialize_channels
@channels = {} @channels = {}
end end
@ -44,6 +49,5 @@ module Diaspora
def unsocket_from_uid(id, opts={}) def unsocket_from_uid(id, opts={})
SocketsController.new.outgoing(id, Retraction.for(self), opts) SocketsController.new.outgoing(id, Retraction.for(self), opts)
end end
end end
end end

View file

@ -22,6 +22,7 @@ namespace :db do
require 'db/seeds/backer' require 'db/seeds/backer'
create create
end end
end end
desc 'Delete the collections in the current RAILS_ENV database' desc 'Delete the collections in the current RAILS_ENV database'
@ -53,4 +54,23 @@ namespace :db do
Rake::Task['db:seed:dev'].invoke Rake::Task['db:seed:dev'].invoke
puts "you did it!" puts "you did it!"
end end
task :fix_diaspora_handle do
puts "fixing the people in this seed"
require 'config/environment'
people = Person.all( '$where' => "function(){
return this.diaspora_handle.charAt(this.diaspora_handle.length-1) == '@'
}")
puts "Found #{people.count} people with broken diaspora_handle fields"
people.each do |person|
if person.owner
puts "Resetting diaspora handle for #{person.owner.username}"
person.diaspora_handle = person.owner.diaspora_handle
person.save
end
end
puts "everything should be peachy"
end
end end

View file

@ -3,42 +3,56 @@
* the COPYRIGHT file. * the COPYRIGHT file.
*/ */
function decrementRequestsCounter() {
$('#move_friends_link').live( 'click', function(){ var $new_requests = $(".new_requests"),
$.post('/aspects/move_friends', request_html = $new_requests.html(),
{ 'moves' : $('#aspect_list').data() }, old_request_count = request_html.match(/\d+/);
function(){ $('#aspect_title').html("Groups edited successfully!");});
$(".person").css('background-color','none');
$('#aspect_list').removeData();
$(".person").attr('from_aspect_id', function(){return $(this).parent().attr('id')})
});
function decrementRequestsCounter(){
var old_request_count = $(".new_requests").html().match(/\d+/);
if( old_request_count == 1 ) { if( old_request_count == 1 ) {
$(".new_requests").html( $new_requests.html(
$(".new_requests").html().replace(/ \(\d+\)/,'')); request_html.replace(/ \(\d+\)/,'')
);
} else { } else {
$(".new_requests").html( $new_requests.html(
$(".new_requests").html().replace(/\d+/,old_request_count-1)); request_html.replace(/\d+/,old_request_count-1)
);
} }
} }
$(function() { $(function() {
$("ul .person").draggable({
$('#move_friends_link').live( 'click', function(){
$.post(
'/aspects/move_friends',
{ 'moves' : $('#aspect_list').data() },
function() {
$('#aspect_title').html("Groups edited successfully!");
}
);
// should the following logic be moved into the $.post() callback?
$("#aspect_list").removeData();
$(".person")
.css('background-color','none')
.attr('from_aspect_id', function() {
return $(this).parent().attr('id')
});
});
$("ul .person .requested_person").draggable({
revert: true revert: true
}); });
$("ul .requested_person").draggable({ // Moved class to logic above - unnec duplicate logic
revert: true //$("ul .requested_person").draggable({
}); // revert: true
//});
$(".aspect ul").droppable({ $(".aspect ul").droppable({
hoverClass: 'active',
drop: function(event, ui) { drop: function(event, ui) {
if ($(ui.draggable[0]).hasClass('requested_person')){ if ($(ui.draggable[0]).hasClass('requested_person')){
@ -51,16 +65,23 @@ $(function() {
} }
}); });
}else { } else {
var move = {}; var $aspect_list = $('#aspect_list'),
move[ 'friend_id' ] = ui.draggable[0].id move = {};
move[ 'to' ] = $(this)[0].id;
move[ 'from' ] = ui.draggable[0].getAttribute('from_aspect_id'); // This is poor implementation
move[ 'friend_id' ] = ui.draggable[0].id; // ui.draggable.attr('id')
move[ 'to' ] = $(this)[0].id;// $(this).attr('id');
move[ 'from' ] = ui.draggable[0].getAttribute('from_aspect_id'); // ui.draggable.attr('from_aspect_id')
// if created custom attr's - should be using `data-foo`
if (move['to'] == move['from']){ if (move['to'] == move['from']){
$('#aspect_list').data( ui.draggable[0].id, []); $aspect_list.data( ui.draggable[0].id, []);
ui.draggable.css('background-color','#eee'); ui.draggable.css('background-color','#eee');
} else { } else {
$('#aspect_list').data( ui.draggable[0].id, move); $aspect_list.data( ui.draggable[0].id, move);
ui.draggable.css('background-color','orange'); ui.draggable.css('background-color','orange');
} }
} }
@ -69,33 +90,39 @@ $(function() {
}); });
$(".remove ul").droppable({ $(".remove ul").droppable({
hoverClass: 'active',
drop: function(event, ui) { drop: function(event, ui) {
if ($(ui.draggable[0]).hasClass('requested_person')){ if ($(ui.draggable[0]).hasClass('requested_person')){
$.ajax({ $.ajax({
type: "DELETE", type: "DELETE",
url: "/requests/" + ui.draggable[0].getAttribute('request_id') url: "/requests/" + ui.draggable.attr('request_id'),
}); success: function () {
decrementRequestsCounter(); decrementRequestsCounter();
$(ui.draggable[0]).fadeOut('slow') }
}else{ });
} else {
$.ajax({ $.ajax({
type: "DELETE", type: "DELETE",
url: "/people/" + ui.draggable[0].id url: "/people/" + ui.draggable.attr('id'),
}); success: function () {
alert("Removed Friend, proably want an undo countdown.") alert("Removed Friend, proably want an undo countdown.")
$(ui.draggable[0]).fadeOut('slow')
}
} }
}); });
});
$(".aspect h1").live( 'click', function() { }
var $this = $(this); $(ui.draggable[0]).fadeOut('slow'); // ui.draggable.fadeOut('slow')
var id = $this.closest("li").children("ul").attr("id"); }
var link = "/aspects/"+ id; });
$(".aspect h1").live( 'focus', function() {
var $this = $(this),
id = $this.closest("li").children("ul").attr("id"),
link = "/aspects/"+ id;
$this.keypress(function(e) { $this.keypress(function(e) {
if (e.which == 13) { if (e.which == 13) {
@ -114,4 +141,6 @@ $(".aspect h1").live( 'click', function() {
$("#aspect_nav a[href='"+link+"']").text($this.text()); $("#aspect_nav a[href='"+link+"']").text($this.text());
}); });
}); });
});
}); });

View file

@ -262,6 +262,11 @@
close.show(); close.show();
} }
$("#fancybox-inner input[type='text'], #fancybox-inner textarea").focus(function() {
$(document).unbind('keydown.fb');
});
fancybox_set_navigation(); fancybox_set_navigation();
$(window).bind("resize.fb", $.fancybox.center); $(window).bind("resize.fb", $.fancybox.center);

File diff suppressed because one or more lines are too long

View file

@ -519,20 +519,33 @@ h1.big_text {
.requests .aspect_name, .requests .aspect_name,
.remove .aspect_name { .remove .aspect_name {
position: relative; } position: relative; }
.aspect .aspect_name .tools, .aspect .aspect_name ul.tools,
.requests .aspect_name .tools, .requests .aspect_name ul.tools,
.remove .aspect_name .tools { .remove .aspect_name ul.tools {
position: absolute; position: absolute;
top: 10px; top: 10px;
right: 0; right: 0;
display: inline; } display: inline;
.aspect .aspect_name:hover .tools, padding: 0;
.requests .aspect_name:hover .tools, margin: 0;
.remove .aspect_name:hover .tools { list-style: none; }
display: inline; } .aspect .aspect_name ul.tools li,
.aspect ul, .requests .aspect_name ul.tools li,
.requests ul, .remove .aspect_name ul.tools li {
.remove ul { display: inline;
margin-right: 1em; }
.aspect .aspect_name ul.tools li:last-child,
.requests .aspect_name ul.tools li:last-child,
.remove .aspect_name ul.tools li:last-child {
margin-right: 0; }
.aspect .grey,
.requests .grey,
.remove .grey {
color: #999999;
cursor: default; }
.aspect ul.dropzone,
.requests ul.dropzone,
.remove ul.dropzone {
min-height: 20px; min-height: 20px;
margin: 0; margin: 0;
margin-bottom: 25px; margin-bottom: 25px;
@ -540,6 +553,10 @@ h1.big_text {
border: 1px solid #cccccc; border: 1px solid #cccccc;
list-style: none; list-style: none;
padding: 15px; } padding: 15px; }
.aspect ul.dropzone.active,
.requests ul.dropzone.active,
.remove ul.dropzone.active {
background-color: #fafafa; }
.aspect .person, .aspect .person,
.aspect .requested_person, .aspect .requested_person,
.requests .person, .requests .person,
@ -580,14 +597,6 @@ h1.big_text {
-webkit-box-shadow: 0 1px 3px #333333; -webkit-box-shadow: 0 1px 3px #333333;
-moz-box-shadow: 0 2px 4px #333333; -moz-box-shadow: 0 2px 4px #333333;
opacity: 0.9; } opacity: 0.9; }
.aspect .person .grey,
.aspect .requested_person .grey,
.requests .person .grey,
.requests .requested_person .grey,
.remove .person .grey,
.remove .requested_person .grey {
font-style: italic;
color: #666666; }
#notification_badge { #notification_badge {
position: fixed; position: fixed;
@ -598,3 +607,6 @@ h1.big_text {
border: 1px solid #cccccc; border: 1px solid #cccccc;
border-bottom: none; border-bottom: none;
padding: 3px 10px; } padding: 3px 10px; }
#fancybox-close:hover {
background-color: transparent; }

View file

@ -678,17 +678,29 @@ h1.big_text
.aspect_name .aspect_name
:position relative :position relative
.tools ul.tools
:position absolute :position absolute
:top 10px :top 10px
:right 0 :right 0
:display inline :display inline
:padding 0
&:hover :margin 0
.tools :list
:style none
li
:display inline :display inline
:margin
:right 1em
ul &:last-child
:margin
:right 0
.grey
:color #999
:cursor default
ul.dropzone
:min-height 20px :min-height 20px
:margin 0 :margin 0
:bottom 25px :bottom 25px
@ -699,6 +711,10 @@ h1.big_text
:style none :style none
:padding 15px :padding 15px
&.active
:background
:color #fafafa
.person, .person,
.requested_person .requested_person
:display inline-block :display inline-block
@ -726,12 +742,6 @@ h1.big_text
:-moz-box-shadow 0 2px 4px #333 :-moz-box-shadow 0 2px 4px #333
:opacity 0.9 :opacity 0.9
.grey
:font
:style italic
:color #666
#notification_badge #notification_badge
:position fixed :position fixed
:bottom 0 :bottom 0
@ -746,3 +756,7 @@ h1.big_text
:bottom none :bottom none
:padding 3px 10px :padding 3px 10px
#fancybox-close:hover
:background
:color transparent

13
script/server Executable file
View file

@ -0,0 +1,13 @@
#!/bin/bash
# Check if Mongo is running
if ! ps ax | grep -v grep | grep mongod >/dev/null
then
echo "Mongod not started"
else
mkdir -p -v log/thin/
bundle exec ruby ./script/websocket_server.rb&
bundle exec thin start $@
fi

View file

@ -0,0 +1,48 @@
# Copyright (c) 2010, Diaspora Inc. This file is
# licensed under the Affero General Public License version 3. See
# the COPYRIGHT file.
require File.dirname(__FILE__) + '/../config/environment'
require File.dirname(__FILE__) + '/../lib/diaspora/websocket'
CHANNEL = Magent::GenericChannel.new('websocket')
def process_message
if CHANNEL.queue_count > 0
message = CHANNEL.dequeue
if message
Diaspora::WebSocket.push_to_user(message['uid'], message['data'])
end
EM.next_tick{ process_message}
else
EM::Timer.new(1){process_message}
end
end
begin
EM.run {
Diaspora::WebSocket.initialize_channels
EventMachine::WebSocket.start(
:host => "0.0.0.0",
:port => APP_CONFIG[:socket_port],
:debug =>APP_CONFIG[:socket_debug]) do |ws|
ws.onopen {
sid = Diaspora::WebSocket.subscribe(ws.request['Path'].gsub('/',''), ws)
ws.onmessage { |msg| SocketsController.new.incoming(msg) }
ws.onclose { Diaspora::WebSocket.unsubscribe(ws.request['Path'].gsub('/',''), sid) }
}
end
puts "Websocket server started."
process_message
}
rescue RuntimeError => e
raise e unless e.message.include?("no acceptor")
puts "Are you sure the websocket server isn't already running?"
puts "Just start thin with bundle exec thin start."
Process.exit
end

View file

@ -36,7 +36,7 @@ end
Factory.define :user do |u| Factory.define :user do |u|
u.sequence(:username) {|n| "bob#{n}"} u.sequence(:username) {|n| "bob#{n}"}
u.sequence(:email) {|n| "bob#{n}@aol.com"} u.sequence(:email) {|n| "bob#{n}@pivotallabs.com"}
u.password "bluepin7" u.password "bluepin7"
u.password_confirmation "bluepin7" u.password_confirmation "bluepin7"
u.person { |a| Factory.create(:person_with_user, :owner_id => a._id)} u.person { |a| Factory.create(:person_with_user, :owner_id => a._id)}

View file

@ -0,0 +1,37 @@
# Copyright (c) 2010, Diaspora Inc. This file is
# licensed under the Affero General Public License version 3. See
# the COPYRIGHT file.
require File.dirname(__FILE__) + '/../spec_helper'
describe Diaspora::WebSocket do
before do
@user = Factory.create(:user)
@aspect = @user.aspect(:name => "losers")
@post = @user.build_post(:status_message, :message => "hey", :to => @aspect.id)
unstub_sockets
end
it 'should queue a job' do
Diaspora::WebSocket.should_receive(:queue_to_user)
@post.socket_to_uid(@user.id, :aspect_ids => @aspect.id)
end
describe 'queuing and dequeuing ' do
before do
@post.socket_to_uid(@user.id, :aspect_ids => @aspect.id)
@channel = Magent::GenericChannel.new('websocket')
end
it 'should send the queued job to Magent' do
@channel.message_count.should == 1
end
it 'should dequeue the job successfully' do
messages = @channel.message_count
@channel.dequeue
@channel.message_count.should == messages -1
end
end
end

View file

@ -2,87 +2,81 @@
# licensed under the Affero General Public License version 3. See # licensed under the Affero General Public License version 3. See
# the COPYRIGHT file. # the COPYRIGHT file.
require 'spec_helper'
require File.dirname(__FILE__) + '/../spec_helper'
describe Album do describe Album do
let(:user) { Factory.create(:user) }
let(:person) { user.person }
let(:aspect) { user.aspect(:name => "Foo") }
let(:album) { user.post(:album, :name => "test collection", :to => aspect.id) }
it 'is valid' do
album.should be_valid
end
it 'validates presence of a name' do
album.name = nil
album.should_not be_valid
end
it 'has many photos' do
album.associations[:photos].type == :many
end
context 'when an album has two attached images' do
before do before do
@fixture_name = File.dirname(__FILE__) + '/../fixtures/button.png' 2.times do
@user = Factory.create(:user) photo = Factory.build(:photo, :person => person, :album => album)
@user.person.save album.photos << photo
@aspect = @user.aspect(:name => "Foo")
@album = @user.post(:album, :name => "test collection", :to => @aspect.id)
end
it 'should require a name' do
@album.name = "test collection"
@album.valid?.should be true
@album.name = nil
@album.valid?.should be false
end
it 'should contain photos' do
photo = Factory.build(:photo, :person => @user.person)
@album.photos << photo
@album.photos.count.should == 1
end
it 'should remove all photos on album delete' do
photos = []
1.upto 3 do
photo = Photo.new(:person => @user.person, :album => @album, :created_at => Time.now)
photo.image.store! File.open @fixture_name
photos << photo
end
@album.photos += photos
Photo.all.count.should == 3
@album.destroy
Photo.all.count.should == 0
end
describe 'traversing' do
before do
@photos = []
1.upto 3 do |n|
photo = Photo.new(:person => @user.person, :album => @album, :created_at => Time.now + n)
photo.image.store! File.open @fixture_name
@photos << photo
end
@album.photos += @photos
end
it 'should traverse the album correctly' do
#should retrieve the next photo relative to a given photo
@album.next_photo(@photos[1]).id.should == @photos[2].id
#should retrieve the previous photo relative to a given photo
@album.prev_photo(@photos[1]).id.should == @photos[0].id
#wrapping
#does next photo of last to first
@album.next_photo(@photos[2]).id.should == @photos[0].id
#does previous photo of first to last
@album.prev_photo(@photos[0]).id.should == @photos[2].id
end end
end end
describe 'serialization' do context 'when the album is deleted' do
before do it 'removes all child photos' do
@xml = @album.to_xml.to_s expect{ album.destroy }.to change(Photo, :count).from(2).to(0)
end end
it 'should have a person' do
@xml.include?(@album.person.id.to_s).should be true
end end
it 'should have a name' do
@xml.include?(@album.name).should be true
end end
it 'should have an id' do
@xml.include?(@album.id.to_s).should be true context 'traversing photos' do
let(:attrs) { {:person => person, :album => album} }
let!(:photo_1) { Factory(:photo, attrs.merge(:created_at => 2.days.ago)) }
let!(:photo_2) { Factory(:photo, attrs.merge(:created_at => 1.day.ago)) }
let!(:photo_3) { Factory(:photo, attrs.merge(:created_at => Time.now)) }
describe '#next_photo' do
it 'returns the next photo' do
album.next_photo(photo_1).id.should == photo_2.id
end
it 'returns the first photo when given the last photo in the album' do
album.next_photo(photo_3).id.should == photo_1.id
end
end
describe '#prev_photo' do
it 'returns the previous photo' do
album.prev_photo(photo_2).id.should == photo_1.id
end
it 'returns the last photo when given the first photo in the album' do
album.prev_photo(photo_1).id.should == photo_3.id
end
end
end
describe '#to_xml' do
let(:doc) { album.to_xml }
it 'has a name' do
doc.at_xpath('./name').text.should == album.name
end
it 'has an id' do
doc.at_xpath('./_id').text.should == album.id.to_s
end
it 'includes the person' do
doc.at_xpath('./person/_id').text.should == album.person.id.to_s
end end
end end
end end

View file

@ -20,7 +20,6 @@ describe Request do
end end
it 'should generate xml for the User as a Person' do it 'should generate xml for the User as a Person' do
request = @user.send_friend_request_to Factory.create(:person), @aspect request = @user.send_friend_request_to Factory.create(:person), @aspect
xml = request.to_xml.to_s xml = request.to_xml.to_s

View file

@ -12,6 +12,15 @@ describe User do
@aspect = @user.aspect(:name => 'heroes') @aspect = @user.aspect(:name => 'heroes')
end end
it 'should create with pivotal or allowed emails' do
user1 = Factory.create(:user, :email => "kimfuh@yahoo.com")
user2 = Factory.create(:user, :email => "awesome@sofaer.net")
user3 = Factory.create(:user, :email => "steveellis@pivotallabs.com")
user1.created_at.nil?.should be false
user2.created_at.nil?.should be false
user3.created_at.nil?.should be false
end
describe 'profiles' do describe 'profiles' do
it 'should be able to update their profile and send it to their friends' do it 'should be able to update their profile and send it to their friends' do
Factory.create(:person) Factory.create(:person)
@ -22,4 +31,31 @@ describe User do
@user.profile.image_url.should == "http://clown.com" @user.profile.image_url.should == "http://clown.com"
end end
end end
describe 'aspects' do
it 'should delete an empty aspect' do
@user.aspects.include?(@aspect).should == true
@user.drop_aspect(@aspect)
@user.reload
@user.aspects.include?(@aspect).should == false
end
it 'should not delete an aspect with friends' do
user2 = Factory.create(:user)
aspect2 = user2.aspect(:name => 'stuff')
user2.reload
aspect2.reload
friend_users(@user, Aspect.find_by_id(@aspect.id), user2, Aspect.find_by_id(aspect2.id))
@aspect.reload
@user.aspects.include?(@aspect).should == true
proc{@user.drop_aspect(@aspect)}.should raise_error /Aspect not empty/
@user.reload
@user.aspects.include?(@aspect).should == true
end
end
end end

View file

@ -38,6 +38,7 @@ RSpec.configure do |config|
config.before(:each) do config.before(:each) do
DatabaseCleaner.start DatabaseCleaner.start
stub_sockets stub_sockets
User.stub!(:allowed_email?).and_return(:true)
end end
config.after(:each) do config.after(:each) do
@ -45,11 +46,17 @@ RSpec.configure do |config|
end end
end end
def stub_sockets def stub_sockets
Diaspora::WebSocket.stub!(:push_to_user).and_return(true) Diaspora::WebSocket.stub!(:queue_to_user).and_return(true)
Diaspora::WebSocket.stub!(:subscribe).and_return(true) Diaspora::WebSocket.stub!(:subscribe).and_return(true)
Diaspora::WebSocket.stub!(:unsubscribe).and_return(true) Diaspora::WebSocket.stub!(:unsubscribe).and_return(true)
end end
def unstub_sockets
Diaspora::WebSocket.unstub!(:queue_to_user)
Diaspora::WebSocket.unstub!(:subscribe)
Diaspora::WebSocket.unstub!(:unsubscribe)
end
def stub_signature_verification def stub_signature_verification
(get_models.map{|model| model.camelize.constantize} - [User]).each do |model| (get_models.map{|model| model.camelize.constantize} - [User]).each do |model|
model.any_instance.stubs(:verify_signature).returns(true) model.any_instance.stubs(:verify_signature).returns(true)

96
ubuntu-setup.bash Normal file
View file

@ -0,0 +1,96 @@
#!/bin/bash
# Author : hemanth.hm@gmail.com
# Site : www.h3manth.com
# This script helps to setup diaspora.
#
# Set extented globbing
shopt -s extglob
# Check if the user has sudo privileges.
[[ $( id -u) ]] && echo "$(whoami) has no sudo permissions on this machine" && exit 1
# Install build tools
echo "Installing build tools.."
sudo apt-get -y --no-install-recommends install build-essential libxslt1.1 libxslt1-dev libxml2
echo "..Done installing build tools"
# Install Ruby 1.8.7
echo "Installing ruby-full Ruby 1.8.7.."
sudo apt-get -y --no-install-recommends install ruby-full
echo "..Done installing Ruby"
# Install Rake
echo "Installing rake.."
sudo apt-get -y --no-install-recommends install rake
echo "..Done installing rake"
# Get the current release and install mongodb
lsb=$(lsb_release -rs)
ver=${lsb//.+(0)/.}
repo="deb http://downloads.mongodb.org/distros/ubuntu ${ver} 10gen"
echo "Setting up MongoDB.."
echo "."
echo ${repo} | sudo tee -a /etc/apt/sources.list
echo "."
echo "Fetching keys.."
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv 7F0CEB10
echo "."
sudo apt-get update
echo "."
sudo apt-get -y --no-install-recommends install mongodb-stable
echo "Done installing monngodb-stable.."
# Install imagemagick
echo "Installing imagemagick.."
sudo apt-get -y --no-install-recommends install imagemagick libmagick9-dev
echo "Installed imagemagick.."
# Install git-core
echo "Installing git-core.."
sudo apt-get -y --no-install-recommends install git-core
echo "Installed git-core.."
# Setting up ruby gems
echo "Fetching and installing ruby gems.."
(
echo "."
cd /tmp
wget http://production.cf.rubygems.org/rubygems/rubygems-1.3.7.tgz
echo "."
tar -xf rubygems-1.3.7.tgz
echo "."
cd rubygems-1.3.7
echo "."
sudo ruby setup.rb
echo "."
sudo ln -s /usr/bin/gem1.8 /usr/bin/gem
echo "."
)
echo "Done installing the gems.."
# Install blunder
echo "Installing blunder.."
sudo gem install bundler
echo "Installed blunder.."
# Take a clone of Diaspora
(
echo "Clone diaspora source.."
git clone http://github.com/diaspora/diaspora.git
echo "Cloned the source.."
# Install extra gems
cd diaspora
echo "Installing more gems.."
sudo bundle install
echo "Installed."
# Install DB setup
echo "Seting up DB.."
rake db:seed:tom
echo "DB ready. Login -> tom and password -> evankorth. More details ./diaspora/db/seeds/tom.rb."
# Run appserver
echo "Starting server"
bundle exec thin start
)