play 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/Gemfile +2 -0
  2. data/Gemfile.lock +87 -0
  3. data/README.md +139 -0
  4. data/Rakefile +185 -0
  5. data/bin/play +49 -0
  6. data/config.ru +10 -0
  7. data/db/migrate/01_create_schema.rb +55 -0
  8. data/lib/play.rb +73 -0
  9. data/lib/play/album.rb +6 -0
  10. data/lib/play/app.rb +118 -0
  11. data/lib/play/app/api.rb +110 -0
  12. data/lib/play/artist.rb +21 -0
  13. data/lib/play/client.rb +67 -0
  14. data/lib/play/core_ext/hash.rb +6 -0
  15. data/lib/play/history.rb +7 -0
  16. data/lib/play/library.rb +58 -0
  17. data/lib/play/office.rb +34 -0
  18. data/lib/play/song.rb +97 -0
  19. data/lib/play/templates/album_songs.mustache +5 -0
  20. data/lib/play/templates/artist_songs.mustache +5 -0
  21. data/lib/play/templates/index.mustache +18 -0
  22. data/lib/play/templates/layout.mustache +23 -0
  23. data/lib/play/templates/now_playing.mustache +5 -0
  24. data/lib/play/templates/play_history.mustache +3 -0
  25. data/lib/play/templates/profile.mustache +24 -0
  26. data/lib/play/templates/search.mustache +3 -0
  27. data/lib/play/templates/show_song.mustache +9 -0
  28. data/lib/play/templates/song.mustache +21 -0
  29. data/lib/play/user.rb +59 -0
  30. data/lib/play/views/album_songs.rb +9 -0
  31. data/lib/play/views/artist_songs.rb +9 -0
  32. data/lib/play/views/index.rb +9 -0
  33. data/lib/play/views/layout.rb +6 -0
  34. data/lib/play/views/now_playing.rb +17 -0
  35. data/lib/play/views/play_history.rb +9 -0
  36. data/lib/play/views/profile.rb +9 -0
  37. data/lib/play/views/search.rb +9 -0
  38. data/lib/play/views/show_song.rb +19 -0
  39. data/lib/play/vote.rb +7 -0
  40. data/play.gemspec +129 -0
  41. data/play.yml.example +22 -0
  42. data/public/css/base.css +129 -0
  43. data/test/helper.rb +33 -0
  44. data/test/spec/mini.rb +24 -0
  45. data/test/test_api.rb +118 -0
  46. data/test/test_app.rb +57 -0
  47. data/test/test_artist.rb +15 -0
  48. data/test/test_client.rb +11 -0
  49. data/test/test_library.rb +19 -0
  50. data/test/test_office.rb +26 -0
  51. data/test/test_play.rb +17 -0
  52. data/test/test_song.rb +78 -0
  53. data/test/test_user.rb +21 -0
  54. metadata +299 -0
