diff --git a/Gemfile b/Gemfile
index 9f9498361..946870396 100644
--- a/Gemfile
+++ b/Gemfile
@@ -26,7 +26,7 @@ gem 'json'
#Standards
gem 'pubsubhubbub'
-gem 'redfinger'
+gem 'redfinger', :git => 'git://github.com/rsofaer/redfinger.git'
#EventMachine
gem 'em-http-request',:git => 'git://github.com/igrigorik/em-http-request.git', :require => 'em-http'
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index f173633c4..6e4a43e86 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -2,7 +2,8 @@ class ApplicationController < ActionController::Base
protect_from_forgery :except => :receive
- before_filter :set_friends_and_status, :count_requests
+ before_filter :set_friends_and_status
+ before_filter :count_requests
layout :layout_by_resource
@@ -17,8 +18,6 @@ class ApplicationController < ActionController::Base
def set_friends_and_status
if current_user
@groups = current_user.groups
- @friends = current_user.friends
- @group = params[:group] ? current_user.group_by_id(params[:group]) : current_user.groups.first
end
end
diff --git a/app/controllers/gridfs_controller.rb b/app/controllers/gridfs_controller.rb
deleted file mode 100644
index 538eb5b79..000000000
--- a/app/controllers/gridfs_controller.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-class GridfsController < ActionController::Metal
- def serve
- gridfs_path = env["PATH_INFO"].gsub("/images/", "")
- begin
- gridfs_file = Mongo::GridFileSystem.new(MongoMapper.database).open(gridfs_path, 'r')
- self.response_body = gridfs_file.read
- self.content_type = gridfs_file.content_type
- rescue
- self.status = :file_not_found
- self.content_type = 'text/plain'
- self.response_body = "File totally imaginary #{gridfs_path}"
- end
- end
-
-end
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index 88b8235f2..aa0e618ef 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -2,7 +2,9 @@ class GroupsController < ApplicationController
before_filter :authenticate_user!
def index
- @posts = current_user.raw_visible_posts.paginate :page => params[:page], :order => 'created_at DESC'
+ @posts = current_user.visible_posts(:by_members_of => :all).paginate :page => params[:page], :order => 'created_at DESC'
+ @group = :all
+ @friends = current_user.friends
end
def create
@@ -28,12 +30,9 @@ class GroupsController < ApplicationController
end
def show
- @people_ids = @group.person_ids
-
@group = Group.first(:id => params[:id])
-
+ @friends = @group.people
@posts = current_user.visible_posts( :by_members_of => @group ).paginate :order => 'created_at DESC'
- #@posts = Post.paginate :person_id => @people_ids, :order => 'created_at DESC'
end
def edit
diff --git a/app/controllers/photos_controller.rb b/app/controllers/photos_controller.rb
index 2996a23ec..46332992d 100644
--- a/app/controllers/photos_controller.rb
+++ b/app/controllers/photos_controller.rb
@@ -2,6 +2,7 @@ class PhotosController < ApplicationController
before_filter :authenticate_user!
def create
+ render :nothing => true
begin
@photo = current_user.post(:photo, params)
@@ -21,6 +22,8 @@ class PhotosController < ApplicationController
def new
@photo = Photo.new
+ @album = current_user.album_by_id(params[:album_id])
+ render :partial => "new_photo"
end
def destroy
diff --git a/app/controllers/requests_controller.rb b/app/controllers/requests_controller.rb
index 24c4634b8..c639de66c 100644
--- a/app/controllers/requests_controller.rb
+++ b/app/controllers/requests_controller.rb
@@ -31,22 +31,31 @@ class RequestsController < ApplicationController
end
def create
- puts params.inspect
- rel_hash = relationship_flow(params[:request][:destination_url])
+ begin
+ rel_hash = relationship_flow(params[:request][:destination_url])
+ rescue Exception => e
+ flash[:error] = "no diaspora seed found with this email!"
+ redirect_to current_user.group_by_id(params[:request][:group_id])
+ return
+ end
+
Rails.logger.debug("Sending request: #{rel_hash}")
- @request = current_user.send_request(rel_hash, params[:request][:group_id])
+
+ begin
+ @request = current_user.send_request(rel_hash, params[:request][:group_id])
+ rescue Exception => e
+ raise e unless e.message.include? "already friends"
+ flash[:notice] = "You are already friends with #{params[:request][:destination_url]}!"
+ redirect_to current_user.group_by_id(params[:request][:group_id])
+ return
+ end
if @request
flash[:notice] = "a friend request was sent to #{@request.destination_url}"
- redirect_to requests_url
+ redirect_to current_user.group_by_id(params[:request][:group_id])
else
- if url.include? '@'
- flash[:error] = "no diaspora seed found with this email!"
- else
- flash[:error] = "you have already friended this person"
- end
- @request = Request.new
- render :action => 'new'
+ flash[:error] = "Something went horribly wrong..."
+ redirect_to current_user.group_by_id(params[:request][:group_id])
end
end
diff --git a/app/controllers/status_messages_controller.rb b/app/controllers/status_messages_controller.rb
index 786b15007..3cacb1a55 100644
--- a/app/controllers/status_messages_controller.rb
+++ b/app/controllers/status_messages_controller.rb
@@ -1,15 +1,8 @@
class StatusMessagesController < ApplicationController
before_filter :authenticate_user!
- def index
- @status_messages = StatusMessage.paginate :page => params[:page], :order => 'created_at DESC'
- respond_to do |format|
- format.html
- end
- end
-
def create
- puts params.inspect
+ params[:status_message][:group_ids] = params[:group_ids]
@status_message = current_user.post(:status_message, params[:status_message])
if @status_message.created_at
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index c5ef2f0e8..22c9cbe00 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -1,7 +1,7 @@
module ApplicationHelper
def current_group?(group)
- @group.id == group.id
+ @group == :all || @group.id == group.id
end
def object_path(object)
diff --git a/app/helpers/photos_helper.rb b/app/helpers/photos_helper.rb
index c518ceec5..faf29ed63 100644
--- a/app/helpers/photos_helper.rb
+++ b/app/helpers/photos_helper.rb
@@ -4,11 +4,11 @@ module PhotosHelper
link_to (image_tag photo.url(:scaled_full)), photo_path(album.next_photo(photo)), :rel => "prefetch"
end
- def link_to_prev(photo, album)
- link_to "<< prev", photo_path(album.prev_photo(photo)), :rel => "prefetch"
+ def url_to_prev(photo, album)
+ photo_path(album.prev_photo(photo))
end
- def link_to_next(photo, album)
- link_to "next >>", photo_path(album.next_photo(photo)), :rel => "prefetch"
+ def url_to_next(photo, album)
+ photo_path(album.next_photo(photo))
end
end
diff --git a/app/helpers/requests_helper.rb b/app/helpers/requests_helper.rb
index c0320c0b8..37a5485c4 100644
--- a/app/helpers/requests_helper.rb
+++ b/app/helpers/requests_helper.rb
@@ -29,7 +29,6 @@ module RequestsHelper
action = :none
url = nil
local_person = Person.by_webfinger identifier
- puts local_person.inspect
if local_person
action = (local_person == current_user.person ? :none : :friend)
url = local_person.receive_url
diff --git a/app/models/person.rb b/app/models/person.rb
index 32d68cab8..84edbed3d 100644
--- a/app/models/person.rb
+++ b/app/models/person.rb
@@ -51,6 +51,10 @@ class Person
serialized_key = new_key.export
end
+ def public_key_hash
+ Base64.encode64 OpenSSL::Digest::SHA256.new(self.export_key).to_s
+ end
+
def export_key
encryption_key.public_key.export
end
diff --git a/app/models/post.rb b/app/models/post.rb
index 8f30586a0..0ab355968 100644
--- a/app/models/post.rb
+++ b/app/models/post.rb
@@ -29,11 +29,6 @@ class Post
self.create params
end
-#Querying
- def self.newest_for(person)
- self.where(:person_id => person.id, :order => '_id desc')
- end
-
#ENCRYPTION
xml_accessor :creator_signature
key :creator_signature, String
diff --git a/app/models/user.rb b/app/models/user.rb
index e3aa4425f..d9c890087 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -27,10 +27,7 @@ class User
def allowed_email?
- allowed_emails = ["@pivotallabs.com", "@joindiaspora.com", "@sofaer.net",
- "wchulley@gmail.com", "kimfuh@yahoo.com", "CJichi@yahoo.com",
- "madkisso@mit.edu", "bribak@msn.com", "asykley@verizon.net",
- "paulhaeberli@gmail.com","bondovatic@gmail.com", "dixon1e@yahoo.com"]
+ allowed_emails = ["@pivotallabs.com", "@joindiaspora.com", "@sofaer.net"]
allowed_emails.each{|allowed|
if email.include?(allowed)
return true
@@ -59,23 +56,25 @@ class User
def post(class_name, options = {})
options[:person] = self.person
- group_id = options[:group_id]
- options.delete(:group_id)
+ group_ids = options[:group_ids]
+ options.delete(:group_ids)
model_class = class_name.to_s.camelize.constantize
+
post = model_class.instantiate(options)
post.creator_signature = post.sign_with_key(encryption_key)
post.save
- if group_id
- group = self.groups.find_by_id(group_id)
+ groups = self.groups.find_all_by_id(group_ids)
+ target_people = []
+
+ groups.each{ |group|
group.posts << post
group.save
- post.push_to( group.people.all )
- else
- post.push_to( self.friends.all )
- end
+ target_people = target_people | group.people
+ }
+ post.push_to( target_people )
post.socket_to_uid(id) if post.respond_to?(:socket_to_uid)
@@ -86,6 +85,7 @@ class User
def visible_posts( opts = {} )
if opts[:by_members_of]
+ return raw_visible_posts if opts[:by_members_of] == :all
group = self.groups.find_by_id( opts[:by_members_of].id )
group.posts
end
@@ -139,22 +139,22 @@ class User
######### Friend Requesting ###########
def send_friend_request_to(friend_url, group_id)
- unless self.friends.detect{ |x| x.receive_url == friend_url}
- request = Request.instantiate(:to => friend_url, :from => self.person, :into => group_id)
- if request.save
- self.pending_requests << request
- self.save
+ raise "You are already friends with that person!" if self.friends.detect{ |x| x.receive_url == friend_url}
+ request = Request.instantiate(:to => friend_url, :from => self.person, :into => group_id)
+ if request.save
+ self.pending_requests << request
+ self.save
- group = self.group_by_id(group_id)
+ group = self.group_by_id(group_id)
- group.requests << request
- group.save
-
- request.push_to_url friend_url
- end
- request
+ group.requests << request
+ group.save
+
+ request.push_to_url friend_url
end
- end
+ request
+ end
+
def accept_friend_request(friend_request_id, group_id)
request = Request.find_by_id(friend_request_id)
@@ -358,7 +358,12 @@ class User
group(:name => "Acquaintances")
group(:name => "Family")
group(:name => "Nemeses")
- group(:name => "Work")
+ group(:name => "Pivots")
+ end
+
+ def album_by_id( id )
+ id = ensure_bson id
+ albums.detect{|x| x.id == id }
end
def groups_with_person person
@@ -369,8 +374,8 @@ class User
protected
def setup_person
- self.person.serialized_key = generate_key.export
- self.person.email = email
+ self.person.serialized_key ||= generate_key.export
+ self.person.email ||= email
self.person.save!
end
diff --git a/app/uploaders/image_uploader.rb b/app/uploaders/image_uploader.rb
index 3fd36c6a6..732367ffa 100644
--- a/app/uploaders/image_uploader.rb
+++ b/app/uploaders/image_uploader.rb
@@ -11,9 +11,9 @@ class ImageUploader < CarrierWave::Uploader::Base
%w(jpg jpeg gif png)
end
-# def filename
-# model.id.to_s + File.extname(@filename)
-# end
+ def filename
+ model.id.to_s + File.extname(@filename) if @filename
+ end
version :thumb_small do
process :resize_to_fill => [30,30]
diff --git a/app/views/albums/show.html.haml b/app/views/albums/show.html.haml
index 04b117645..c0cf97427 100644
--- a/app/views/albums/show.html.haml
+++ b/app/views/albums/show.html.haml
@@ -1,3 +1,9 @@
+:javascript
+ $(document).ready(function(){
+ reset_photo_fancybox();
+ });
+
+.album_id{:id => @album.id, :style => "display:hidden;"}
.back= link_to '⇧ albums', albums_path
%h1.big_text
@@ -11,7 +17,6 @@
.yo{:style => "display:none;"}
#new_photo_pane
- = render "photos/new_photo", :photo => @photo, :album => @album
.sub_header
="updated #{how_long_ago(@album)}"
diff --git a/app/views/groups/index.html.haml b/app/views/groups/index.html.haml
index 89ef12f84..1f9764bbb 100644
--- a/app/views/groups/index.html.haml
+++ b/app/views/groups/index.html.haml
@@ -2,9 +2,7 @@
welcome,
= current_user.profile.first_name
-- @group.nil? ? group_id = nil : group_id = @group.id
-
-= render "shared/publisher", :group_id => group_id
+= render "shared/publisher", :group_ids => :all
%ul#stream
- for post in @posts
diff --git a/app/views/js/_websocket_js.haml b/app/views/js/_websocket_js.haml
index 443726e50..282a07624 100644
--- a/app/views/js/_websocket_js.haml
+++ b/app/views/js/_websocket_js.haml
@@ -1,103 +1,101 @@
-- if user_signed_in?
- = javascript_include_tag 'FABridge', 'swfobject', 'web_socket'
- :javascript
- WebSocket.__swfLocation = "/javascripts/WebSocketMain.swf";
- :javascript
- $(document).ready(function(){
- function debug(str){ $("#debug").append("
" + str); };
+= javascript_include_tag 'FABridge', 'swfobject', 'web_socket'
+:javascript
+ WebSocket.__swfLocation = "/javascripts/WebSocketMain.swf";
+ $(document).ready(function(){
+ function debug(str){ $("#debug").append("
" + str); };
- ws = new WebSocket("ws://#{request.host}:8080/#{CGI::escape(current_user.id.to_s)}");
+ ws = new WebSocket("ws://#{request.host}:8080/#{CGI::escape(current_user.id.to_s)}");
- //Attach onmessage to websocket
- ws.onmessage = function(evt) {
- var obj = jQuery.parseJSON(evt.data);
- debug("got a " + obj['class'] + " for group " + obj['group_id']);
+ //Attach onmessage to websocket
+ ws.onmessage = function(evt) {
+ var obj = jQuery.parseJSON(evt.data);
+ debug("got a " + obj['class'] + " for group " + obj['group_id']);
- if (obj['class']=="retractions"){
- processRetraction(obj['post_id']);
-
- }else if (obj['class']=="comments"){
- processComment(obj['post_id'], obj['html'])
-
- }else if (obj['class']=='photos' && onPageForClass('albums')){
- processPhotoInAlbum(obj['photo_hash'])
- }else if (obj['class']=='status_messages'){
- processStatusMessage(obj['class'], obj['html'], obj['status_message_hash'], obj['group_id'], obj['mine?'])
- }else{
- processPost(obj['class'], obj['html'], obj['group_id'], obj['mine?'])
- }
-
-
- };
- ws.onclose = function() { debug("socket closed"); };
- ws.onopen = function() {
- ws.send(location.pathname);
- debug("connected...");
- };
-
- function processRetraction(post_id){
- $('#' + post_id ).fadeOut(500, function(){
- $(this).remove;
- });
- }
-
- function processComment(post_id, html){
- post = $('#' + post_id)[0]
- $(' .comment_set li:last', post ).before(
- $(html).fadeIn("fast", function(){})
- );
- toggler = $('.show_post_comments', post)
- toggler.html(
- toggler.html().replace(/\d/,$('.comment_set', post)[0].childElementCount -1));
- }
-
- function processPost(className, html, groupId, mineBool){
- if(mineBool || onPageForClass(className) || onPageForGroup(groupId)){
- $("#stream").prepend(
- $(html).fadeIn("fast", function(){
- $("#stream label:first").inFieldLabels();
- })
- );
- }
- }
-
- function processStatusMessage(className, html, messageHash, groupId, mineBool){
- processPost(className, html, groupId, mineBool);
- console.log(messageHash)
- if(messageHash['mine?']){
- updateMyLatestStatus(messageHash);
- }
- }
+ if (obj['class']=="retractions"){
+ processRetraction(obj['post_id']);
- function updateMyLatestStatus(messageHash){
- $("#latest_message").text(messageHash['text']);
- $("#latest_message_time").text(' - just now');
+ }else if (obj['class']=="comments"){
+ processComment(obj['post_id'], obj['html'])
+
+ }else if (obj['class']=='photos' && onPageForClass('albums')){
+ processPhotoInAlbum(obj['photo_hash'])
+ }else if (obj['class']=='status_messages'){
+ processStatusMessage(obj['class'], obj['html'], obj['status_message_hash'], obj['group_id'], obj['mine?'])
+ }else{
+ processPost(obj['class'], obj['html'], obj['group_id'], obj['mine?'])
}
- function processPhotoInAlbum(photoHash){
- if (location.href.indexOf(photoHash['album_id']) == -1){
- return ;
- }
- html = "
"
- $("#thumbnails").append( $(html) )
- $("#"+ photoHash['id'] + " img").load( function() {
- $(this).fadeIn("slow");
- });
- }
- function onPageForClass(className){
- return ((location.href.indexOf(className) != -1 ) || (location.pathname == '/')) && onPageOne();
- }
+ };
+ ws.onclose = function() { debug("socket closed"); };
+ ws.onopen = function() {
+ ws.send(location.pathname);
+ debug("connected...");
+ };
- function onPageForGroup(groupId){
- return (location.href.indexOf(groupId) != -1 )
+ function processRetraction(post_id){
+ $('#' + post_id ).fadeOut(500, function(){
+ $(this).remove;
+ });
+ }
+
+ function processComment(post_id, html){
+ post = $('#' + post_id)[0]
+ $(' .comment_set li:last', post ).before(
+ $(html).fadeIn("fast", function(){})
+ );
+ toggler = $('.show_post_comments', post)
+ toggler.html(
+ toggler.html().replace(/\d/,$('.comment_set', post)[0].childElementCount -1));
+ }
+
+ function processPost(className, html, groupId, mineBool){
+ if(mineBool || onPageForClass(className) || onPageForGroup(groupId)){
+ $("#stream").prepend(
+ $(html).fadeIn("fast", function(){
+ $("#stream label:first").inFieldLabels();
+ })
+ );
}
-
- function onPageOne() {
- var c = document.location.search.charAt(document.location.search.length-1);
- return ((c =='') || (c== '1'));
+ }
+
+ function processStatusMessage(className, html, messageHash, groupId, mineBool){
+ processPost(className, html, groupId, mineBool);
+ console.log(messageHash)
+ if(messageHash['mine?']){
+ updateMyLatestStatus(messageHash);
}
- });
+ }
+
+ function updateMyLatestStatus(messageHash){
+ $("#latest_message").text(messageHash['text']);
+ $("#latest_message_time").text(' - just now');
+ }
+
+ function processPhotoInAlbum(photoHash){
+ if (location.href.indexOf(photoHash['album_id']) == -1){
+ return ;
+ }
+ html = ""
+ $("#thumbnails").append( $(html) )
+ $("#"+ photoHash['id'] + " img").load( function() {
+ $(this).fadeIn("slow");
+ });
+ }
+
+ function onPageForClass(className){
+ return ((location.href.indexOf(className) != -1 ) || (location.pathname == '/')) && onPageOne();
+ }
+
+ function onPageForGroup(groupId){
+ return (location.href.indexOf(groupId) != -1 )
+ }
+
+ function onPageOne() {
+ var c = document.location.search.charAt(document.location.search.length-1);
+ return ((c =='') || (c== '1'));
+ }
+ });
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index da2b73eb8..1061d9d13 100644
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -13,7 +13,6 @@
/= javascript_include_tag "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"
= javascript_include_tag 'jquery142', 'rails', 'google'
- = javascript_include_tag 'tiny_mce/tiny_mce'
= javascript_include_tag 'jquery.infieldlabel', 'jquery.cycle/jquery.cycle.min.js'
= javascript_include_tag 'fancybox/jquery.fancybox-1.3.1.pack'
@@ -33,26 +32,35 @@
%header
.container
#session_action
- - if user_signed_in?
- %ul#user_menu
- %li.name= link_to current_user.real_name, current_user.person
- %li= link_to "requests (#{@request_count})", requests_path, :class => new_request(@request_count)
- %li= link_to "settings", edit_user_path(current_user)
- %li= link_to "search", users_path
- %li= link_to "logout", destroy_user_session_path
- - else
- = link_to "login", new_user_session_path
+ %ul#user_menu
+ %li#global_search
+ = form_tag(users_path, :method => 'get') do
+ %label{:for => 'q'} Search
+ = text_field_tag 'q'
+
+ %li
+ %ul#other_user_menu
+ %li
+ = owner_image_tag
+ = link_to current_user.real_name, current_user.person
+ %li.requests= link_to "requests (#{@request_count})", requests_path, :class => new_request(@request_count)
+ %li.settings= link_to "settings", edit_user_path(current_user)
+ %li.logout= link_to "logout", destroy_user_session_path
+
#diaspora_text{:href => root_path}
= link_to "DIASPORA*", root_path
%span.sub_text
PREVIEW
- = render "shared/group_nav"
- = link_to "photos", albums_path
+ %span{:style => "padding-left:30px;"}
+ = link_to "photos", albums_path
.container
- .span-24.last
+ .span-4.append-1.last
+ = render "shared/group_nav"
+
+ .span-19.last
= yield
- .span-24.last
+
= render "posts/debug"
diff --git a/app/views/people/_sidebar.html.haml b/app/views/people/_sidebar.html.haml
deleted file mode 100644
index 79d2d0c41..000000000
--- a/app/views/people/_sidebar.html.haml
+++ /dev/null
@@ -1,11 +0,0 @@
-%ul#friend_stream.nav
- %h3 friends
- - for friend in @friends
- = person_image_link(friend)
-
- %li= link_to "view all", people_path
-
- %br
- %br
-
-= link_to "add a new person", requests_path
diff --git a/app/views/photos/_new_photo.haml b/app/views/photos/_new_photo.haml
index b57731596..5bc6d6882 100644
--- a/app/views/photos/_new_photo.haml
+++ b/app/views/photos/_new_photo.haml
@@ -2,7 +2,7 @@
$(function() {
$("#photo_image").html5_upload({
// WE INSERT ALBUM_ID PARAM HERE
- url: "/photos?album_id=#{album.id}",
+ url: "/photos?album_id=#{@album.id}",
sendBoundary: window.FormData || $.browser.mozilla,
setName: function(text) {
$("#progress_report_name").text(text);
@@ -12,8 +12,10 @@
$("#add_photo_loader").fadeOut(400);
$("#photo_title_status").text("Done!");
- $("#progress_report").html("Great job!");
- },
+ $("#progress_report").html("Good job me!");
+
+ $("#add_photo_button").addClass("uploading_complete");
+ },
onStart: function(event, total){
$("#add_photo_button").html( "Uploading Photos" );
$("#add_photo_loader").fadeIn(400);
@@ -29,10 +31,10 @@
%h1
%span{:id=>"photo_title_status"}
Add photos to
- %i= album.name
-= form_for photo, :html => {:multipart => true} do |f|
+ %i= @album.name
+= form_for @photo, :html => {:multipart => true} do |f|
= f.error_messages
- = f.hidden_field :album_id, :value => album.id
+ = f.hidden_field :album_id, :value => @album.id
= f.file_field :image, :multiple => 'multiple'
#progress_report{ :style => "display:none;text-align:center;" }
diff --git a/app/views/photos/show.html.haml b/app/views/photos/show.html.haml
index 8636998b3..27afac74c 100644
--- a/app/views/photos/show.html.haml
+++ b/app/views/photos/show.html.haml
@@ -1,3 +1,16 @@
+:javascript
+ $(document).keydown(function(e){
+ switch(e.keyCode) {
+ case 37:
+ window.location.replace( "#{url_to_prev(@photo,@album)}" );
+ break;
+ case 39:
+ window.location.replace( "#{url_to_next(@photo,@album)}" );
+ break;
+ }
+ });
+
+
.back= link_to "⇧ #{@album.name}", album_path(@album)
%h1.big_text
= @photo.image
@@ -6,11 +19,11 @@
= link_to 'Edit Photo', edit_photo_path(@photo), :class => "button"
.sub_header
- = link_to_prev @photo, @album
+ = link_to "<< prev", url_to_prev(@photo, @album)
|
= link_to "full size", @photo.url
|
- = link_to_next @photo, @album
+ = link_to "next >>", url_to_next(@photo, @album)
%div{:id => @photo.id}
#show_photo
diff --git a/app/views/requests/_form.haml b/app/views/requests/_form.haml
deleted file mode 100644
index de088d363..000000000
--- a/app/views/requests/_form.haml
+++ /dev/null
@@ -1,6 +0,0 @@
-= form_for @request do |f|
- = f.error_messages
-
- .field_with_submit
- = f.text_field :destination_url
- = f.submit
diff --git a/app/views/requests/new.html.haml b/app/views/requests/new.html.haml
deleted file mode 100644
index 8a5276998..000000000
--- a/app/views/requests/new.html.haml
+++ /dev/null
@@ -1,5 +0,0 @@
-%h1 requests
-
-= render 'form'
-
-%p= link_to "Back to List", requests_path
diff --git a/app/views/shared/_group_nav.haml b/app/views/shared/_group_nav.haml
index 455d90bb4..d0c90b125 100644
--- a/app/views/shared/_group_nav.haml
+++ b/app/views/shared/_group_nav.haml
@@ -1,8 +1,16 @@
#group
%ul
+ - if @group == :all
+ = link_to "All Groups", root_url, :class => "selected"
+
+ - elsif @group
+ = link_to @group.name, @group, :class => "selected"
+ = link_to "edit", edit_group_path(@group)
+
- for group in @groups
- %li{:class => ("selected" if group.id.to_s == params[:id])}
- = link_to group.name, group
+ - unless (group.id.to_s == params[:id])
+ %li
+ = link_to group.name, group
%li.new_group= link_to("NEW GROUP", "#add_group_pane", :id => "add_group_button")
@@ -12,15 +20,11 @@
- if @group
#friend_pictures
- - for friend in @group.people
+ - for friend in @friends
= person_image_link(friend)
= link_to (image_tag 'add_friend_button.png'), "#add_request_pane", :id => 'add_request_button'
- - if @group.people.count == 0
- %span.add_new_description
- << click the plus to add friends to this group
-
-
- .yo{:style => 'display:none'}
- #add_request_pane
- = render "requests/new_request"
+ - unless @group == :all
+ .yo{:style => 'display:none'}
+ #add_request_pane
+ = render "requests/new_request"
diff --git a/app/views/shared/_publisher.haml b/app/views/shared/_publisher.haml
index 470cfbcfc..59fdbbfb7 100644
--- a/app/views/shared/_publisher.haml
+++ b/app/views/shared/_publisher.haml
@@ -1,18 +1,24 @@
#publisher
- #publisher_form
+ .span-19.last
= form_for StatusMessage.new, :remote => true do |f|
= f.error_messages
- -if group_id
- = f.hidden_field :group_id, :value => group_id
-
+ .span-15.last
+ .span-2.last
+ .user_image
+ = owner_image_tag
+ .span-13.last
+ %p
+ %label{:for => "status_message_message"} Message
+ = f.text_area :message, :rows => 2
+
+ .span-3.last
- %label{:for => "status_message_message"} Message
- = f.text_area :message, :rows => 2
- %ul
- - for group in current_user.groups
- %li
- = group.name
- = check_box_tag("groups_id[]", group.id, current_group?(group))
- .right
+ %ul.group_selector
+ going to...
+ - for group in current_user.groups
+ %li
+ = check_box_tag("group_ids[]", group.id, current_group?(group) )
+ = group.name
+ .span-1.last
= f.submit "Post"
diff --git a/config/app_config.yml b/config/app_config.yml
index 0c87b6b4c..1eee9376c 100644
--- a/config/app_config.yml
+++ b/config/app_config.yml
@@ -1,14 +1,17 @@
development:
debug: false
+ socket_debug : false
socket_port: 8080
pubsub_server: 'https://pubsubhubbub.appspot.com/'
test:
debug: false
+ socket_debug : false
socket_port: 8081
pubsub_server: 'https://pubsubhubbub.appspot.com/'
production:
debug: false
+ socket_debug : false
socket_port: 8080
pubsub_server: 'https://pubsubhubbub.appspot.com/'
diff --git a/config/environments/development.rb b/config/environments/development.rb
index 6314ef6c6..f9be7f0dd 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -1,3 +1,4 @@
+require 'lib/mongo_mapper/clear_dev_memory'
Diaspora::Application.configure do
# Settings specified here will take precedence over those in config/environment.rb
@@ -17,6 +18,7 @@ Diaspora::Application.configure do
# Don't care if the mailer can't send
config.action_mailer.raise_delivery_errors = true
config.active_support.deprecation = :log
+ config.middleware.use MongoMapper::ClearDevMemory
#config.threadsafe!
config.action_mailer.delivery_method = :smtp
config.action_mailer.default_url_options = {:host => 'localhost:3000'}
diff --git a/config/initializers/socket.rb b/config/initializers/socket.rb
index 381d1f6c2..03f9e24eb 100644
--- a/config/initializers/socket.rb
+++ b/config/initializers/socket.rb
@@ -7,7 +7,7 @@ require "lib/diaspora/websocket"
EventMachine::WebSocket.start(
:host => "0.0.0.0",
:port => APP_CONFIG[:socket_port],
- :debug =>APP_CONFIG[:debug]) do |ws|
+ :debug =>APP_CONFIG[:socket_debug]) do |ws|
ws.onopen {
sid = Diaspora::WebSocket.subscribe(ws.request['Path'].gsub('/',''), ws)
diff --git a/config/routes.rb b/config/routes.rb
index 946d34729..f2b4ebd80 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,10 +1,10 @@
Diaspora::Application.routes.draw do
- resources :people
+ resources :people, :only => [:index, :show, :destroy]
resources :users, :except => [:create, :new]
- resources :status_messages
- resources :comments
- resources :requests
- resources :photos
+ resources :status_messages, :except => [:index]
+ resources :comments, :except => [:index]
+ resources :requests, :except => [:edit, :update]
+ resources :photos, :except => [:index]
resources :albums
resources :groups
diff --git a/lib/mongo_mapper/clear_dev_memory.rb b/lib/mongo_mapper/clear_dev_memory.rb
new file mode 100644
index 000000000..aebf675dc
--- /dev/null
+++ b/lib/mongo_mapper/clear_dev_memory.rb
@@ -0,0 +1,19 @@
+module MongoMapper
+ class ClearDevMemory
+ def initialize(app)
+ @app = app
+ end
+
+ def call(env)
+ if Rails.configuration.cache_classes
+ else
+ MongoMapper::Document.descendants.each do |m|
+ m.descendants.clear if m.respond_to? :descendants
+ end
+ MongoMapper::Document.descendants.clear
+ MongoMapper::EmbeddedDocument.descendants.clear
+ end
+ @app.call(env)
+ end
+ end
+end
diff --git a/lib/salmon/salmon.rb b/lib/salmon/salmon.rb
new file mode 100644
index 000000000..a20f35796
--- /dev/null
+++ b/lib/salmon/salmon.rb
@@ -0,0 +1,220 @@
+# Add URL safe Base64 support
+module Base64
+ module_function
+ # Returns the Base64-encoded version of +bin+.
+ # This method complies with RFC 4648.
+ # No line feeds are added.
+ def strict_encode64(bin)
+ [bin].pack("m0")
+ end
+
+ # Returns the Base64-decoded version of +str+.
+ # This method complies with RFC 4648.
+ # ArgumentError is raised if +str+ is incorrectly padded or contains
+ # non-alphabet characters. Note that CR or LF are also rejected.
+ def strict_decode64(str)
+ str.unpack("m0").first
+ end
+
+ # Returns the Base64-encoded version of +bin+.
+ # This method complies with ``Base 64 Encoding with URL and Filename Safe
+ # Alphabet'' in RFC 4648.
+ # The alphabet uses '-' instead of '+' and '_' instead of '/'.
+ def urlsafe_encode64(bin)
+ strict_encode64(bin).tr("+/", "-_")
+ end
+
+ # Returns the Base64-decoded version of +str+.
+ # This method complies with ``Base 64 Encoding with URL and Filename Safe
+ # Alphabet'' in RFC 4648.
+ # The alphabet uses '-' instead of '+' and '_' instead of '/'.
+ def urlsafe_decode64(str)
+ strict_decode64(str.tr("-_", "+/"))
+ end
+end
+
+# Verify documents secured with Magic Signatures
+module Salmon
+ class SalmonSlap
+ attr_accessor :magic_sig, :user, :data, :data_type, :sig
+ def self.parse(xml)
+ slap = self.new
+ doc = Nokogiri::XML(xml)
+
+ sig_doc = doc.search('entry')
+ slap.magic_sig = MagicSigEnvelope.parse sig_doc
+
+
+
+ if 'base64url' == slap.magic_sig.encoding
+ slap.data = decode64url(slap.magic_sig.data)
+ slap.sig = slap.magic_sig.sig
+ else
+ raise ArgumentError, "Magic Signature data must be encoded with base64url, was #{slap.magic_sig.encoding}"
+ end
+
+ slap.data_type = slap.magic_sig.data_type
+
+ raise ArgumentError, "Magic Signature data must be signed with RSA-SHA256, was #{slap.magic_sig.alg}" unless 'RSA-SHA256' == slap.magic_sig.alg
+
+ slap
+ end
+
+
+
+ def self.create(user, activity)
+ salmon = self.new
+ salmon.user = user
+ salmon.magic_sig = MagicSigEnvelope.create(user, activity)
+ salmon
+ end
+
+ def to_xml
+ xml =<
+
+
+ #{@user.real_name}
+ acct:#{@user.email}
+
+ #{@magic_sig.to_xml}
+
+ENTRY
+
+ end
+
+ # Decode URL-safe-Base64. This implements
+ def self.decode64url(str)
+ # remove whitespace
+ sans_whitespace = str.gsub(/\s/, '')
+ # pad to a multiple of 4
+ string = sans_whitespace + '=' * ((4 - sans_whitespace.size) % 4)
+ # convert to standard Base64
+ # string = padded.tr('-','+').tr('_','/')
+
+ # Base64.decode64(string)
+ Base64.urlsafe_decode64 string
+ end
+
+ # def verified?
+ #
+ # end
+
+ # Check whether this envelope's signature can be verified with the
+ # provided OpenSSL::PKey::RSA public_key.
+ # Example:
+ #
+ # env.verified_for_key? OpenSSL::PKey::RSA.new(File.open('public_key.pem'))
+ # # -> true
+ def verified_for_key?(public_key)
+ signature = Base64.urlsafe_decode64(self.magic_sig.sig)
+ signed_data = self.magic_sig.signable_string# Base64.urlsafe_decode64(self.magic_sig.signable_string)
+
+
+ public_key.verify(OpenSSL::Digest::SHA256.new, signature, signed_data )
+ end
+
+ # Decode a string containing URL safe Base64 into an integer
+ # Example:
+ #
+ # MagicSig.b64_to_n('AQAB')
+ # # -> 645537
+ def self.b64_to_n(str)
+ packed = decode64url(str)
+ packed.unpack('B*')[0].to_i(2)
+ end
+
+ # Parse a string containing a magic-public-key into an OpenSSL::PKey::RSA key.
+ # Example:
+ #
+ # key = MagicSig.parse_key('RSA.mVgY8RN6URBTstndvmUUPb4UZTdwvwmddSKE5z_jvKUEK6yk1u3rrC9yN8k6FilGj9K0eeUPe2hf4Pj-5CmHww.AQAB')
+ # key.n
+ # # -> 8031283789075196565022891546563591368344944062154100509645398892293433370859891943306439907454883747534493461257620351548796452092307094036643522661681091
+ # key.e
+ # # -> 65537
+ def self.parse_key(str)
+ n,e = str.match(/^RSA.([^.]*).([^.]*)$/)[1..2]
+ build_key(b64_to_n(n),b64_to_n(e))
+ end
+
+ # Take two integers e, n and create a new OpenSSL::PKey::RSA key with them
+ # Example:
+ #
+ # n = 9487834027867356975347184933768917275269369900665861930617802608089634337052392076689226301419587057117740995382286148368168197915234368486155306558161867
+ # e = 65537
+ # key = MagicSig.build_key(n,e)
+ # key.public_encrypt(...) # for sending to strangers
+ # key.public_decrypt(...) # very rarely used
+ # key.verify(...) # for verifying signatures
+ def self.build_key(n,e)
+ key = OpenSSL::PKey::RSA.new
+ key.n = n
+ key.e = e
+ key
+ end
+
+
+
+
+
+
+ end
+
+ class MagicSigEnvelope
+ attr_accessor :data, :data_type, :encoding, :alg, :sig, :user
+ def self.parse(doc)
+ env = self.new
+ ns = {'me'=>'http://salmon-protocol.org/ns/magic-env'}
+ env.encoding = doc.search('//me:env/me:encoding', ns).text.strip
+ env.data = doc.search('//me:env/me:data', ns).text
+ env.alg = doc.search('//me:env/me:alg', ns).text.strip
+ env.sig = doc.search('//me:env/me:sig', ns).text
+ env.data_type = doc.search('//me:env/me:data', ns).first['type'].strip
+ env
+ end
+
+ def self.create(user, activity)
+ env = MagicSigEnvelope.new
+ env.user = user
+ env.data = Base64.urlsafe_encode64(activity)
+ env.data_type = env.get_data_type
+ env.encoding = env.get_encoding
+ env.alg = env.get_alg
+
+
+ env.sig = Base64.urlsafe_encode64(
+ user.encryption_key.sign OpenSSL::Digest::SHA256.new, env.signable_string )
+
+ env
+ end
+
+ def signable_string
+ [@data, Base64.urlsafe_encode64(@data_type),Base64.urlsafe_encode64(@encoding), Base64.urlsafe_encode64(@alg)].join(".")
+ end
+
+ def to_xml
+ xml= <
+ #{@data}
+ #{@encoding}
+ #{@alg}
+ #{@sig}
+
+ENTRY
+ xml
+ end
+
+ def get_encoding
+ 'base64url'
+ end
+
+ def get_data_type
+ 'application/atom+xml'
+ end
+
+ def get_alg
+ 'RSA-SHA256'
+ end
+
+ end
+end
diff --git a/lib/tasks/db.rake b/lib/tasks/db.rake
index 9b78b6855..fceb99430 100644
--- a/lib/tasks/db.rake
+++ b/lib/tasks/db.rake
@@ -29,7 +29,7 @@ namespace :db do
MongoMapper::connection.drop_database(MongoMapper::database.name)
puts 'Deleting tmp folder...'
- `rm -rf #{File.dirname(__FILE__)}/../../public/uploads/tmp`
+ `rm -rf #{File.dirname(__FILE__)}/../../public/uploads/*`
end
desc 'Purge and seed the current RAILS_ENV database using information from db/seeds.rb'
diff --git a/public/images/glyphish-icons/Read me first - license.txt b/public/images/glyphish-icons/Read me first - license.txt
new file mode 100644
index 000000000..b6be14a6e
--- /dev/null
+++ b/public/images/glyphish-icons/Read me first - license.txt
@@ -0,0 +1,13 @@
+Created by Joseph Wain (see http://penandthink.com) at and probably downloaded from http://glyphish.com
+
+This work is licensed under the Creative Commons Attribution 3.0 United States License. To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/us/ or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
+
+You are free to share it and to remix it remix under the following conditions:
+
+* You must attribute the work in the manner specified by the author (SEE BELOW).
+* For any reuse or distribution, you must make clear to others the license terms of this work.
+* The above conditions can be waived if you get permission from the copyright holder (send me an email!).
+
+ATTRIBUTION -- a note reading "icons by Joseph Wain / glyphish.com" or similar, plus a link back to glyphish.com from your app's website, is the preferred form of attribution. Also acceptable would be, like, a link from within your iPhone application, or from the iTunes store page, but those aren't as useful to other people. If none of these work for you, please contact hello@glyphish.com and we can work something out.
+
+USE WITHOUT ATTRIBUTION -- If attribution is not possible, workable or desirable for your application, contact hello@glyphish.com for commercial non-attributed licensing terms.
\ No newline at end of file
diff --git a/public/images/glyphish-icons/glyphish-icons.pdf b/public/images/glyphish-icons/glyphish-icons.pdf
new file mode 100644
index 000000000..b243980be
--- /dev/null
+++ b/public/images/glyphish-icons/glyphish-icons.pdf
@@ -0,0 +1,1637 @@
+%PDF-1.5
%
+1 0 obj
<>/OCGs[5 0 R]>>/Pages 3 0 R/Type/Catalog>>
endobj
2 0 obj
<>stream
+
+
+
+
+ application/pdf
+
+
+ glyphish-icons
+
+
+
+
+ Adobe Illustrator CS4
+ 2010-04-04T12:46:43-04:00
+ 2010-04-04T12:46:43-04:00
+ 2010-04-04T12:46:43-04:00
+
+
+
+ 188
+ 256
+ JPEG
+ /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA
AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK
DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f
Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAAC8AwER
AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA
AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB
UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE
1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ
qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy
obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp
0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo
+DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8Alfkn8wdckv8AyTotzrdr
5a0mfR4LsIbaMjUJ3uGhNtG7gJFRVFOO9fGuylCaJ+dXnc6tqM9zqFtetFZ65c3Xlr6o0TaYdLjd
7f1JwFZxKVCmrfj0VpGQ+f8A80rHRNYt7zXLG41OTSNM1rTdQuYoLOO3F/Nwkgq3GFqLsjSbV64q
yG+8yX3mP/nHXVdYTUJ3u5NPvBLeyQwwyP6MjpIvGEtFRlUpyQ7j4tjtiqG0qTzP5YkudE0C7T9E
eVPLY1NdMFrGXv7y5Fw6Kzj40HOIbJucVYppH5yefJvLurtba9a6zdm20p7fUVsxCthd6jciGW2d
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
AJOKH//Z
+
+
+
+
+
+ xmp.did:F97F11740720681195FEA64C1488983D
+ uuid:5090f4ca-02a0-1647-8100-08dae33ca097
+ proof:pdf
+ uuid:097168A5C0A6DD11BA5DD84E8E1FB577
+
+ uuid:540ef98a-a130-1d4e-a5cd-e404e130aa3f
+ xmp.did:F87F11740720681197A5F9CC61D5EB76
+ uuid:097168A5C0A6DD11BA5DD84E8E1FB577
+ proof:pdf
+
+
+
+
+ saved
+ xmp.iid:F77F11740720681197A5CB309D789073
+ 2009-01-17T11:17:53-05:00
+ Adobe Illustrator CS4
+ /
+
+
+ saved
+ xmp.iid:F77F11740720681195FED32A091F692F
+ 2009-05-09T19:38:52-04:00
+ Adobe Illustrator CS4
+ /
+
+
+ saved
+ xmp.iid:F87F11740720681197A5F9CC61D5EB76
+ 2009-09-07T15:01:22-04:00
+ Adobe Illustrator CS4
+ /
+
+
+ saved
+ xmp.iid:F97F11740720681195FEA64C1488983D
+ 2010-04-04T12:46:41-04:00
+ Adobe Illustrator CS4
+ /
+
+
+
+
+
+ Print
+
+
+ 1
+ True
+ False
+
+ 479.999512
+ 624.000000
+ Pixels
+
+
+
+ Cyan
+ Magenta
+ Yellow
+ Black
+
+
+
+
+
+ Default Swatch Group
+ 0
+
+
+
+ White
+ RGB
+ PROCESS
+ 255
+ 255
+ 255
+
+
+ K=25
+ GRAY
+ PROCESS
+ 63
+
+
+ CMYK Magenta
+ RGB
+ PROCESS
+ 234
+ 0
+ 138
+
+
+ K=100
+ PROCESS
+ 100.000000
+ RGB
+ 35
+ 31
+ 32
+
+
+
+
+
+
+
+
+ Adobe PDF library 9.00
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
endstream
endobj
3 0 obj
<>
endobj
7 0 obj
<>/Resources<>/Properties<>/XObject<>>>/Thumb 89 0 R/TrimBox[0.0 0.0 480.0 624.0]/Type/Page>>
endobj
8 0 obj
<>stream
+HWK$)]C&[x8"2Y]=1$L~߿/z<~[=LǓ?3>c?_3qsm,Ȩk0r`/'"
wD-Ȳ#x9ɂ3$*b
+ 5!K&SP(ESd%'`/h. gRZ*SW`3v"wT!z@qɞD Ah
+ax3+6#T{_Yu0mEx*F`1
+N@iQ错@U,9jyNPrWU"TQ[gv@,;cl^FTѺ6mcZ-C"^LteaQ:Ta]Jft7bS:'Ttq+S~PZSMx,BՃm de)z^$(?T)n浲̗F/h},=P:5:12VI !qf8YoaHB"̣ [m({MS}C>!(X=sbu:T%t:e
+W.KYOEiT,(:mwfM