Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge remote-tracking branch 'ovh/master'

  • Loading branch information...
commit 74f5dab628506cb704eb5ea98027f9a0690a3759 2 parents 9c7695e + 6586088
Arthur PETRY authored
Showing with 784 additions and 127 deletions.
  1. +36 −5 app/controllers/albums_controller.rb
  2. +2 −1  app/controllers/application_controller.rb
  3. +23 −8 app/controllers/comments_controller.rb
  4. +2 −0  app/controllers/home_controller.rb
  5. +66 −0 app/controllers/lists_controller.rb
  6. +37 −0 app/controllers/posts_controller.rb
  7. +8 −20 app/controllers/sessions_controller.rb
  8. +15 −4 app/helpers/application_helper.rb
  9. +4 −1 app/models/album.rb
  10. +69 −0 app/models/list.rb
  11. +30 −0 app/models/modification.rb
  12. +32 −0 app/models/paginator.rb
  13. +24 −0 app/models/post.rb
  14. +11 −6 app/models/session.rb
  15. +1 −0  app/models/track.rb
  16. +1 −1  app/models/track_listening.rb
  17. +16 −2 app/models/user.rb
  18. +51 −0 app/models/user_list.rb
  19. +0 −8 app/views/albums/_last.html.haml
  20. +26 −0 app/views/albums/_lists.html.haml
  21. +12 −0 app/views/albums/_paginated.html.haml
  22. +5 −7 app/views/albums/_randomly.html.haml
  23. +2 −0  app/views/albums/show.html.haml
  24. +27 −14 app/views/home/index.html.haml
  25. +1 −2  app/views/layouts/application.html.haml
  26. +51 −0 app/views/lists/index.html.haml
  27. +25 −0 app/views/posts/index.html.haml
  28. +10 −0 app/views/posts/new.html.haml
  29. +12 −17 app/views/sessions/new.html.haml
  30. +4 −0 app/views/sessions/waiting_activation.html.haml
  31. +12 −1 config/routes.rb
  32. +13 −11 public/javascripts/application.js
  33. +17 −16 public/stylesheets/application.css
  34. +112 −0 spec/models/list_spec.rb
  35. +27 −3 spec/spec_helper.rb