@@ -0,0 +1,17 @@
1
+ module Play
2
+ module Views
3
+ class NowPlaying < Layout
4
+ def title
5
+ "now playing"
6
+ end
7
+
8
+ def artist_name
9
+ @song.artist_name
10
+ end
11
+
12
+ def song_title
13
+ @song.title
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,9 @@
1
+ module Play
2
+ module Views
3
+ class PlayHistory < Layout
4
+ def title
5
+ "History"
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Play
2
+ module Views
3
+ class Profile < Layout
4
+ def title
5
+ @user ? @user.name : "Profile"
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Play
2
+ module Views
3
+ class Search < Layout
4
+ def title
5
+ @search
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,19 @@
1
+ module Play
2
+ module Views
3
+ class ShowSong < Layout
4
+ def title
5
+ "#{@song.title} by #{@song.artist.name}"
6
+ end
7
+
8
+ def users
9
+ @song.votes.group(:user_id).collect do |vote|
10
+ vote.user
11
+ end
12
+ end
13
+
14
+ def plays
15
+ @song.votes.count
16
+ end
17
+ end
18
+ end
19
+ end
data/lib/play/vote.rb ADDED
@@ -0,0 +1,7 @@
1
+ module Play
2
+ class Vote < ActiveRecord::Base
3
+ belongs_to :song
4
+ belongs_to :user
5
+ belongs_to :artist
6
+ end
7
+ end
data/play.gemspec ADDED
@@ -0,0 +1,129 @@
1
+ ## This is the rakegem gemspec template. Make sure you read and understand
2
+ ## all of the comments. Some sections require modification, and others can
3
+ ## be deleted if you don't need them. Once you understand the contents of
4
+ ## this file, feel free to delete any comments that begin with two hash marks.
5
+ ## You can find comprehensive Gem::Specification documentation, at
6
+ ## http://docs.rubygems.org/read/chapter/20
7
+ Gem::Specification.new do |s|
8
+ s.specification_version = 2 if s.respond_to? :specification_version=
9
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
10
+ s.rubygems_version = '1.3.5'
11
+
12
+ ## Leave these as is they will be modified for you by the rake gemspec task.
13
+ ## If your rubyforge_project name is different, then edit it and comment out
14
+ ## the sub! line in the Rakefile
15
+ s.name = 'play'
16
+ s.version = '0.0.1'
17
+ s.date = '2011-05-05'
18
+ s.rubyforge_project = 'play'
19
+
20
+ ## Make sure your summary is short. The description may be as long
21
+ ## as you like.
22
+ s.summary = "Your company's dj. ►"
23
+ s.description = "We want to play music at our office. Everyone has their own
24
+ library on their own machines, and everyone except for me plays shitty music.
25
+ Play is designed to make office music more palatable."
26
+
27
+ ## List the primary authors. If there are a bunch of authors, it's probably
28
+ ## better to set the email to an email list or something. If you don't have
29
+ ## a custom homepage, consider using your GitHub URL or the like.
30
+ s.authors = ["Zach Holman"]
31
+ s.email = 'github.com@zachholman.com'
32
+ s.homepage = 'https://github.com/holman/play'
33
+
34
+ ## This gets added to the $LOAD_PATH so that 'lib/NAME.rb' can be required as
35
+ ## require 'NAME.rb' or'/lib/NAME/file.rb' can be as require 'NAME/file.rb'
36
+ s.require_paths = %w[lib]
37
+
38
+ ## If your gem includes any executables, list them here.
39
+ s.executables = ["play"]
40
+ s.default_executable = 'play'
41
+
42
+ ## Specify any RDoc options here. You'll want to add your README and
43
+ ## LICENSE files to the extra_rdoc_files list.
44
+ #s.rdoc_options = ["--charset=UTF-8"]
45
+ #s.extra_rdoc_files = %w[README LICENSE]
46
+
47
+ ## List your runtime dependencies here. Runtime dependencies are those
48
+ ## that are needed for an end user to actually USE your code.
49
+ s.add_dependency('rack', ["~>1.2.2"])
50
+ s.add_dependency('sinatra')
51
+ s.add_dependency('activerecord')
52
+ s.add_dependency('sqlite3')
53
+ s.add_dependency('mustache')
54
+ s.add_dependency('SystemTimer')
55
+ s.add_dependency('ruby-audioinfo')
56
+ s.add_dependency('oa-oauth')
57
+ s.add_dependency('yajl-ruby')
58
+ s.add_dependency('mysql2')
59
+
60
+ ## List your development dependencies here. Development dependencies are
61
+ ## those that are only needed during development
62
+ s.add_development_dependency('running_man')
63
+ s.add_development_dependency('mocha')
64
+
65
+ ## Leave this section as-is. It will be automatically generated from the
66
+ ## contents of your Git repository via the gemspec task. DO NOT REMOVE
67
+ ## THE MANIFEST COMMENTS, they are used as delimiters by the task.
68
+ # = MANIFEST =
69
+ s.files = %w[
70
+ Gemfile
71
+ Gemfile.lock
72
+ README.md
73
+ Rakefile
74
+ bin/play
75
+ config.ru
76
+ db/migrate/01_create_schema.rb
77
+ lib/play.rb
78
+ lib/play/album.rb
79
+ lib/play/app.rb
80
+ lib/play/app/api.rb
81
+ lib/play/artist.rb
82
+ lib/play/client.rb
83
+ lib/play/core_ext/hash.rb
84
+ lib/play/history.rb
85
+ lib/play/library.rb
86
+ lib/play/office.rb
87
+ lib/play/song.rb
88
+ lib/play/templates/album_songs.mustache
89
+ lib/play/templates/artist_songs.mustache
90
+ lib/play/templates/index.mustache
91
+ lib/play/templates/layout.mustache
92
+ lib/play/templates/now_playing.mustache
93
+ lib/play/templates/play_history.mustache
94
+ lib/play/templates/profile.mustache
95
+ lib/play/templates/search.mustache
96
+ lib/play/templates/show_song.mustache
97
+ lib/play/templates/song.mustache
98
+ lib/play/user.rb
99
+ lib/play/views/album_songs.rb
100
+ lib/play/views/artist_songs.rb
101
+ lib/play/views/index.rb
102
+ lib/play/views/layout.rb
103
+ lib/play/views/now_playing.rb
104
+ lib/play/views/play_history.rb
105
+ lib/play/views/profile.rb
106
+ lib/play/views/search.rb
107
+ lib/play/views/show_song.rb
108
+ lib/play/vote.rb
109
+ play.gemspec
110
+ play.yml.example
111
+ public/css/base.css
112
+ test/helper.rb
113
+ test/spec/mini.rb
114
+ test/test_api.rb
115
+ test/test_app.rb
116
+ test/test_artist.rb
117
+ test/test_client.rb
118
+ test/test_library.rb
119
+ test/test_office.rb
120
+ test/test_play.rb
121
+ test/test_song.rb
122
+ test/test_user.rb
123
+ ]
124
+ # = MANIFEST =
125
+
126
+ ## Test files will be grabbed from the file list. Make sure the path glob
127
+ ## matches what you actually use.
128
+ s.test_files = s.files.select { |path| path =~ /^test\/test_.*\.rb/ }
129
+ end
data/play.yml.example ADDED
@@ -0,0 +1,22 @@
1
+ # This file should get moved to:
2
+ # ~/.play.yml
3
+ #
4
+ # Also you should fill it out.
5
+
6
+ path: /path/to/your/music/yo
7
+ gh_key: github_oauth_key
8
+ gh_secret: github_oauth_secret
9
+ office_url: http://example.com/office.macs
10
+
11
+ # Database stuffs that we'll pass on to ActiveRecord. Change if you want to. If
12
+ # you don't want to, you are probably a handsome-looking gentlemen or a
13
+ # gorgeous lady who knows what they want out of life.
14
+ db:
15
+ database: play
16
+ adapter: mysql2
17
+ user: user
18
+ password: password
19
+ reconnect: true
20
+ # db:
21
+ # database: db/play.sqlite3
22
+ # adapter: sqlite3
@@ -0,0 +1,129 @@
1
+ /*
2
+
3
+ dark: 485460
4
+ 3D72AA
5
+ 5E7894
6
+ 438FDF
7
+ D0E4FA
8
+ */
9
+
10
+ html{
11
+ font-family: Helvetica;
12
+ }
13
+ body{
14
+ margin: 0;
15
+ padding: 0;
16
+ color: #5E7894;
17
+ }
18
+ h1{
19
+ margin: 1em 10px 0 10px;
20
+ padding: 0;
21
+ letter-spacing: -3px;
22
+ color: #000;
23
+ }
24
+ a{
25
+ color: #5E7894;
26
+ text-decoration: none;
27
+ }
28
+ a:hover{
29
+ color: #000;
30
+ }
31
+
32
+ .navigation{
33
+ text-align: right;
34
+ padding: 2px 10px;
35
+ font-weight: bold;
36
+ letter-spacing: -1px;
37
+ font-size: 1.4em;
38
+ }
39
+ .navigation a{
40
+ color: #485460;
41
+ padding-left: 10px;
42
+ text-decoration: none;
43
+ }
44
+ .navigation form{
45
+ display: inline;
46
+ }
47
+ .navigation input{
48
+ vertical-align: top;
49
+ width: 250px;
50
+ }
51
+ .content{
52
+ padding: 10px;
53
+ background-color: #D0E4FA;
54
+ }
55
+ .gravatar{
56
+ -webkit-border-radius: 5px;
57
+ }
58
+
59
+ /*
60
+ * SONGS
61
+ */
62
+ .songs{
63
+
64
+ }
65
+ .song{
66
+ letter-spacing: -1px;
67
+ background-color: #D0E4FA;
68
+ border-top: 2px solid #fff;
69
+ padding: .5em 10px;
70
+ font-size: 1.25em;
71
+ font-weight: bold;
72
+ }
73
+ .song a:hover{
74
+ color: #000 !important;
75
+ }
76
+ .song .artist{
77
+ font-size: 3em;
78
+ letter-spacing: -5px;
79
+ }
80
+ .song .artist a{
81
+ color: #485460;
82
+ }
83
+ .song .title{
84
+ padding-left: 10px;
85
+ font-size: 2.2em;
86
+ letter-spacing: -4px;
87
+ }
88
+ .song .album{
89
+ margin-left: 10px;
90
+ font-size: 1.1em;
91
+ letter-spacing: -2px;
92
+ }
93
+ .song .album a{
94
+ color: #438FDF;
95
+ }
96
+ .song .controls{
97
+ float: right;
98
+ font-size: .75em;
99
+ margin: -.5em -5px;
100
+ text-transform: uppercase;
101
+ }
102
+ .votes{
103
+ background-color: #485460;
104
+ padding: 5px 5px 0px 5px;
105
+ }
106
+ .votes img{
107
+ border: 1px solid #5E7894;
108
+ }
109
+ .votes img:hover{
110
+ border: 1px solid #D0E4FA;
111
+ }
112
+
113
+ /*
114
+ * PROFILE
115
+ */
116
+ .profile_box{
117
+ margin-right: 10px;
118
+ float: left;
119
+ font-size: 1.1em;
120
+ }
121
+ .bio{
122
+ padding: 15px 0;
123
+ }
124
+ .favorite_artists{
125
+ margin: 0 15px;
126
+ }
127
+ .favorite_artists h2{
128
+ color: #485460;
129
+ }
data/test/helper.rb ADDED
@@ -0,0 +1,33 @@
1
+ require 'test/unit'
2
+
3
+ begin
4
+ require 'rubygems'
5
+ require 'redgreen'
6
+ require 'leftright'
7
+ rescue LoadError
8
+ end
9
+
10
+ require 'rack/test'
11
+ require 'mocha'
12
+ require 'spec/mini'
13
+ require 'running_man'
14
+ require 'running_man/active_record_block'
15
+
16
+ ENV['RACK_ENV'] = 'test'
17
+
18
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
19
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
20
+
21
+ require 'play'
22
+ include Play
23
+
24
+ ActiveRecord::Base.establish_connection(:adapter => 'sqlite3',
25
+ :database => ":memory:")
26
+ ActiveRecord::Migration.verbose = false
27
+ ActiveRecord::Migrator.migrate("db/migrate")
28
+
29
+ RunningMan.setup_on ActiveSupport::TestCase, :ActiveRecordBlock
30
+
31
+ def parse_json(json)
32
+ Yajl.load(json, :symbolize_keys => true)
33
+ end
data/test/spec/mini.rb ADDED
@@ -0,0 +1,24 @@
1
+ ##
2
+ # test/spec/mini 5
3
+ # http://gist.github.com/307649
4
+ # chris@ozmm.org
5
+ #
6
+ def context(*args, &block)
7
+ return super unless (name = args.first) && block
8
+ require 'test/unit'
9
+ klass = Class.new(defined?(ActiveSupport::TestCase) ? ActiveSupport::TestCase : Test::Unit::TestCase) do
10
+ def self.test(name, &block)
11
+ define_method("test_#{name.to_s.gsub(/\W/,'_')}", &block) if block
12
+ end
13
+ def self.xtest(*args) end
14
+ def self.context(*args, &block) instance_eval(&block) end
15
+ def self.setup(&block)
16
+ define_method(:setup) { self.class.setups.each { |s| instance_eval(&s) } }
17
+ setups << block
18
+ end
19
+ def self.setups; @setups ||= [] end
20
+ def self.teardown(&block) define_method(:teardown, &block) end
21
+ end
22
+ (class << klass; self end).send(:define_method, :name) { name.gsub(/\W/,'_') }
23
+ klass.class_eval &block
24
+ end
data/test/test_api.rb ADDED
@@ -0,0 +1,118 @@
1
+ require 'helper'
2
+ include Rack::Test::Methods
3
+
4
+ def app
5
+ Play::App
6
+ end
7
+
8
+ context "Api" do
9
+ fixtures do
10
+ @artist = Play::Artist.create(:name => "Justice")
11
+ @album = Play::Album.create(:name => "Cross", :artist => @artist)
12
+ @song = Play::Song.create(:title => "Stress",
13
+ :artist => @artist,
14
+ :album => @album)
15
+ @user = Play::User.create(:login => 'holman', :alias => 'zach')
16
+ end
17
+
18
+ test "/api/now_playing" do
19
+ Play.expects(:now_playing).returns(@song)
20
+ get "/api/now_playing"
21
+ now_playing = parse_json(last_response.body.strip)
22
+ assert_equal @artist.name, now_playing[:artist_name]
23
+ assert_equal @song.title, now_playing[:song_title]
24
+ assert_equal @album.name, now_playing[:album_name]
25
+ end
26
+
27
+ test "/api requires user_login" do
28
+ post "/api/add_song", {}
29
+ user = parse_json(last_response.body.strip)
30
+ assert user[:error].include?("must supply a valid `user_login`")
31
+ end
32
+
33
+ test "user login check also works for aliases" do
34
+ post "/api/add_song", {:user_login => 'zach'}
35
+ user = parse_json(last_response.body.strip)
36
+ assert !user[:error].include?("must supply a valid `user_login`")
37
+ end
38
+
39
+ test "/api/add_song" do
40
+ post "/api/add_song", { :song_title => @song.title,
41
+ :artist_name => @artist.name,
42
+ :user_login => @user.login }
43
+ song = parse_json(last_response.body.strip)
44
+ assert_equal @song.title, song[:song_title]
45
+ end
46
+
47
+ test "/api/add_song without a found artist" do
48
+ post "/api/add_song", { :song_title => 'Stress',
49
+ :artist_name => "Ace of Base",
50
+ :user_login => @user.login }
51
+ resp = parse_json(last_response.body.strip)
52
+ assert resp[:error].include?("find that artist")
53
+ end
54
+
55
+ test "/api/add_song without a found song" do
56
+ post "/api/add_song", { :song_title => "I Saw the Sign",
57
+ :artist_name => @artist.name,
58
+ :user_login => @user.login }
59
+ resp = parse_json(last_response.body.strip)
60
+ assert resp[:error].include?("find that song")
61
+ end
62
+
63
+ test "/api/add_artist" do
64
+ post "/api/add_artist", { :artist_name => @artist.name,
65
+ :user_login => @user.login }
66
+ song = parse_json(last_response.body.strip)
67
+ assert_equal @artist.name, song[:artist_name]
68
+ assert_equal [@song.title], song[:song_titles]
69
+ end
70
+
71
+ test "/api/remove" do
72
+ post "/api/remove"
73
+ resp = parse_json(last_response.body.strip)
74
+ assert resp[:error].include?("hasn't been implemented")
75
+ end
76
+
77
+ test "/api/search artist" do
78
+ get "/api/search", { :q => @artist.name,
79
+ :facet => 'artist' }
80
+ resp = parse_json(last_response.body.strip)
81
+ assert resp[:song_titles].include?(@song.title)
82
+ end
83
+
84
+ test "/api/search song" do
85
+ get "/api/search", { :q => @song.title,
86
+ :facet => 'song' }
87
+ resp = parse_json(last_response.body.strip)
88
+ assert resp[:song_titles].include?(@song.title)
89
+ end
90
+
91
+ test "/api/user/add_alias" do
92
+ post "/api/user/add_alias", { :login => @user.login, :alias => 'zach' }
93
+ resp = parse_json(last_response.body.strip)
94
+ assert 'true', resp[:success]
95
+ assert_equal 'zach', User.first.alias
96
+ end
97
+
98
+ test "/api/import" do
99
+ Library.stubs(:import_songs).returns('true')
100
+ post "/api/import"
101
+ resp = parse_json(last_response.body.strip)
102
+ assert_equal 'true', resp[:success]
103
+ end
104
+
105
+ test "/api/volume" do
106
+ Play::Client.expects(:volume).with(3).returns(true)
107
+ post "/api/volume", {:level => '3'}
108
+ resp = parse_json(last_response.body.strip)
109
+ assert_equal 'true', resp[:success]
110
+ end
111
+
112
+ test "/api/pause" do
113
+ Play::Client.expects(:pause).returns(true)
114
+ post "/api/pause"
115
+ resp = parse_json(last_response.body.strip)
116
+ assert_equal 'true', resp[:success]
117
+ end
118
+ end