Bringing on
1
Gemfile
@ -6,6 +6,7 @@ gem 'rails', '3.0.8'
|
||||
# gem 'rails', :git => 'git://github.com/rails/rails.git'
|
||||
|
||||
gem 'sqlite3'
|
||||
gem 'pg'
|
||||
|
||||
# Use unicorn as the web server
|
||||
# gem 'unicorn'
|
||||
|
@ -39,6 +39,7 @@ GEM
|
||||
mime-types (~> 1.16)
|
||||
treetop (~> 1.4.8)
|
||||
mime-types (1.16)
|
||||
pg (0.11.0)
|
||||
polyglot (0.3.1)
|
||||
rack (1.2.3)
|
||||
rack-mount (0.6.14)
|
||||
@ -69,5 +70,6 @@ PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
pg
|
||||
rails (= 3.0.8)
|
||||
sqlite3
|
||||
|
2
app/models/album.rb
Normal file
@ -0,0 +1,2 @@
|
||||
class Album < ActiveRecord::Base
|
||||
end
|
2
app/models/artist.rb
Normal file
@ -0,0 +1,2 @@
|
||||
class Artist < ActiveRecord::Base
|
||||
end
|
21
app/models/music_brainz_artist.rb
Normal file
@ -0,0 +1,21 @@
|
||||
class MusicBrainzArtist < ActiveRecord::Base
|
||||
|
||||
establish_connection :musicbrainz
|
||||
set_table_name 'musicbrainz.bh_artist'
|
||||
|
||||
has_many :albums, :conditions => "release_type = 1", :order => 'year ASC, id ASC'
|
||||
|
||||
def self.getByName(name)
|
||||
Artist.first(:conditions => ['name = ? AND id=credit_id', name], :order => 'rating DESC')
|
||||
end
|
||||
|
||||
def self.getLastFmAutocomplete(query)
|
||||
return nil if query.nil? or query.strip.empty?
|
||||
|
||||
json = ActiveSupport::JSON.decode(open(
|
||||
'http://www.last.fm/search/autocomplete' <<
|
||||
'?q=' << URI.escape(query)
|
||||
).read)
|
||||
return json.empty? ? nil : json
|
||||
end
|
||||
end
|
2
app/models/track.rb
Normal file
@ -0,0 +1,2 @@
|
||||
class Track < ActiveRecord::Base
|
||||
end
|
@ -20,3 +20,11 @@ production:
|
||||
database: db/production.sqlite3
|
||||
pool: 5
|
||||
timeout: 5000
|
||||
|
||||
|
||||
musicbrainz:
|
||||
host: 192.168.0.128
|
||||
adapter: postgresql
|
||||
database: beathaven
|
||||
username: postgres
|
||||
password: password
|
BIN
db/development.sqlite3
Normal file
14
db/migrate/20110613125954_create_artists.rb
Normal file
@ -0,0 +1,14 @@
|
||||
class CreateArtists < ActiveRecord::Migration
|
||||
def self.up
|
||||
create_table :artists do |t|
|
||||
t.string :name
|
||||
t.text :desc
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
|
||||
def self.down
|
||||
drop_table :artists
|
||||
end
|
||||
end
|
17
db/migrate/20110613130105_create_albums.rb
Normal file
@ -0,0 +1,17 @@
|
||||
class CreateAlbums < ActiveRecord::Migration
|
||||
def self.up
|
||||
create_table :albums do |t|
|
||||
t.string :name
|
||||
t.integer :artist_id
|
||||
t.integer :year
|
||||
t.integer :status
|
||||
t.string :pic_url
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
|
||||
def self.down
|
||||
drop_table :albums
|
||||
end
|
||||
end
|
18
db/migrate/20110613135648_create_tracks.rb
Normal file
@ -0,0 +1,18 @@
|
||||
class CreateTracks < ActiveRecord::Migration
|
||||
def self.up
|
||||
create_table :tracks do |t|
|
||||
t.string :name
|
||||
t.integer :album_id
|
||||
t.integer :position
|
||||
t.integer :bonus
|
||||
t.integer :live
|
||||
t.integer :acoustic
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
|
||||
def self.down
|
||||
drop_table :tracks
|
||||
end
|
||||
end
|
43
db/schema.rb
Normal file
@ -0,0 +1,43 @@
|
||||
# This file is auto-generated from the current state of the database. Instead
|
||||
# of editing this file, please use the migrations feature of Active Record to
|
||||
# incrementally modify your database, and then regenerate this schema definition.
|
||||
#
|
||||
# Note that this schema.rb definition is the authoritative source for your
|
||||
# database schema. If you need to create the application database on another
|
||||
# system, you should be using db:schema:load, not running all the migrations
|
||||
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
|
||||
# you'll amass, the slower it'll run and the greater likelihood for issues).
|
||||
#
|
||||
# It's strongly recommended to check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(:version => 20110613135648) do
|
||||
|
||||
create_table "albums", :force => true do |t|
|
||||
t.string "name"
|
||||
t.integer "artist_id"
|
||||
t.integer "year"
|
||||
t.integer "status"
|
||||
t.string "pic_url"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
end
|
||||
|
||||
create_table "artists", :force => true do |t|
|
||||
t.string "name"
|
||||
t.text "desc"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
end
|
||||
|
||||
create_table "tracks", :force => true do |t|
|
||||
t.string "name"
|
||||
t.integer "album_id"
|
||||
t.integer "position"
|
||||
t.integer "bonus"
|
||||
t.integer "live"
|
||||
t.integer "acoustic"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
end
|
||||
|
||||
end
|
6
lib/tasks/db_import.rake
Normal file
@ -0,0 +1,6 @@
|
||||
namespace :db do
|
||||
desc 'Imports data from MusicBrainz database'
|
||||
task :import => :environment do
|
||||
|
||||
end
|
||||
end
|
47
nginx/nginx.conf
Normal file
@ -0,0 +1,47 @@
|
||||
worker_processes 1;
|
||||
error_log logs/error.log debug;
|
||||
|
||||
events {
|
||||
worker_connections 256;
|
||||
}
|
||||
|
||||
http {
|
||||
default_type application/octet-stream;
|
||||
sendfile on;
|
||||
#tcp_nopush on;
|
||||
keepalive_timeout 65;
|
||||
tcp_nodelay on;
|
||||
|
||||
gzip on;
|
||||
gzip_min_length 1100;
|
||||
gzip_buffers 4 8k;
|
||||
gzip_types text/plain;
|
||||
|
||||
upstream mongrel {
|
||||
server 127.0.0.1:3000;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name bh.vim.me localhost susanna brooklyn;
|
||||
#root /Users/chez/Sites;
|
||||
#index index.html index.htm;
|
||||
|
||||
try_files $uri @mongrel;
|
||||
|
||||
location @mongrel {
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_redirect off;
|
||||
proxy_pass http://mongrel;
|
||||
}
|
||||
|
||||
include proxy.conf;
|
||||
|
||||
#error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
root html;
|
||||
}
|
||||
}
|
||||
}
|
43
nginx/proxy.conf
Executable file
@ -0,0 +1,43 @@
|
||||
# Proxy download
|
||||
location ~* ^/proxy-stream/(.*?)/(.*?)/(.*?)/(.*?)/(.*) {
|
||||
# Do not allow people to mess with this location directly
|
||||
# Only internal redirects are allowed
|
||||
internal;
|
||||
|
||||
# Location-specific logging
|
||||
#access_log logs/proxy_stream.access.log debug;
|
||||
#error_log logs/proxy_stream.error.log debug;
|
||||
|
||||
# Extract download url from the request
|
||||
set $token $1;
|
||||
set $remixsid $2;
|
||||
set $remixchk $3;
|
||||
set $download_host $4;
|
||||
set $download_uri $5;
|
||||
|
||||
# Compose download url
|
||||
set $download_url http://$download_host/$download_uri;
|
||||
|
||||
# Compose cookie string
|
||||
set $cookie "remixsid=$remixsid;remixchk=$remixchk";
|
||||
|
||||
# Set download request headers
|
||||
proxy_set_header Host $download_host;
|
||||
proxy_set_header Cookie $cookie;
|
||||
proxy_set_header Referer "http://vkontakte.ru/audio?album_id=0";
|
||||
|
||||
# The next two lines could be used if your storage
|
||||
# backend does not support Content-Disposition
|
||||
# headers used to specify file name browsers use
|
||||
# when save content to the disk
|
||||
proxy_ignore_headers Cache-Control Expires;
|
||||
|
||||
|
||||
# Do not touch local disks when proxying
|
||||
# content to clients
|
||||
proxy_max_temp_file_size 0;
|
||||
|
||||
# Download the file and send it to client
|
||||
resolver 192.168.0.1;
|
||||
proxy_pass $download_url;
|
||||
}
|
62
public/BetaHaven.html
Normal file
@ -0,0 +1,62 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>BetaHaven</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel="stylesheet" type="text/css" media="screen" href="css/layout.css" />
|
||||
<link rel="stylesheet" type="text/css" media="screen" href="css/misc.css" />
|
||||
<link rel="stylesheet" type="text/css" media="screen" href="css/player.css" />
|
||||
<link rel="stylesheet" type="text/css" media="screen" href="css/albums.css" />
|
||||
<script type="text/javascript" charset="utf-8" src="js/jquery.min.js"></script>
|
||||
<script type="text/javascript" charset="utf-8" src="js/layout.js"></script>
|
||||
<script type="text/javascript" charset="utf-8" src="js/ajax.js"></script>
|
||||
<script type="text/javascript" charset="utf-8" src="js/pages.js"></script>
|
||||
<script type="text/javascript" charset="utf-8" src="js/audio.js"></script>
|
||||
<script type="text/javascript" charset="utf-8" src="js/player.js"></script>
|
||||
<script type="text/javascript" charset="windows-1251" src="http://vkontakte.ru/js/api/openapi.js"></script>
|
||||
<script type="text/javascript" charset="utf-8" src="js/vkontakte.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- START PLAYER -->
|
||||
<div id="player-container">
|
||||
<div id="player">
|
||||
<audio id="a"></audio>
|
||||
<div class="now-playing">Jet — Black Hearts</div>
|
||||
<div class="progress">
|
||||
<div class="loaded">
|
||||
<div class="played"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="controls">
|
||||
<div class="prev"></div>
|
||||
<div class="play"></div>
|
||||
<div class="next"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="playlist">
|
||||
<ul class="playlist-tracks"></ul>
|
||||
</div>
|
||||
</div>
|
||||
<!-- END PLAYER -->
|
||||
|
||||
<!-- START HEADER -->
|
||||
<div id="header-container">
|
||||
<ul id="navigation">
|
||||
<li class="logo">BeatHaven</li>
|
||||
<li>News</li>
|
||||
<li>Settings</li>
|
||||
<li>Logout</li>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- END HEADER -->
|
||||
|
||||
<!-- START DATA -->
|
||||
<div id="data-container">
|
||||
<a href="/Jet.json" class="data artist">Jet</a>
|
||||
</div>
|
||||
<!-- END DATA -->
|
||||
|
||||
<div id="vk_api_transport"></div>
|
||||
</body>
|
||||
</html>
|
1
public/demo
Symbolic link
@ -0,0 +1 @@
|
||||
/Users/chez/Sites/Progress/
|
BIN
public/images/dummy.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
public/images/getborn.jpg
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
public/images/icns/next.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
public/images/icns/pause.png
Normal file
After Width: | Height: | Size: 1003 B |
BIN
public/images/icns/play.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
public/images/icns/prev.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
public/images/jet.jpg
Normal file
After Width: | Height: | Size: 81 KiB |
BIN
public/images/shakarock.jpg
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
public/images/shineon.jpg
Normal file
After Width: | Height: | Size: 19 KiB |
13
public/javascripts/ajax.js
Normal file
@ -0,0 +1,13 @@
|
||||
$(function(){
|
||||
$('a.data').live('click', function(){
|
||||
var button = this;
|
||||
$.get(this.href, function(data){
|
||||
data = eval('('+ data +')');
|
||||
if ($(button).hasClass('artist')) {
|
||||
Pages.renderArtist(data);
|
||||
}
|
||||
})
|
||||
return false;
|
||||
});
|
||||
$('a.data').trigger('click');
|
||||
})
|
51
public/javascripts/audio.js
Normal file
@ -0,0 +1,51 @@
|
||||
var Audio = {
|
||||
|
||||
audio: null,
|
||||
tid: null,
|
||||
|
||||
init: function() {
|
||||
this.audio = document.getElementById('a');
|
||||
},
|
||||
|
||||
play: function() {
|
||||
this.audio.play();
|
||||
},
|
||||
|
||||
pause: function() {
|
||||
this.audio.pause();
|
||||
},
|
||||
|
||||
setTrack: function(url) {
|
||||
this.audio.setAttribute('src', url);
|
||||
},
|
||||
|
||||
getLoadedPercent: function() {
|
||||
try {
|
||||
return Audio.audio.buffered.end(0) / Audio.audio.duration;
|
||||
} catch(e) {}
|
||||
return 0;
|
||||
},
|
||||
|
||||
getPlayedPercent: function() {
|
||||
try {
|
||||
return Audio.audio.currentTime / Audio.audio.duration;
|
||||
} catch(e) {}
|
||||
return 0;
|
||||
},
|
||||
|
||||
setPlayedPercent: function(val) {
|
||||
if (typeof(this.audio.duration) != undefined) {
|
||||
this.audio.currentTime = Math.round(val * this.audio.duration / 100);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
startListener: function() {
|
||||
Audio.tid = window.setTimeout(Audio.startListener, 100);
|
||||
Player.updateUI(
|
||||
Audio.getLoadedPercent(),
|
||||
Audio.getPlayedPercent()
|
||||
);
|
||||
}
|
||||
}
|
18
public/javascripts/jquery.min.js
vendored
Normal file
19
public/javascripts/layout.js
Normal file
@ -0,0 +1,19 @@
|
||||
$(function(){
|
||||
beathaven.init();
|
||||
$(window).resize(beathaven.adjustSizes)
|
||||
})
|
||||
var beathaven = {
|
||||
|
||||
init: function () {
|
||||
this.drawInterface();
|
||||
this.adjustSizes();
|
||||
},
|
||||
drawInterface: function() {
|
||||
},
|
||||
adjustSizes: function() {
|
||||
$('#data-container').height($(window).height() - $('#header-container').height());
|
||||
$('#player-container').height($(window).height());
|
||||
$('#playlist').height($(window).height() - $('#player').height());
|
||||
|
||||
}
|
||||
}
|
79
public/javascripts/pages.js
Normal file
@ -0,0 +1,79 @@
|
||||
var Pages = {
|
||||
|
||||
renderArtist: function(data){
|
||||
var artist_info = $('\
|
||||
<div class="artist-info">\
|
||||
<div class="pic">\
|
||||
<img src="'+ data.artist.pic +'" alt="'+ data.artist.name +'" width="250" />\
|
||||
</div>\
|
||||
<h1 class="name">'+ data.artist.name +'</h1>\
|
||||
<div class="info">\
|
||||
'+ data.artist.desc +'\
|
||||
</div>\
|
||||
</div>\
|
||||
');
|
||||
|
||||
var albums_info = $('<div class="albums"></div>');
|
||||
$.each(data.albums, function(i, album){
|
||||
var album_info = $('\
|
||||
<div class="album">\
|
||||
<h2 class="name">'+ album.name +' ('+ album.year +')</h2>\
|
||||
<div class="pic">\
|
||||
<img src="'+ album.pic +'" alt="'+ album.name +' by '+ data.artist.name +'" width="250" />\
|
||||
<div class="add-album">Add to playlist</div>\
|
||||
</div>\
|
||||
<div class="tracklist">\
|
||||
<ul>\
|
||||
</ul>\
|
||||
</div>\
|
||||
</div>\
|
||||
');
|
||||
|
||||
$.each(album.tracks.album, function(i, track){
|
||||
var track_info = $('\
|
||||
<li>\
|
||||
<span class="index">'+ (i+1) +'</span>\
|
||||
<div class="trackname">'+ track.name +'</div>\
|
||||
<div class="length">'+ track.duration +'</div>\
|
||||
</li>\
|
||||
');
|
||||
|
||||
$(album_info).find('.tracklist ul').append(track_info);
|
||||
});
|
||||
|
||||
$(albums_info).append(album_info);
|
||||
})
|
||||
|
||||
$('#data-container').html('').append(artist_info).append(albums_info);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
<div class="albums">
|
||||
<div class="album">
|
||||
<h2 class="name">Get Born</h2>
|
||||
<div class="pic">
|
||||
<img src="pics/getborn.jpg" alt="Get Born by Jet" width="250" />
|
||||
<div class="add-album">Add to playlist</div>
|
||||
</div>
|
||||
<div class="tracklist">
|
||||
<ul>
|
||||
<li>
|
||||
<div class="trackname">Last Chance</div>
|
||||
<div class="length">1:52</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="trackname">Are You Gonna Be My Girl</div>
|
||||
<div class="length">3:34</div>
|
||||
</li>
|
||||
<li>
|
||||
<div class="trackname">Rollover DJ</div>
|
||||
<div class="length">3:17</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
*/
|
59
public/javascripts/player.js
Normal file
@ -0,0 +1,59 @@
|
||||
var Player = {
|
||||
|
||||
bar_width: 290,
|
||||
|
||||
getTrackUrl: function(data) {
|
||||
|
||||
},
|
||||
|
||||
addTrack: function(artist, track, length) {
|
||||
$('.playlist-tracks').append('\
|
||||
<li id="i'+ Math.round(Math.random() * 999999) +'">\
|
||||
<div class="item">\
|
||||
<span class="title">'+ artist +' — '+ track +'</span>\
|
||||
<span class="duration">'+ length +'</span>\
|
||||
</div>\
|
||||
</li>\
|
||||
');
|
||||
},
|
||||
|
||||
setTrack: function(obj) {
|
||||
var id = $(obj).attr('id');
|
||||
var query = $(obj).find('.title').html();
|
||||
var length = $(obj).find('.duration').html();
|
||||
|
||||
$('#player .now-playing').html(query);
|
||||
$('.playlist-tracks li').removeClass('now');
|
||||
$('#'+ id).addClass('now');
|
||||
|
||||
loadTracksData(query, this.playSource);
|
||||
},
|
||||
|
||||
playSource: function(url) {
|
||||
Audio.setTrack(url);
|
||||
Audio.play();
|
||||
Audio.startListener();
|
||||
},
|
||||
|
||||
updateUI: function(buffered, played) {
|
||||
$('#player .loaded').width(Math.round(buffered * this.bar_width));
|
||||
$('#player .played').width(Math.round(played * this.bar_width));
|
||||
}
|
||||
}
|
||||
|
||||
$('.add-album').live('click', function() {
|
||||
var artist = $(this).parent().parent().parent().parent().find('.artist-info .name').html();
|
||||
$(this).parent().parent().find('.tracklist li').each(function(i, item){
|
||||
var track_name = $(item).find('.trackname').html();
|
||||
var length = $(item).find('.length').html();
|
||||
Player.addTrack(artist, track_name, length);
|
||||
});
|
||||
})
|
||||
|
||||
$('.playlist-tracks li').live('dblclick', function(){
|
||||
Player.setTrack(this);
|
||||
})
|
||||
|
||||
$(function(){
|
||||
Audio.init();
|
||||
})
|
12
public/javascripts/vkontakte.js
Normal file
@ -0,0 +1,12 @@
|
||||
$(function(){
|
||||
VK.init({
|
||||
apiId: 2335068,
|
||||
nameTransportPath: "/demo/xd_receiver.html"
|
||||
});
|
||||
})
|
||||
|
||||
function loadTracksData(query, callback) {
|
||||
VK.Api.call('audio.search', {q:query}, function(r){
|
||||
callback(r.response[1].url);
|
||||
})
|
||||
}
|
236
public/jet.json
Normal file
@ -0,0 +1,236 @@
|
||||
{
|
||||
'artist': {
|
||||
'name': 'Jet',
|
||||
'desc': 'Jet is an Australian rock band formed in 2001 in Melbourne, Australia, consisting of lead guitarist Cameron Muncey, bassist Mark Wilson, and brothers Nic and Chris Cester on vocals/rhythm guitar and drums respectively. The group has sold 6.5 million records worldwide, with their debut album Get Born, released in 2003, accounting for about 3.5 million of that figure. The band\'s most recent album, Shaka Rock, was released on 19 August 2009.',
|
||||
'pic': 'pics/jet.jpg'
|
||||
},
|
||||
'albums': [
|
||||
{
|
||||
'name': 'Get Born',
|
||||
'year': 2003,
|
||||
'pic': '/images/getborn.jpg',
|
||||
'tracks': {
|
||||
'album': [
|
||||
{
|
||||
'name': 'Last Chance',
|
||||
'duration': '1:52',
|
||||
},
|
||||
{
|
||||
'name': 'Are You Gonna Be My Girl',
|
||||
'duration': '3:34',
|
||||
},
|
||||
{
|
||||
'name': 'Rollover DJ',
|
||||
'duration': '3:17',
|
||||
},
|
||||
{
|
||||
'name': 'Look What You\'ve Done',
|
||||
'duration': '3:51',
|
||||
},
|
||||
{
|
||||
'name': 'Get What You Need',
|
||||
'duration': '4:08',
|
||||
},
|
||||
{
|
||||
'name': 'Move On',
|
||||
'duration': '4:21',
|
||||
},
|
||||
{
|
||||
'name': 'Radio Song',
|
||||
'duration': '4:32',
|
||||
},
|
||||
{
|
||||
'name': 'Get Me Outta Here',
|
||||
'duration': '2:56',
|
||||
},
|
||||
{
|
||||
'name': 'Cold Hard Bitch',
|
||||
'duration': '4:03',
|
||||
},
|
||||
{
|
||||
'name': 'Come Around Again',
|
||||
'duration': '4:30',
|
||||
},
|
||||
{
|
||||
'name': 'Take It or Leave It',
|
||||
'duration': '2:23',
|
||||
},
|
||||
{
|
||||
'name': 'Lazy Gun',
|
||||
'duration': '4:42',
|
||||
},
|
||||
{
|
||||
'name': 'Timothy',
|
||||
'duration': '4:30',
|
||||
},
|
||||
{
|
||||
'name': 'Sgt. Major',
|
||||
'duration': '4:05',
|
||||
},
|
||||
{
|
||||
'name': 'Are You Gonna Be My Girl (Acoustic)',
|
||||
'duration': '3:50',
|
||||
},
|
||||
{
|
||||
'name': 'Bruises (Demo)',
|
||||
'duration': '2:37',
|
||||
},
|
||||
{
|
||||
'name': 'Hey Kids (Non-Album Track)',
|
||||
'duration': '3:00',
|
||||
},
|
||||
{
|
||||
'name': 'Move On (Live)',
|
||||
'duration': '4:05',
|
||||
},
|
||||
{
|
||||
'name': 'Cold Hard Bitch (Live)',
|
||||
'duration': '5:01',
|
||||
},
|
||||
{
|
||||
'name': 'You Don\'t Look The Same (Demo)',
|
||||
'duration': '4:40',
|
||||
},
|
||||
{
|
||||
'name': 'Look What You\'ve Done (Live)',
|
||||
'duration': '4:07',
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
'name': 'Shine On',
|
||||
'year': 2006,
|
||||
'pic': '/images/shineon.jpg',
|
||||
'tracks': {
|
||||
'album': [
|
||||
{
|
||||
'name': 'Espirit d\'Escalier',
|
||||
'duration': '0:23',
|
||||
},
|
||||
{
|
||||
'name': 'Holiday',
|
||||
'duration': '3:26',
|
||||
},
|
||||
{
|
||||
'name': 'Put Your Money Where Your Mouth Is',
|
||||
'duration': '2:33',
|
||||
},
|
||||
{
|
||||
'name': 'Bring It on Back',
|
||||
'duration': '4:09',
|
||||
},
|
||||
{
|
||||
'name': 'That\'s All Lies',
|
||||
'duration': '2:44',
|
||||
},
|
||||
{
|
||||
'name': 'Hey Kids',
|
||||
'duration': '3:13',
|
||||
},
|
||||
{
|
||||
'name': 'Kings Horses',
|
||||
'duration': '3:20',
|
||||
},
|
||||
{
|
||||
'name': 'Shine On',
|
||||
'duration': '4:37',
|
||||
},
|
||||
{
|
||||
'name': 'Come On Come On',
|
||||
'duration': '4:24',
|
||||
},
|
||||
{
|
||||
'name': 'Stand Up',
|
||||
'duration': '4:33',
|
||||
},
|
||||
{
|
||||
'name': 'Rip It Up',
|
||||
'duration': '3:20',
|
||||
},
|
||||
{
|
||||
'name': 'Skin and Bones',
|
||||
'duration': '3:17',
|
||||
},
|
||||
{
|
||||
'name': 'Shiny Magazine',
|
||||
'duration': '3:28',
|
||||
},
|
||||
{
|
||||
'name': 'Eleanor',
|
||||
'duration': '3:34',
|
||||
},
|
||||
{
|
||||
'name': 'All You Have to Do',
|
||||
'duration': '4:39',
|
||||
},
|
||||
{
|
||||
'name': 'Snap Your Fingers (Barbados Demo)',
|
||||
'duration': '1:29',
|
||||
},
|
||||
{
|
||||
'name': 'This Night is Yours',
|
||||
'duration': '1:57',
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
'name': 'Shaka Rock',
|
||||
'year': 2009,
|
||||
'pic': '/images/shakarock.jpg',
|
||||
'tracks': {
|
||||
'album': [
|
||||
{
|
||||
'name': 'K.I.A. (Killed In Action)',
|
||||
'duration': '3:29',
|
||||
},
|
||||
{
|
||||
'name': 'Beat On Repeat',
|
||||
'duration': '2:30',
|
||||
},
|
||||
{
|
||||
'name': 'She\'s A Genius',
|
||||
'duration': '2:59',
|
||||
},
|
||||
{
|
||||
'name': 'Black Hearts (On Fire)',
|
||||
'duration': '3:14',
|
||||
},
|
||||
{
|
||||
'name': 'Seventeen',
|
||||
'duration': '3:41',
|
||||
},
|
||||
{
|
||||
'name': 'La Di Da',
|
||||
'duration': '2:53',
|
||||
},
|
||||
{
|
||||
'name': 'Goodbye Hollywood',
|
||||
'duration': '4:13',
|
||||
},
|
||||
{
|
||||
'name': 'Walk',
|
||||
'duration': '3:07',
|
||||
},
|
||||
{
|
||||
'name': 'Times Like This',
|
||||
'duration': '3:20',
|
||||
},
|
||||
{
|
||||
'name': 'Let Me Out',
|
||||
'duration': '3:12',
|
||||
},
|
||||
{
|
||||
'name': 'Start the Show',
|
||||
'duration': '3:59',
|
||||
},
|
||||
{
|
||||
'name': 'She Holds a Grudge',
|
||||
'duration': '4:18',
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
0
public/passenger.3000.pid.lock
Normal file
81
public/stylesheets/albums.css
Normal file
@ -0,0 +1,81 @@
|
||||
/* Main blocks*/
|
||||
.artist-info {
|
||||
width: 100%;
|
||||
float: left;
|
||||
margin: 25px 0;
|
||||
}
|
||||
.albums {
|
||||
width: 100%;
|
||||
float: left;
|
||||
}
|
||||
|
||||
/* Artist info block */
|
||||
.artist-info .pic {
|
||||
float: left;
|
||||
width: 250px;
|
||||
margin: 25px 0;
|
||||
}
|
||||
.artist-info .pic img {
|
||||
margin-left: 25px;
|
||||
}
|
||||
.artist-info .name {
|
||||
margin: 25px 0 0 300px;
|
||||
}
|
||||
.artist-info .info {
|
||||
margin: 0 25px 25px 300px;
|
||||
}
|
||||
|
||||
/* Albums block */
|
||||
.album {
|
||||
clear: both;
|
||||
}
|
||||
.album .pic {
|
||||
float: left;
|
||||
width: 250px;
|
||||
}
|
||||
.album .pic > * {
|
||||
margin-left: 25px;
|
||||
}
|
||||
.album .pic .add-album {
|
||||
margin-top: 15px;
|
||||
width: auto;
|
||||
color: #04D;
|
||||
cursor: pointer;
|
||||
}
|
||||
.album .name {
|
||||
display: block;
|
||||
margin: 0 0 10px 300px;
|
||||
}
|
||||
.album .tracklist {
|
||||
margin: 0 25px 30px 300px;
|
||||
}
|
||||
.album .tracklist ul {
|
||||
|
||||
}
|
||||
.album .tracklist ul li {
|
||||
display: block;
|
||||
height: 20px;
|
||||
padding: 5px 0 0 0;
|
||||
border-top: #EEE 1px solid;
|
||||
}
|
||||
.album .tracklist ul li:hover {
|
||||
background-color: #FAFAFA;
|
||||
}
|
||||
.album .tracklist ul li:first-child {
|
||||
border-top: none;
|
||||
}
|
||||
.album .tracklist ul li .trackname {
|
||||
float: left;
|
||||
}
|
||||
.album .tracklist ul li .index {
|
||||
display: block;
|
||||
float: left;
|
||||
width: 15px;
|
||||
text-align: right;
|
||||
margin: 3px 5px 0 0;
|
||||
font-size: 10px;
|
||||
color: #555;
|
||||
}
|
||||
.album .tracklist ul li .length {
|
||||
float: right;
|
||||
}
|
32
public/stylesheets/layout.css
Normal file
@ -0,0 +1,32 @@
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
}
|
||||
|
||||
body {
|
||||
overflow: hidden;
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
#header-container {
|
||||
margin-right: 350px;
|
||||
}
|
||||
#player-container {
|
||||
width: 350px;
|
||||
height: 600px;
|
||||
float: right;
|
||||
}
|
||||
#data-container {
|
||||
width: auto;
|
||||
margin-right: 350px;
|
||||
}
|
||||
|
||||
#player {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
}
|
||||
#playlist {
|
||||
width: 100%;
|
||||
}
|
38
public/stylesheets/misc.css
Normal file
@ -0,0 +1,38 @@
|
||||
.fullscreen {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#navigation {
|
||||
background-color: #333;
|
||||
height: 30px;
|
||||
}
|
||||
#navigation li {
|
||||
display: block;
|
||||
float: left;
|
||||
width: auto;
|
||||
height: 30px;
|
||||
margin-left: 10px;
|
||||
color: #FFF;
|
||||
line-height: 30px;
|
||||
text-shadow: #CCC 0px 0px 0.5px;
|
||||
}
|
||||
#navigation li:hover {
|
||||
cursor: pointer;
|
||||
text-shadow: #CCC 0px 0px 2px;
|
||||
}
|
||||
#navigation li.logo {
|
||||
font-size: 20px;
|
||||
line-height: 32px;
|
||||
font-weight: bold;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
/* Colorizing *
|
||||
#player-container { background-color: #CFC; }
|
||||
#data-container { background-color: #CCF; }
|
||||
#player { background-color: #AAC; }
|
||||
#playlist { background-color: #ACC; }
|
||||
.artist-info { background-color: #8EA; }
|
||||
.albums { background-color: #A8E; }
|
68
public/stylesheets/player.css
Normal file
@ -0,0 +1,68 @@
|
||||
#player {
|
||||
background-color: #222;
|
||||
}
|
||||
#player .now-playing {
|
||||
height: 30px;
|
||||
color: #FFF;
|
||||
text-align: center;
|
||||
line-height: 30px;
|
||||
}
|
||||
#player .progress {
|
||||
width: 290px;
|
||||
height: 10px;
|
||||
background-color: #333;
|
||||
margin: 20px 30px;
|
||||
}
|
||||
#player .progress .loaded {
|
||||
width: 0;
|
||||
height: 10px;
|
||||
background-color: #405050;
|
||||
}
|
||||
#player .progress .played {
|
||||
width: 0;
|
||||
height: 10px;
|
||||
background-color: #09A;
|
||||
}
|
||||
#player .controls {
|
||||
width: 290px;
|
||||
margin: 40px 95px;
|
||||
}
|
||||
#player .controls > div {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
float: left;
|
||||
margin-right: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
#player .controls .prev {
|
||||
background-image: url('../icns/prev.png');
|
||||
}
|
||||
#player .controls .play {
|
||||
background-image: url('../icns/play.png');
|
||||
}
|
||||
#player .controls .next {
|
||||
background-image: url('../icns/next.png');
|
||||
}
|
||||
|
||||
.playlist-tracks li {
|
||||
display: block;
|
||||
}
|
||||
.playlist-tracks li .item {
|
||||
padding: 5px 6px;
|
||||
}
|
||||
.playlist-tracks li .item:hover {
|
||||
background-color: #D0E0F0;
|
||||
cursor: default;
|
||||
}
|
||||
.playlist-tracks li:nth-child(even) {
|
||||
background-color: #F0F0F0;
|
||||
cursor: default;
|
||||
}
|
||||
.playlist-tracks li.now .item {
|
||||
background-color: #E0EAF0;
|
||||
cursor: default;
|
||||
}
|
||||
.playlist-tracks li .item .duration {
|
||||
display: block;
|
||||
float: right;
|
||||
}
|
10
public/xd_receiver.html
Normal file
@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Open API XD Receiver</title>
|
||||
</head>
|
||||
<body>
|
||||
<script src="http://vkontakte.ru/js/api/xd_receiver.js" type="text/javascript"></script>
|
||||
</body>
|
||||
</html>
|
15
test/fixtures/albums.yml
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
|
||||
|
||||
one:
|
||||
name: MyString
|
||||
artist_id: 1
|
||||
year: 1
|
||||
status: 1
|
||||
pic_url: MyString
|
||||
|
||||
two:
|
||||
name: MyString
|
||||
artist_id: 1
|
||||
year: 1
|
||||
status: 1
|
||||
pic_url: MyString
|
9
test/fixtures/artists.yml
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
|
||||
|
||||
one:
|
||||
name: MyString
|
||||
desc: MyText
|
||||
|
||||
two:
|
||||
name: MyString
|
||||
desc: MyText
|
17
test/fixtures/tracks.yml
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
|
||||
|
||||
one:
|
||||
name: MyString
|
||||
album_id: 1
|
||||
position: 1
|
||||
bonus: 1
|
||||
live: 1
|
||||
acoustic: 1
|
||||
|
||||
two:
|
||||
name: MyString
|
||||
album_id: 1
|
||||
position: 1
|
||||
bonus: 1
|
||||
live: 1
|
||||
acoustic: 1
|
8
test/unit/album_test.rb
Normal file
@ -0,0 +1,8 @@
|
||||
require 'test_helper'
|
||||
|
||||
class AlbumTest < ActiveSupport::TestCase
|
||||
# Replace this with your real tests.
|
||||
test "the truth" do
|
||||
assert true
|
||||
end
|
||||
end
|
8
test/unit/artist_test.rb
Normal file
@ -0,0 +1,8 @@
|
||||
require 'test_helper'
|
||||
|
||||
class ArtistTest < ActiveSupport::TestCase
|
||||
# Replace this with your real tests.
|
||||
test "the truth" do
|
||||
assert true
|
||||
end
|
||||
end
|
8
test/unit/track_test.rb
Normal file
@ -0,0 +1,8 @@
|
||||
require 'test_helper'
|
||||
|
||||
class TrackTest < ActiveSupport::TestCase
|
||||
# Replace this with your real tests.
|
||||
test "the truth" do
|
||||
assert true
|
||||
end
|
||||
end
|