View
41 app/controllers/albums_controller.rb
@@ -5,18 +5,49 @@ def index
if q = params[:q]
# conditions = {:artist => /#{q}/i, :name => /#{q}/i}
# see http://www.mongodb.org/display/DOCS/OR+operations+in+query+expressions
- conditions = { "$where" => "this.name.match(/#{q}/i) || this.artist.match(/#{q}/i)" }
+ # this can shutdown the server !
+ # conditions = { "$where" => "this.name.match(/#{q}/i) || this.artist.match(/#{q}/i)" }
+ conditions = nil # disabled for now.
end
if params[:randomly]
@albums = Album.find_randomly
render :partial => "albums/randomly"
return
end
- if params[:last_page]
- @last_albums = Album.find_last(params[:last_page])
- render :partial => "albums/last"
+ if params[:last]
+ albums_params = {:last => true}
+ if params[:user_id]
+ user = User.find(params[:user_id])
+ albums_params[:user_id] = user.id
+ albums = user.last_uploaded_albums(params[:page])
+ else
+ albums = Album.find_last(params[:page])
+ end
+ render :partial => "albums/paginated", :locals => {:albums => albums, :albums_params => albums_params}
+ return
+ end
+ if params[:user_id] && params[:preferred]
+ user = User.find(params[:user_id])
+ votes = user.last_votes(params[:page])
+ render :partial => "albums/paginated", :locals => {
+ :albums => votes.map(&:album),
+ :paginator => votes,
+ :albums_params => {:user_id => user.id, :preferred => true}
+ }
return
end
+ if params[:user_id] && params[:list_id]
+ user = User.find(params[:user_id])
+ list = user.list_by_id(params[:list_id])
+ paginator = Paginator.new(list.album_ids, :class => Album, :page => params[:page])
+ render :partial => "albums/paginated", :locals => {
+ :albums => paginator.objects_in_page,
+ :paginator => paginator,
+ :albums_params => {:user_id => list.user.id, :list_id => list.list_id}
+ }
+ return
+ end
+
@albums ||= Album.paginate(:order => 'artist, name', :per_page => params[:limit] || 50, :conditions => conditions, :page => params[:page])
end
@@ -76,4 +107,4 @@ def album
@album ||= Album.find(params[:id])
end
-end
+end
View
3  app/controllers/application_controller.rb
@@ -34,7 +34,8 @@ def login_required
def ensure_activated
if current_user && !current_user.activated
- redirect_to root_path
+ render :file => "sessions/waiting_activation"
+ false
end
end
View
31 app/controllers/comments_controller.rb
@@ -6,12 +6,19 @@ def new
end
def create
- album.comments << Comment.new(params[:comment])
- @comment = album.comments.last
+ @comment = Comment.new(params[:comment])
@comment.author = current_user
- @album.save
- @album.save_user_comment_for @comment
- create_or_update_response
+
+ if album
+ album.comments << @comment
+ @album.save
+ @album.save_user_comment_for @comment
+ create_or_update_response
+ elsif post
+ post.comments << @comment
+ post.save
+ redirect_to posts_path
+ end
end
def edit
@@ -35,12 +42,20 @@ def create_or_update_response
end
end
+ def comment_from_params_id
+ album_or_post.comments.detect{|c| c.id == params[:id]}
+ end
+
+ def album_or_post
+ album || post
+ end
+
def album
- @album ||= Album.find(params[:album_id])
+ @album ||= params[:album_id] && Album.find(params[:album_id])
end
- def comment_from_params_id
- album.comments.detect{|c| c.id == params[:id]}
+ def post
+ @post ||= params[:post_id] && Post.find(params[:post_id])
end
end
View
2  app/controllers/home_controller.rb
@@ -2,9 +2,11 @@ class HomeController < ApplicationController
skip_before_filter :ensure_activated
def index
+ @last_blog_post = Post.last
@last_listenings = TrackListening.find(:all, :order => 'created_at DESC', :limit => 10)
@last_comments = UserComment.find(:all, :order => 'created_at DESC', :limit => 10)
@last_albums = Album.find_last
+ @users = User.all.sort_by{|u| u.last_uploaded_albums.empty? ? 0 : u.last_uploaded_albums.total_entries}.reverse
end
end
View
66 app/controllers/lists_controller.rb
@@ -0,0 +1,66 @@
+class ListsController < ApplicationController
+
+ def index
+ user = params[:user_id] ? User.find(params[:user_id]) : current_user
+ @lists = user.user_lists.each{|l| l.user = user}
+ @new_list = List.new
+ end
+
+ def create
+ list = List.new(params[:list])
+ list.author = current_user
+ list.save
+ redirect_to :action => :index
+ end
+
+ def add_album
+ list.add(:album_id => params[:album_id], :author => current_user)
+ list_in_album_update_response
+ end
+
+ def remove_album
+ list.remove(:album_id => params[:album_id], :author => current_user)
+ list_in_album_update_response
+ end
+
+ def accept_modification
+ logger
+ modification && modification.accept(:author => current_user)
+ redirect_to :action => :index
+ end
+
+ def reject_modification
+ modification && modification.reject(:author => current_user)
+ redirect_to :action => :index
+ end
+
+ def follow
+ list.follow_by(current_user)
+ redirect_to :action => :index
+ end
+
+protected
+
+ def list_in_album_update_response
+ respond_to do |format|
+ format.js do
+ @album = Album.find(params[:album_id])
+ render :partial => "albums/lists"
+ end
+ format.html do
+ redirect_to album_path(params[:album_id])
+ end
+ end
+ end
+
+ def list
+ @list ||= List.find(params[:id])
+ end
+
+ def modification
+ @modification ||= list.modifications.detect{|m| m.id.to_s == params[:modification_id]}
+ @modification.list = list
+ @modification
+ end
+
+end
View
37 app/controllers/posts_controller.rb
@@ -0,0 +1,37 @@
+class PostsController < ApplicationController
+
+ def index
+ @posts = Post.all
+ @comment = Comment.new
+ end
+
+ def new
+ @post = Post.new
+ end
+
+ def create
+ @post = Post.new(params[:post])
+ @post.author_id = current_user.id
+ if @post.save
+ redirect_to :action => :index
+ else
+ render :action => :new
+ end
+ end
+
+ def edit
+ @post = Post.find(params[:id])
+ render :action => :new
+ end
+
+ def update
+ @post = Post.find(params[:id])
+ @post.author_id = current_user.id
+ if @post.update_attributes(params[:post])
+ redirect_to :action => :index
+ else
+ render :action => :edit
+ end
+ end
+
+end
View
28 app/controllers/sessions_controller.rb
@@ -2,7 +2,6 @@
require 'openid/extensions/ax'
require 'openid/extensions/sreg'
-
class SessionsController < ApplicationController
skip_before_filter :login_required
@@ -12,19 +11,13 @@ def new
def create
session = Session.new(params[:session])
- logger.debug ["openid_url_or_gmail", session.openid_url_or_gmail].inspect
- open_id_request = consumer.begin(session.openid_url_or_gmail)
+ logger.debug ["openid_provider_url", session.openid_provider_url].inspect
+ open_id_request = consumer.begin(session.openid_provider_url)
+
+ ax_request = OpenID::AX::FetchRequest.new
+ ax_request.add(OpenID::AX::AttrInfo.new("http://axschema.org/contact/email", nil, true ))
+ open_id_request.add_extension(ax_request)
- if session.gmail?
- ax_request = OpenID::AX::FetchRequest.new
- ax_request.add(OpenID::AX::AttrInfo.new("http://schema.openid.net/contact/email", nil, true ))
- open_id_request.add_extension(ax_request)
- else
- sregreq = OpenID::SReg::Request.new
- sregreq.request_fields(['email','nickname'], true)
- open_id_request.add_extension(sregreq)
- open_id_request.return_to_args['did_sreg'] = 'y'
- end
redirect_to open_id_request.redirect_url(root_url, openid_complete_session_url, params[:immediate])
end
@@ -47,14 +40,9 @@ def openid_complete
when OpenID::Consumer::SUCCESS
ax_response = OpenID::AX::FetchResponse.from_success_response(openid_response)
if ax_response && ax_response.data
- email = ax_response.data["http://schema.openid.net/contact/email"].first
+ email = ax_response.data["http://axschema.org/contact/email"].first
flash[:ax_response] = ax_response.data
end
- sreg_resp = OpenID::SReg::Response.from_success_response(openid_response)
- unless sreg_resp.empty?
- email = sreg_resp.data["email"]
- end
- flash[:sreg_results] = sreg_resp.data
when OpenID::Consumer::SETUP_NEEDED
flash[:alert] = "Immediate request failed - Setup Needed"
when OpenID::Consumer::CANCEL
@@ -76,4 +64,4 @@ def consumer
@consumer ||= OpenID::Consumer.new(session, OpenIdStore.new)
end
-end
+end
View
19 app/helpers/application_helper.rb
@@ -15,17 +15,28 @@ def cover_img_tag(record_with_cover, size=40)
end
end
+ def album_name_with_link(album)
+ content_tag(:span, h(album.artist), :class => 'artist') +
+ link_to(h(album.name), album_path(album), :class => 'album_name')
+ end
+
def album_div(album)
content_tag(:div,
content_tag(:div,
cover_img_tag(album) +
content_tag(:div, "", :class => "pointer"),
:class => 'in_first_line') +
- content_tag(:div,
- content_tag(:span, h(album.artist), :class => 'artist') +
- link_to(h(album.name), album_path(album), :class => 'album_name'),
- :class => "info"),
+ content_tag(:div, album_name_with_link(album), :class => "info"),
:class => 'cover_album')
end
+
+ def no_one_or_n_comments(comments)
+ case comments.length
+ when 0 then "Aucun commentaire"
+ when 1 then "1 commentaire"
+ else "#{comments.length} commentaires"
+ end
+ end
+
end
View
5 app/models/album.rb
@@ -12,6 +12,8 @@ class Album
key :amazon_asin, String
key :musicbrainz_release_id, String
+ key :user_id, String # author
+
timestamps
many :votes
@@ -86,7 +88,8 @@ def hated_by(user)
UserVote.delete_all(:album_id => id, :author_id => user.id)
votes.delete_if{|v| v.author_id == user.id}
votes << Vote.new(:note => -1, :author => user)
- UserVote.create(:album_id => id, :author_id => user.id, :note => -1)
+ # only create UserVote for positive ones for now.
+ # UserVote.create(:album_id => id, :author_id => user.id, :note => -1)
end
def haters
View
69 app/models/list.rb
@@ -0,0 +1,69 @@
+class List
+ include MongoMapper::Document
+
+ key :name, String, :required => true
+ many :modifications
+ key :author_id, String, :required => true
+ # belongs_to :author, :class_name => "User"
+
+ include Timestamp
+ timestamps
+
+ after_save :create_author_user_list
+
+ def author=(author)
+ self.author_id = author.id
+ end
+
+ def author
+ @author ||= author_id && User.find(author_id)
+ end
+
+ def add(params)
+ add_or_remove(:add, params)
+ end
+
+ def remove(params)
+ add_or_remove(:remove, params)
+ end
+
+ def follow_by(user)
+ user_list = user.list_by_id(id)
+ return user_list if user_list
+ user_list = UserList.new(:name => name, :list_id => id)
+ user.user_lists << user_list
+ user.save
+ modifications.each do |modification|
+ modification.list = self
+ modification.accept(:author => user)
+ end
+ user_list
+ end
+
+ def add_or_remove(action, params)
+ author_id = params[:author_id]
+ author_id ||= params[:author] && params[:author].id
+ album_id = params[:album_id]
+ raise "missing :author_id or author" unless author_id
+ raise "missing :album_id" unless author_id
+ author = params[:author] || User.find(author_id)
+ user_list = follow_by(author)
+ modification = Modification.new(:author_id => author_id, :action => action.to_s, :album_id => album_id)
+ modification.list = self
+ modifications << modification
+ save
+ modification.accept(:author => author)
+ end
+
+protected
+ def create_author_user_list
+ user_list = author.list_by_id(id)
+ unless user_list
+ user_list = UserList.new(:name => name, :list_id => id)
+ author.user_lists << user_list
+ author.save
+ end
+ end
+
+
+end
View
30 app/models/modification.rb
@@ -0,0 +1,30 @@
+class Modification
+
+ include MongoMapper::EmbeddedDocument
+ include Timestamp
+ # embedded_in :list
+ attr_accessor :list
+
+ belongs_to :author, :class_name => "User"
+ belongs_to :album
+ key :author_id, String, :required => true
+ key :album_id, String, :required => true
+ key :action, String, :required => true # add or remove
+
+ def accept(params)
+ accept_or_reject(:accept, params)
+ end
+
+ def reject(params)
+ accept_or_reject(:reject, params)
+ end
+
+ def accept_or_reject(action, params)
+ author_id = params[:author_id]
+ author_id ||= params[:author] && params[:author].id
+ raise "missing :author_id or author" unless author_id
+ author = params[:author] || User.find(author_id)
+ author.list_by_id(self.list.id).send(action, self)
+ end
+
+end
View
32 app/models/paginator.rb
@@ -0,0 +1,32 @@
+class Paginator
+
+ def initialize(ids, options = {})
+ @ids = ids
+ @per_page = options[:per_page] ? options[:per_page].to_i : 10
+ @page = options[:page] ? options[:page].to_i : 1
+ @class = options[:class]
+ end
+
+ attr_reader :ids, :page, :per_page
+
+ def pages_count
+ (ids.length.to_f/per_page).ceil
+ end
+
+ def previous_page
+ page > 1 ? page - 1 : nil
+ end
+
+ def next_page
+ page < pages_count ? page + 1 : nil
+ end
+
+ def ids_in_page
+ (((page - 1) * per_page)..((page*per_page) - 1)).map{ |i| ids[i] }.compact
+ end
+
+ def objects_in_page
+ @objects_in_page ||= ids_in_page.map{|id| @class.find(id)}
+ end
+
+end
View
24 app/models/post.rb
@@ -0,0 +1,24 @@
+class Post
+
+ include MongoMapper::Document
+ include Timestamp
+ timestamps
+
+ key :title, String, :required => true
+ key :body, String, :required => true
+ key :author_id, String, :required => true
+ belongs_to :author, :class_name => "User"
+
+ many :comments
+
+ before_save :timestamps_in_comments
+
+ def timestamps_in_comments
+ current_time = Time.now.utc
+ comments.each do |comment|
+ comment.created_at ||= current_time
+ comment.updated_at ||= current_time
+ end
+ end
+
+end
View
17 app/models/session.rb
@@ -2,19 +2,24 @@ class Session
attr_accessor :email
attr_accessor :openid_url
+ attr_accessor :openid_provider
- def gmail?
- openid_url.blank?
- end
-
- def openid_url_or_gmail
- openid_url.blank? ? "https://www.google.com/accounts/o8/id" : openid_url
+ def openid_provider_url
+ case openid_provider
+ when "google"
+ "https://www.google.com/accounts/o8/id"
+ when "yahoo"
+ "https://me.yahoo.com/"
+ else
+ openid_url
+ end
end
def initialize(attributes={})
attributes ||= {}
self.email = attributes[:email]
self.openid_url = attributes[:openid_url]
+ self.openid_provider = attributes[:openid_provider]
end
end
View
1  app/models/track.rb
@@ -59,6 +59,7 @@ def set_album
if album.nil? || album.artist != album_artist || album.name != album_name
old_album = album
self.album = Album.find_or_create_by_artist_and_name(album_artist, album_name)
+ album.user_id ||= user_id
album.add_track(self)
album.save
if old_album
View
2  app/models/track_listening.rb
@@ -15,4 +15,4 @@ def album
track && track.album
end
-end
+end
View
18 app/models/user.rb
@@ -9,6 +9,8 @@ class User
key :activated, Boolean
key :roles, Array
+ many :user_lists
+
def roles_str
roles.join(', ')
end
@@ -21,8 +23,20 @@ def admin?
roles.include?("admin")
end
- def last_preferred_albums
- UserVote.find_all_by_author_id(id, :order => 'created_at DESC', :limit => 10).select{|v| v.note > 0}.map(&:album_id).uniq.map{|album_id| Album.find(album_id)}
+ def last_votes(page = 1)
+ UserVote.paginate(:order => 'created_at DESC', :conditions => {:author_id => id}, :per_page => 10, :page => page)
+ # FIXME : conditions to have only positive votes
+ # .select{|v| v.note > 0}
+ end
+
+ def last_uploaded_albums(page = 1)
+ Album.paginate(:order => 'created_at DESC', :conditions => {:user_id => id}, :per_page => 10, :page => page)
+ end
+
+ def list_by_id(id)
+ list = user_lists.detect{|l| l.list_id == id}
+ list.user = self if list
+ list
end
end
View
51 app/models/user_list.rb
@@ -0,0 +1,51 @@
+class UserList
+
+ include MongoMapper::EmbeddedDocument
+
+ key :list_id, String, :required => true
+ key :name, String, :required => true
+ key :album_ids, Array
+ key :accepted_modification_ids, Array
+ key :rejected_modification_ids, Array
+
+ attr_accessor :user
+
+ def accept(modification)
+ if modification.action == "add"
+ album_ids << modification.album_id
+ else
+ album_ids.delete(modification.album_id)
+ end
+ accepted_modification_ids << modification.id
+ RAILS_DEFAULT_LOGGER.debug "accepted_modification #{modification.id} by #{user.id}"
+ user.save
+ end
+
+ def reject(modification)
+ if modification.action == "remove"
+ album_ids << modification.album_id
+ else
+ album_ids.delete(modification.album_id)
+ end
+ rejected_modification_ids << modification.id
+ user.save
+ end
+
+ def list
+ @list ||= List.find(list_id)
+ end
+
+ def albums
+ @albums ||= album_ids.map{|id| Album.find(id)}.compact
+ end
+
+ def pending_modifications(reload = false)
+ @pending_modifications = nil if reload
+ @pending_modifications ||= list.modifications.reject{|m| accepted_modification_ids.include?(m.id) || rejected_modification_ids.include?(m.id) }.each{|m| m.list = list}
+ end
+
+ def to_param
+ id
+ end
+
+end
View
8 app/views/albums/_last.html.haml
@@ -1,8 +0,0 @@
-.last_albums.albums_group
- %h3 les derniers albums importés:
- %ul.links
- %li= link_to "«", albums_path(:last_page => @last_albums.current_page - 1)
- %li= link_to "»", albums_path(:last_page => @last_albums.current_page + 1)
- %ul.albums
- - @last_albums.each do |album|
- %li= album_div(album)
View
26 app/views/albums/_lists.html.haml
@@ -0,0 +1,26 @@
+.lists
+ - in_lists = current_user.user_lists.select{|list| list.album_ids.include?(@album.id)}
+ - other_lists = current_user.user_lists - in_lists
+ .in_lists
+ - unless in_lists.blank?
+ %p Dans les listes suivantes :
+ %ul
+ - in_lists.each do |list|
+ %li
+ %span.name=h list.name
+ .remove
+ - form_tag remove_album_list_path(list.list_id), :method => :delete do
+ = hidden_field_tag :album_id, @album.id
+ = submit_tag "enlever"
+
+ .not_in_lists
+ - unless other_lists.blank?
+ %p l'ajouter à une liste :
+ %ul
+ - other_lists.each do |list|
+ %li
+ %span.name=h list.name
+ .add
+ - form_tag add_album_list_path(list.list_id) do
+ = hidden_field_tag :album_id, @album.id
+ = submit_tag "ajouter"
View
12 app/views/albums/_paginated.html.haml
@@ -0,0 +1,12 @@
+- paginator ||= albums
+%ul.links
+ %li{:class => "#{"empty" unless paginator.previous_page}"}
+ - if paginator.previous_page
+ = link_to "«", albums_path(albums_params.merge(:page => paginator.previous_page))
+ %li{:class => "#{"empty" unless paginator.next_page}"}
+ - if paginator.next_page
+ = link_to "»", albums_path(albums_params.merge(:page => paginator.next_page))
+
+%ul.albums
+ - albums.each do |album|
+ %li= album_div(album)
View
12 app/views/albums/_randomly.html.haml
@@ -1,7 +1,5 @@
-.albums_group.randomly
- %h3 Albums choisis aléatoirement:
- %ul.links
- %li.last= link_to "∞", albums_path(:randomly => true)
- %ul.albums
- - Album.find_randomly.each do |album|
- %li= album_div(album)
+%ul.links
+ %li.last= link_to "∞", albums_path(:randomly => true)
+%ul.albums
+ - Album.find_randomly.each do |album|
+ %li= album_div(album)
View
2  app/views/albums/show.html.haml
@@ -32,3 +32,5 @@
= render :partial => "votes.html"
= render :partial => "comments.html"
+
+ = render :partial => "lists.html"
View
41 app/views/home/index.html.haml
@@ -3,31 +3,44 @@
- form_tag albums_path, :method => :get do
= text_field_tag :q
= submit_tag "Rechercher"
-
+
%p= link_to "liste (très moche) des albums", albums_path
%p= link_to "ajouter des fichiers", new_track_path
%ul.two_cols
%li.left_col
- =render :partial => "albums/randomly"
- =render :partial => "albums/last"
+ .randomly
+ %h3 Albums choisis aléatoirement:
+ .albums_group=render :partial => "albums/randomly"
+ .last_albums
+ %h3 les derniers albums importés:
+ .albums_group=render :partial => "albums/paginated", :locals => {:albums => @last_albums, :albums_params => {:last => true}}
- .preferred_albums
- %h3
- Albums préférés:
+ .users
+ %h2 Utilisateurs
%ul
- - User.all.each do |user|
- - albums = user.last_preferred_albums
- - unless albums.empty?
+ - @users.each do |user|
+ - votes = user.last_votes
+ - last_uploaded = user.last_uploaded_albums
+ - unless votes.empty? && last_uploaded.empty?
%li
- .albums_group
- =h(user.nickname)
- %ul.albums
- - albums.each do |album|
- %li= album_div(album)
+ %h3.nickname=h(user.nickname)
+ - unless votes.empty?
+ %p= "#{votes.total_entries} albums préférés."
+ .albums_group
+ = render :partial => "albums/paginated", :locals => {:albums => votes.map(&:album), :paginator => votes, :albums_params => {:user_id => user.id, :preferred => true}}
+ - unless last_uploaded.empty?
+ %p= "#{last_uploaded.total_entries} albums uploadés."
+ .albums_group
+ = render :partial => "albums/paginated", :locals => {:albums => last_uploaded, :albums_params => {:user_id => user.id, :last => true}}
%li.right_col
+ - if @last_blog_post
+ .last_blog_post
+ %h3 Sur le blog :
+ = link_to @last_blog_post.title, posts_path
+
.last_comments.last_thing
%h3 derniers commentaires :
%ul
View
3  app/views/layouts/application.html.haml
@@ -29,7 +29,6 @@
= yield
#footer
- - if controller_name != "home"
+ - if controller_name != "home" and current_user
%p
= link_to "home", root_path
-
View
51 app/views/lists/index.html.haml
@@ -0,0 +1,51 @@
+
+.mine
+ %h2 mes listes d'albums
+
+ %ul
+ - @lists.each do |list|
+ %li
+ %h3=h list.name
+ %span.count= "(#{pluralize(list.album_ids.length, "album")})"
+ - if list.list.author.id != list.user.id
+ %span.participation= "Participation à la liste de #{list.list.author.nickname}"
+ - unless list.album_ids.blank?
+ - paginator = Paginator.new(list.album_ids, :class => Album)
+ .albums_group= render :partial => "albums/paginated", :locals => {:albums => paginator.objects_in_page, :paginator => paginator, :albums_params => {:user_id => list.user.id, :list_id => list.list_id}}
+
+ - unless list.pending_modifications.blank?
+ %ul.pending_modifications
+ - list.pending_modifications.each do |modification|
+ %li
+ %span.author= modification.author.nickname
+ %span.action= modification.action == "add" ? "propose d'ajouter" : "propose d'enlever"
+ %span.album= "l'album : " + album_name_with_link(modification.album)
+ .accept
+ - form_tag accept_modification_list_path(modification.list) do
+ = hidden_field_tag "modification_id", modification.id
+ = submit_tag "accepter"
+ .reject
+ - form_tag reject_modification_list_path(modification.list), :method => :delete do
+ = hidden_field_tag "modification_id", modification.id
+ = submit_tag "rejeter"
+
+
+ .new
+ %h3 Ajouter une nouvelle liste
+ - form_for @new_list, :url => lists_path, :html => {:method => :POST} do |f|
+ .title
+ = f.text_field :name
+
+ = submit_tag "Ajouter"
+
+
+.others
+ %h2 Listes d'autres utilisateurs
+ %ul
+ - List.all.delete_if{|list| @lists.map(&:list_id).include?(list.id)}.each do |list|
+ %li
+ %span.name= list.name
+ %span.author= list.author.nickname
+ .follow
+ - form_tag follow_list_path(list) do
+ = submit_tag "participer"
View
25 app/views/posts/index.html.haml
@@ -0,0 +1,25 @@
+%ul.posts
+ - @posts.each do |post|
+ %li.post
+ %h1= post.title
+ - if current_user.admin?
+ .action= link_to "edit", edit_post_path(post)
+ .body= post.body
+ .author= post.author.nickname
+ .timestamp= post.created_at.to_s(:db)
+
+ .comments
+ %p.summary= no_one_or_n_comments(post.comments)
+ %ul.comments
+ - post.comments.each do |comment|
+ %li
+ .body= comment.body
+ .author_and_date
+ %span.author= comment.author.nickname
+ ,
+ %span.date= comment.created_at.to_s(:db) if comment.created_at
+
+ %li.new_comment
+ - form_for(@comment, :url => post_comments_path(post), :html => {:method => :post}) do |f|
+ = f.text_area :body
+ = f.submit "Send"
View
10 app/views/posts/new.html.haml
@@ -0,0 +1,10 @@
+- form_for @post do |f|
+ .title
+ = f.label :title, "Titre :"
+ = f.text_field :title
+
+ .body
+ %div= f.text_area :body
+
+ = submit_tag "Sauver"
+
View
29 app/views/sessions/new.html.haml
@@ -1,19 +1,14 @@
-- form_for(@session, :url => session_path, :html => {:method => :post}) do |f|
- %p
- = f.label :openid_url
- = f.text_field :openid_url
- %p
- = f.submit "Login with Gmail or OpenID"
+.google
+ - form_for(@session, :url => session_path, :html => {:method => :post}) do |f|
+ = hidden_field_tag "session[openid_provider]", "google"
+ %p= f.submit "Signin with Google Account"
+ %p.hint si tu utilises GMail ou que tu as un compte Google
+.yahoo
+ - form_for(@session, :url => session_path, :html => {:method => :post}) do |f|
+ = hidden_field_tag "session[openid_provider]", "yahoo"
+ %p= f.submit "Signin with Yahoo! Id"
+ %p.hint si tu utilises Yahoo Mail ou que tu as un compte Yahoo! Id
-%ul.hints
- %li
- %p
- Si tu utilises GMail, tu n'as qu'à cliquer en laissant le champ "Openid url" vide.
- %li
- %p
- Si tu n'utilises pas GMail, il te faut une adresse OpenID, tu peux t'en créer une facilement là :
- = link_to "Créer une adresse OpenID chez OpenID France", "http://www.openidfrance.fr/home-2/Creez+votre+OpenID.html"
- %p
- Ensuite il suffit de revenir ici, et de remplir le champ "Openid url", puis de cliquer sur le bouton de login !
-
+.otherwise
+ Sinon, crée toi un compte google ou Yahoo pour utiliser onzeer.com !
View
4 app/views/sessions/waiting_activation.html.haml
@@ -0,0 +1,4 @@
+
+%p.thanks Merci pour votre inscription sur onzeer.com.
+
+%p.wait Nous activerons votre inscription dés que possible, a bientôt sur onzeer.com !
View
13 config/routes.rb
@@ -4,12 +4,23 @@
map.resources :tokens
- map.resources :users
+ map.resources :users, :has_many => :lists
map.resources :tracks, :member => {:just_listened => :post}, :collection => {:wanted => :post}
map.resources :albums, :member => {:like => :post, :hate => :post, :destroy_vote => :delete, :mb_releases => :get}, :has_many => [:comments]
+ map.resources :posts, :has_many => [:comments]
+ map.connect 'blog', :controller => "posts"
+
+ map.resources :lists, :member => {
+ :follow => :post,
+ :add_album => :post,
+ :remove_album => :delete,
+ :accept_modification => :post,
+ :reject_modification => :delete,
+ }
+
map.root :controller => 'home'
end
View
24 public/javascripts/application.js
@@ -37,7 +37,7 @@ function playNow(id, auto) {
// set the class playing on the current track_li
track_element.addClass('playing');
}
- // audio.get(0).volume = 0.1;
+ audio.get(0).volume = 0.5;
audio.bind("ended", trackEnded);
setTimeout(function(){ $('#time_bar').trigger("showCurrentTime"); }, 100);
@@ -276,6 +276,14 @@ function setupPlayer(tracks) {
return false;
});
+ $('.album .lists input[type="submit"]').live('click', function(event) {
+ var form = $(this).parents('form');
+ $.post(form.attr('action'), form.serialize(), function (data) {
+ $('.lists').replaceWith(data);
+ });
+ return false;
+ });
+
}
$(document).ready(function() {
@@ -296,6 +304,7 @@ $(document).ready(function() {
});
$(document).keypress(function (e) {
+ if (e.altKey || e.ctrlKey || e.metaKey) { return; }
if (e.target.tagName == "INPUT" || e.target.tagName == "TEXTAREA") { return ;}
if (e.which == 32 || (65 <= e.which && e.which <= 65 + 25) || (97 <= e.which && e.which <= 97 + 25)) {
if ( ' ' == String.fromCharCode(e.which) ) { togglePlayPause(); return false; }
@@ -304,18 +313,11 @@ $(document).ready(function() {
}
});
- $('.albums_group .links li').live('click', function(e) {
- var target = $(this);
- var url = target.find('a').attr('href');
- target.parents('.albums_group').load(url);
- });
-
- $('.albums_group .links li a').live('click', function(e) {
+ $('.albums_group .links li, .albums_group .links li a').live('click', function(e) {
+ e.preventDefault();
var target = $(this);
- var url = target.attr('href');
- console.log(["click", target, url]);
+ var url = target.attr('href') || target.find('a').attr('href');
target.parents('.albums_group').load(url);
- e.preventDefault();
});
});
View
33 public/stylesheets/application.css
@@ -1,6 +1,8 @@
+h1, h2, h3,
ul, li, p { margin: 0; padding: 0; }
ul li { list-style-type: none; }
+
.header {position: absolute; top: 0; right: 0;}
.header > div { float:left; margin: .5em; padding: 0;}
@@ -65,7 +67,7 @@ div.album,
width: 500px; left: 200px;
background-color: #bbb;
border: 1px solid #fff;
- -webkit-border-radius: 5px;
+ -webkit-border-radius: 5px;
}
#player .info_box > div { position: absolute; }
#player .img {
@@ -100,9 +102,9 @@ div.album,
.album .tracks .album_name { display:none; }
-#browser > ul {
+#browser > ul {
position: absolute;
- margin: 0; padding: 0;
+ margin: 0; padding: 0;
overflow-y: auto;
border: 2px solid #999;
}
@@ -155,7 +157,7 @@ li.playing {
width: 100%;
background-color: #bbb;
border: 1px solid #fff;
- -webkit-border-radius: 5px;
+ -webkit-border-radius: 5px;
}
.tracks ul li {
position: relative;
@@ -199,7 +201,8 @@ li.playing {
}
.comments li { position: relative; }
-.comments .author {
+.comments .author_and_date,
+.comments p.author {
position: absolute; right: 5px; bottom: -15px;
font-size: 12px;
font-style: italic;
@@ -297,17 +300,17 @@ div.album {
padding: 1em;
margin: 1em 3em 2em;
background-color: #E8E8E8;
- -webkit-border-radius: 1em;
+ -webkit-border-radius: 1em;
-webkit-box-shadow: rgb(0, 0, 0) 0px 2px 5px;
}
-#player {
+#player {
margin-bottom: 0;
-webkit-border-bottom-left-radius: 0;
-webkit-border-bottom-right-radius: 0;
}
-div.album {
+div.album {
margin-top: 0;
-webkit-border-top-left-radius: 0;
-webkit-border-top-right-radius: 0;
@@ -335,7 +338,7 @@ li.album {
.albums_group {
position: relative;
- height: 100px;
+ height: 50px;
}
/* we specified albums_group height because content are positionned in absolute in it */
@@ -344,23 +347,23 @@ li.album {
.albums_group .links,
.albums_group .albums {
position:absolute;
- top: 20px;
+ top: 0;
height: 46px;
}
.albums_group .albums {
- margin: 15px 40px;
+ margin: 0px 40px;
width: 460px;
border: 1px solid #999;
background-color: #DDD;
}
.albums_group .links {
- margin: 15px 20px;
+ margin: 0px 20px;
width: 500px;
/* border: 1px solid red;*/
}
.albums_group .albums li {
float: left;
- width: 42px;
+ width: 42px;
margin: 2px 1px;
padding: 0px 1px;
cursor: pointer;
@@ -423,8 +426,6 @@ li.album {
.albums_group ul:hover li .cover_album span { top: 0.1em; }
.albums_group ul:hover li .cover_album a { top: 1.1em; }
-.preferred_albums .albums_group { height: 80px; }
-.preferred_albums .albums_group ul { top: 20px; }
/* last_thing : last_listenings & last_comments styling */
.last_thing li { position: relative; width: 200px; height: 25px; border: 1px solid #999;}
@@ -456,7 +457,7 @@ li.album {
.last_listenings .more_info {
position: absolute;
top: -10px;
- right: 200px;
+ right: 185px;
padding: 0.5em 20px;
margin: 0 10px;
width: 390px;
View
112 spec/models/list_spec.rb
@@ -0,0 +1,112 @@
+require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+
+# List:
+# name
+# modifications:
+# action
+# author_id
+# album_id
+#
+# User:
+# lists:
+# id
+# name
+# albums_ids
+# accepted_modification_ids
+# rejected_modification_ids
+
+
+describe List do
+
+ def new_user(name)
+ u = User.create(:name => name, :email => "test@test.com")
+ raise u.errors.inspect unless u.valid?
+ u
+ end
+
+ def tricky
+ @tricky ||= new_user("tricky")
+ end
+
+ def pelicano
+ @pelicano ||= new_user("pelicano")
+ end
+
+ it "should be created by a user" do
+ list = List.new(:name => "a list", :author => tricky)
+ list.should be_valid
+ end
+
+ it "should create the user_list" do
+ list = List.create(:name => "a list", :author => tricky)
+ tricky.list_by_id(list.id).should_not be_nil
+ end
+
+ describe "created by tricky" do
+
+ before :each do
+ @list = List.create(:name => 'R&B', :author => tricky)
+ end
+
+ it "should accept new event from user" do
+ @list.add(:album_id => "1", :author => tricky)
+ @tricky = User.find(tricky.id)
+ user_list = tricky.list_by_id(@list.id)
+ user_list.should_not be_nil
+ user_list.album_ids.should == ["1"]
+ @list.modifications.length.should == 1
+ modif = @list.modifications.first
+ modif.author_id.should == tricky.id
+ modif.action.should == "add"
+ modif.album_id.should == "1"
+ user_list.accepted_modification_ids.should == [modif.id]
+ end
+
+ it "should accept event from others" do
+ @list.add(:album_id => "1", :author => tricky)
+ @list.add(:album_id => "2", :author => pelicano)
+ @tricky = User.find(tricky.id)
+ tricky.list_by_id(@list.id).album_ids.should == ["1"]
+ pelicano.list_by_id(@list.id).album_ids.should == ["1", "2"]
+ tricky.list_by_id(@list.id).pending_modifications.length.should == 1
+ pending_modification = tricky.list_by_id(@list.id).pending_modifications.first
+ pending_modification.action.should == "add"
+ pending_modification.author_id.should == pelicano.id
+ pending_modification.album_id.should == "2"
+ pending_modification.accept(:author => tricky)
+ @tricky = User.find(tricky.id)
+ tricky.list_by_id(@list.id).pending_modifications.should be_empty
+ tricky.list_by_id(@list.id).album_ids.should == ["1", "2"]
+ end
+
+ it "should reject event from others" do
+ @list.add(:album_id => "1", :author => tricky)
+ @list.add(:album_id => "2", :author => pelicano)
+ pending_modification = tricky.list_by_id(@list.id).pending_modifications.first
+ pending_modification.reject(:author => tricky)
+ @tricky = User.find(tricky.id)
+ tricky.list_by_id(@list.id).pending_modifications.should be_empty
+ tricky.list_by_id(@list.id).album_ids.should == ["1"]
+ end
+
+ it "should accept removal from others" do
+ @list.add(:album_id => "1", :author => tricky)
+ @list.add(:album_id => "2", :author => tricky)
+ @list.remove(:album_id => "1", :author => pelicano)
+ @tricky = User.find(tricky.id)
+ tricky.list_by_id(@list.id).album_ids.should == ["1", "2"]
+ @pelicano = User.find(pelicano.id)
+ pelicano.list_by_id(@list.id).album_ids.should == ["2"]
+ pending_modification = tricky.list_by_id(@list.id).pending_modifications.first
+ pending_modification.action.should == "remove"
+ pending_modification.author_id.should == pelicano.id
+ pending_modification.album_id.should == "1"
+ pending_modification.accept(:author => tricky)
+ @tricky = User.find(tricky.id)
+ tricky.list_by_id(@list.id).pending_modifications.should be_empty
+ tricky.list_by_id(@list.id).album_ids.should == ["2"]
+ end
+
+ end
+
+end
View
30 spec/spec_helper.rb
@@ -1,4 +1,28 @@
-ENV["RAILS_ENV"] = "test"
-require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
-require 'spec'
+# This file is copied to ~/spec when you run 'ruby script/generate rspec'
+# from the project root directory.
+ENV["RAILS_ENV"] ||= 'test'
+require File.expand_path(File.join(File.dirname(__FILE__),'..','config','environment'))
+require 'spec/autorun'
require 'spec/rails'
+
+# Uncomment the next line to use webrat's matchers
+#require 'webrat/integrations/rspec-rails'
+
+# Requires supporting files with custom matchers and macros, etc,
+# in ./support/ and its subdirectories.
+Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','**','*.rb'))].each {|f| require f}
+
+Spec::Runner.configure do |config|
+ # == Mock Framework
+ #
+ # RSpec uses its own mocking framework by default. If you prefer to
+ # use mocha, flexmock or RR, uncomment the appropriate line:
+ #
+ # config.mock_with :mocha
+ # config.mock_with :flexmock
+ # config.mock_with :rr
+ #
+ # == Notes
+ #
+ # For more information take a look at Spec::Runner::Configuration and Spec::Runner
+end
Please sign in to comment.
Something went wrong with that request. Please try again.