1
0
Fork 0

Merge branch 'master' of github.com:magnolia-fan/BeatHaven

Conflicts:
	config/routes.rb
This commit is contained in:
Hipster Hitman 2011-04-28 03:24:41 +04:00
commit 3bb393bbc7
24 changed files with 361 additions and 138 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
tmp/
log/

View File

@ -3,15 +3,15 @@ class ArtistController < ApplicationController
require 'open-uri'
def view
# Dirty auth block START
unless request.session['session_id'].nil? or MainController.logged_in request.session['session_id']
redirect_to '/login'
return
else
if request.session['session_id'].nil?
redirect_to '/login'
return
end
end
# unless request.session['session_id'].nil? or MainController.logged_in request.session['session_id']
# redirect_to '/login'
# return
# else
# if request.session['session_id'].nil?
# redirect_to '/login'
# return
# end
# end
# Dirty auth block END
if params[:name].nil?
name = ''

View File

@ -1,23 +1,7 @@
class MainController < ApplicationController
def index
# Dirty auth block START
unless request.session['session_id'].nil? or MainController.logged_in request.session['session_id']
redirect_to '/login'
else
if request.session['session_id'].nil?
redirect_to '/login'
end
end
# Dirty auth block END
end
def self.logged_in session_id
user_data = User.collection.find({session_key: Digest::SHA256.hexdigest(session_id)}).first
unless user_data.nil?
user_data['lastvisit'] = Time.now()
User.collection.update({_id: user_data._id}, user_data.attributes)
return true
else
return false
end
# unless User.logged_in
# redirect_to '/login'
# end
end
end

View File

@ -3,18 +3,14 @@ class TrackController < ApplicationController
require 'uri'
def listen
pp track = Track.where(:id => params[:id].to_i).first
pp release = Release.where(:id => track.release_id).first
pp album = Album.where(:id => release.album_id).first
pp artist = Artist.where(:id => album.artist_id).first
data = Vkontakte.get(artist.name, track.name, (track.length / 1000).round)
data = Vkontakte.get(track.artist_name, track.name, (track.length / 1000).round)
# data = Vkontakte.get(1, 1, 1)
url = URI.parse(data['url'])
nginx_url = '/proxy-stream/no-token/' << data['remixsid'] << '/' << '5' << '/' << url.host << url.path
#render :inline => nginx_url
headers['Content-Type'] = 'audio/mpeg'
headers['X-Accel-Redirect'] = nginx_url
headers['Connection'] = 'close'
render :nothing => true
end
end

View File

@ -1,4 +1,8 @@
class UserController < ApplicationController
@@invite_salt = 'Gouranga gives a fuck?!'
@@email_regex = /^[a-zA-Z][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$/
def login
@hide_player = 1
unless params[:email].nil? or params[:password].nil?
@ -28,7 +32,7 @@ class UserController < ApplicationController
@hide_player = 1
data = Invite.where(:email => params[:invite_email], :code => params[:invite_code]).first
unless data.nil?
if params[:email].match(/\A[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}\z/).nil? or
if params[:email].match(@@email_regex).nil? or
params[:password].length < 6 or
params[:password] != params[:password_c]
redirect_to '/'
@ -49,4 +53,40 @@ class UserController < ApplicationController
redirect_to '/login'
end
end
def update
@data = User.collection.find({session_key: Digest::SHA256.hexdigest(request.session['session_id'])}).first
unless @data.nil?
if request.request_method == 'POST'
if params[:name]
@data.name = params[:name]
end
User.collection.update({_id: @data._id}, @data.attributes)
end
else
render :json => 'wtf?'
end
end
def invite
@data = User.collection.find({session_key: Digest::SHA256.hexdigest(request.session['session_id'])}).first
unless @data.nil?
if @data.invites > 0
pp 1
if request.request_method == 'POST'
unless params[:email].nil?
if params[:email].match(@@email_regex)
Invite.collection.insert({email: params[:email], code: Digest::SHA256.hexdigest(params[:email] << @@invite_salt), referer: @data._id})
@data.invites -= 1
User.collection.update({_id: @data._id}, @data.attributes)
@ok = true
end
end
end
pp 2
else
render :json => 'wtf?'
end
end
end
end

View File

@ -1,4 +1,7 @@
module ApplicationHelper
def navigation
end
end
class Numeric

View File

@ -2,21 +2,17 @@ module Vkontakte
require 'uri'
require 'net/http'
require 'erb'
require 'pp'
#require 'nokogiri'
@@accounts = YAML.load_file("#{Rails.root.to_s}/config/vk_accounts.yml")
@@bot = nil
def self.get artist, track, length
self.randomBot
def self.get(artist, track, length)
self.randomBot()
html = self.getHtml(artist << ' - ' << track).force_encoding("WINDOWS-1251").encode("UTF-8")
#pp html.encoding
#File.open('/Users/chez/Sites/beathaven/tmp/vkres1.html', 'w') {|f| f.write(html) }
#html = open('/Users/chez/Sites/beathaven/tmp/vkres1.html').read
files = self.parseHtml(html)
files = self.calcWeight(files, artist, track, length)
#self.stream files.first['url']
return {
'url' => files.first['url'],
'remixsid' => @@bot['remixsid'],
@ -27,13 +23,13 @@ module Vkontakte
private
def self.randomBot
def self.randomBot()
botname = @@accounts.keys[rand(@@accounts.keys.length - 1)]
@@bot = @@accounts[botname]
pp 'Using bot ' << botname
end
def self.getHtml q
def self.getHtml(q)
headers = {
'Cookie' => 'remixsid='+ @@bot['remixsid'] + ';remixchk='+ @@bot['remixchk'].to_s,
'Referer' => 'http://vkontakte.ru/audio?album_id=0',
@ -60,7 +56,7 @@ module Vkontakte
data
end
def self.parseHtml html
def self.parseHtml(html)
files = []
html
.scan(/<table.*?<input.*?value=\"(.*?)\,\d{1,4}\".*?>.*?<div\sclass=\"duration.*?>(.*?)<\/div>.*?<div\sclass=\"title_wrap\".*?>.*?selectPerformer\(event\,\s\'(.*?)\'\).*?<span\sclass=\"title\">(.*?)<\/span><\/div>.*?<\/table>/mi)
@ -76,7 +72,7 @@ module Vkontakte
files
end
def self.calcWeight files, artist, track, length
def self.calcWeight(files, artist, track, length)
files.each do |file|
weight = 0
@ -99,18 +95,4 @@ module Vkontakte
files.sort_by{|file| file['weight']}.reverse
end
def self.stream url
headers = {
'Cookie' => 'remixsid='+ @@bot['remixsid'] + ';remixchk='+ @@bot['remixchk'].to_s,
'Referer' => 'http://vkontakte.ru/audio?album_id=0',
'User-Agent' => @@bot['user_agent'],
}
uri = URI.parse(url)
http = Net::HTTP.new(uri.host, 80)
resp, data = http.get2(uri.path, headers)
data
end
end

View File

@ -13,7 +13,7 @@ class Artist < ActiveRecord::Base
'http://www.last.fm/search/autocomplete' <<
'?q=' << URI.escape(query)
).read)
return nil if json.empty? else return json
return json.empty? ? nil : json
end
end

View File

@ -9,4 +9,16 @@ class User
key :invites, Integer
key :referer, Integer
key :active, Integer
def logged_in
unless request.session['session_id'].nil? or MainController.logged_in session['session_id']
redirect_to '/login'
return
else
if request.session['session_id'].nil?
redirect_to '/login'
return
end
end
end
end

View File

@ -9,11 +9,18 @@
<%= csrf_meta_tag %>
</head>
<body>
<div id="contents">
<div class="inner-1">
<div id="nav">
<ul>
<li><a href="/">Search</a></li>
<li><a href="/user/profile">Profile</a></li>
<li><a href="/logout">Logout</a></li>
</ul>
</div>
<% if @hide_player.nil? -%>
<div id="player">
<audio autoplay preload></audio>
<div id="audiobox"></div>
<div class="prev" title="Play Previous Track"><img src="/images/player/prev.svg" alt="prv" /></div>
<div class="play" title="Play"><img src="/images/player/play.svg" alt="ply" /></div>
<div class="pause" title="Pause" style="display:none"><img src="/images/player/pause.svg" alt="pause" /></div>
@ -29,7 +36,7 @@
</div>
<div class="time-left">0:00</div>
<div title="Play Tracks In Random Order" class="shuffle"><img src="/images/player/shuffle.svg" alt="shu" /></div>
<div title="Repeat Playlist" class="repeat"><img src="/images/player/shuffle.svg" alt="rep" /></div>
<div title="Repeat Playlist" class="repeat"><img src="/images/player/repeat.svg" alt="rep" /></div>
<div title="Show/Hide Playlist" class="playlist">
<img src="/images/player/playlist.svg" alt="pls" />
<div class="count">0</div>
@ -38,7 +45,11 @@
<div id="playlist">
<ul class="list"></ul>
</div>
<div class="corner-fix left"></div>
<div class="corner-fix right"></div>
<%- end %>
<div id="contents">
<div class="inner-1">
<%= yield %>
</div>
</div>

View File

@ -0,0 +1,7 @@
<div id="nav">
<ul>
<li><a href="/">Search</a></li>
<li><a href="/user/profile">Profile</a></li>
<li><a href="/logout">Logout</a></li>
</ul>
</div>

23
app/views/user/invite.erb Normal file
View File

@ -0,0 +1,23 @@
<div id="registration">
<h1>Help BeatHaven dominate those lousy humans!</h1>
<%= form_tag('/reg/complete', :method => 'post') do -%>
<%= label_tag 'email', 'E-mail' %><%= email_field_tag 'email', @email %><div id="email_error"></div>
<div class="complete">
<%= submit_tag 'I wanna get this guy in!' %>
</div>
<% end -%>
</div>
<script type="text/javascript" charset="utf-8">
$(function(){
$('#email').focus();
$('form').submit(function(){
$('#email, #email_error').html('');
if (! $('#email').val().match(/^[a-zA-Z][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$/)) {
$('#email_error').html('* Invalid email');
$('#email').focus();
return false;
}
return true;
})
})
</script>

31
app/views/user/update.erb Normal file
View File

@ -0,0 +1,31 @@
<div id="registration">
<h1>Update ur profile!</h1>
<%= form_tag('/user/profile', :method => 'post') do -%>
<%= label_tag 'email', 'E-mail' %><%= email_field_tag 'email', @data.email %>
<%= label_tag 'name', 'Name' %><%= text_field_tag 'name', @data.name %>
<%= label_tag 'password', 'Password' %><%= password_field_tag 'password', nil %><div id="password_error"></div>
<%= label_tag 'password_c', 'Confirm' %><%= password_field_tag 'password_c', nil %><div id="password_c_error"></div>
<div class="complete">
<%= submit_tag 'I\'m done!' %>
</div>
<% end -%>
</div>
<script type="text/javascript" charset="utf-8">
$(function(){
$('#password').focus();
$('form').submit(function(){
$('#password_error, #password_c_error').html('');
if ($('#password').val().length > 0 && $('#password').val().length < 6) {
$('#password_error').html('* Password must be 6+ characters length');
$('#password').focus();
return false;
} else if ($('#password').val().length > 0 && $('#password').val() != $('#password_c').val()) {
$('#password_c_error').html('* Password and confirmation doesn\'t match');
$('#password_c').focus();
return false;
}
return true;
})
})
</script>

View File

@ -1,6 +1,4 @@
# PostgreSQL version 9.0
# gem install pg
development:
defaults: &defaults
adapter: postgresql
database: beathaven
host: 192.168.0.128
@ -8,3 +6,9 @@ development:
password: password
pool: 5
timeout: 5000
development:
<<: *defaults
production:
<<: *defaults

View File

@ -20,6 +20,8 @@ Beathaven::Application.routes.draw do
match 'reg/:email/:code' => 'user#register', :constraints => { :email => /[-a-z0-9\._@]+/i, :code => /[a-f0-9]{64}/ }
match 'reg/complete' => 'user#complete'
match 'login' => 'user#login'
match 'user/profile' => 'user#update'
match 'user/invite' => 'user#invite'
match '*a', :to => 'errors#routing'
end

View File

@ -1,10 +1,9 @@
<?xml version="1.0" standalone="no"?>
<svg width="700" height="920" version="1.1" xmlns="http://www.w3.org/2000/svg">
<rect x="50" y="50" rx="50" ry="50" width="600" height="820" style="stroke:rgb(200,200,200);stroke-width:50;"/>
<rect x="150" y="150" width="400" height="50" style="fill:rgb(200,200,200);"/>
<rect x="150" y="265" width="400" height="50" style="fill:rgb(200,200,200);"/>
<rect x="150" y="380" width="400" height="50" style="fill:rgb(200,200,200);"/>
<rect x="150" y="495" width="400" height="50" style="fill:rgb(200,200,200);"/>
<rect x="150" y="610" width="400" height="50" style="fill:rgb(200,200,200);"/>
<rect x="150" y="725" width="400" height="50" style="fill:rgb(200,200,200);"/>
<svg width="700" height="900" version="1.1" xmlns="http://www.w3.org/2000/svg">
<rect x="50" y="50" rx="50" ry="50" width="600" height="800" style="stroke:rgb(200,200,200);stroke-width:50;"/>
<rect x="150" y="150" width="400" height="70" style="fill:rgb(200,200,200);"/>
<rect x="150" y="282" width="400" height="70" style="fill:rgb(200,200,200);"/>
<rect x="150" y="415" width="400" height="70" style="fill:rgb(200,200,200);"/>
<rect x="150" y="548" width="400" height="70" style="fill:rgb(200,200,200);"/>
<rect x="150" y="680" width="400" height="70" style="fill:rgb(200,200,200);"/>
</svg>

Before

Width:  |  Height:  |  Size: 718 B

After

Width:  |  Height:  |  Size: 637 B

View File

@ -0,0 +1,5 @@
<?xml version="1.0" standalone="no"?>
<svg width="700" height="500" version="1.1" xmlns="http://www.w3.org/2000/svg">
<path d="M250 400 L150 400 C125 400 100 375 100 350 L100 150 C100 125 125 100 150 100 L550 100 C575 100 600 125 600 150 L600 350 C600 375 575 400 550 400 L440 400" style="stroke:rgb(200,200,200);stroke-width:70;" />
<polygon points="249,300 369,400 249,500" style="fill:rgb(200,200,200);"/>
</svg>

After

Width:  |  Height:  |  Size: 417 B

View File

@ -14,7 +14,7 @@
450 150
500 150
L600 150
L560 150
M100 150
@ -31,11 +31,11 @@
450 400
500 400
L600 400
L560 400
" style="stroke:rgb(200,200,200);stroke-width:70;" />
<path d="M295 300 L371 150" style="stroke:rgb(0,0,0);stroke-width:50;" />
<path d="M379 400 L455 250" style="stroke:rgb(0,0,0);stroke-width:50;" />
<polygon points="599,70 680,150 599,230" style="fill:rgb(200,200,200);"/>
<polygon points="599,320 680,400 599,480" style="fill:rgb(200,200,200);"/>
<polygon points="559,50 680,150 559,210" style="fill:rgb(200,200,200);"/>
<polygon points="559,300 680,400 559,500" style="fill:rgb(200,200,200);"/>
</svg>

Before

Width:  |  Height:  |  Size: 757 B

After

Width:  |  Height:  |  Size: 757 B

File diff suppressed because one or more lines are too long

16
public/javascripts/jquery.jcarousel.min.js vendored Executable file

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,6 @@
var audio;
var prev_audio;
var next_audio;
var utid;
$(function(){
$.extend($.fn.disableTextSelect = function() {
@ -12,9 +14,8 @@ $(function(){
}
});
});
audio = document.getElementsByTagName('audio')[0];
$('#player .play').click(function(){
if (! audio.src) return;
if (! audio) return;
audio.play();
utid = window.setTimeout(updatePlayer, 100);
$('#player .pause').show();
@ -44,22 +45,29 @@ $(function(){
playPrev();
}).disableTextSelect();
$('#player .next').click(function(){
playNext(false);
playNext();
}).disableTextSelect();
$('#player .shuffle, #player .repeat').click(function(){
$(this).toggleClass('on');
setNext();
}).disableTextSelect();
$('#player .playlist').click(function(){
$('#playlist').toggle();
//$('#playlist').data('jsp').reinitialise();
})
$('#player .progress-bar').click(function(e){
if (typeof(audio) !== 'undefined' && typeof(audio.duration) !== 'undefined') {
desired_progress = Math.abs(e.pageX - $(this).offset().left) / $('#player .progress-bar').innerWidth();
audio.currentTime = Math.round(audio.duration * desired_progress);
}
})
$('#playlist').hide();
})
function updatePlayer() {
duration = audio.duration;
cur_time = audio.currentTime;
if (cur_time == duration) {
playNext(true);
if (cur_time > 0 && cur_time == duration) {
playNext();
}
loaded = 0;
if ((audio.buffered != undefined) && (audio.buffered.length != 0)) {
@ -68,7 +76,12 @@ function updatePlayer() {
$('#player .time-left').html(formatTime(duration - cur_time));
progress = Math.round((cur_time / duration) * 390);
$('#player .progress-loaded').css('width', loaded +'px')
$('#player .progress-point').css('margin-left', progress +'px')
$('#player .progress-point').css('margin-left', progress - $('#player .progress-point').width() +'px')
/* Starting buffering next track */
if (Math.round(cur_time / duration * 100) > 10) {
addAudio(next_audio);
}
}
utid = window.setTimeout(updatePlayer, 100);
}
@ -79,35 +92,40 @@ function formatTime(sec) {
return m +':'+ (s < 10 ? '0' : '') +s;
}
function playTrack(artist, track, id) {
$(audio).attr('src', '/listen/'+ id +'.mp3');
switchAudio(id);
setNext();
$('#player .track-title').html(artist +' &mdash; '+ track);
$('#player .time-played').html('0:00');
$('#player .time-left').html('0:00');
$('#player .progress-loaded').css('width', 0 +'px')
$('#player .progress-point').css('margin-left', 0 +'px')
$('#player .progress-loaded').css('width', '0px')
$('#player .progress-point').css('margin-left', '-6px')
$('#player .play').trigger('click');
}
function playPrev() {
function setPrev() {
if ($('#playlist ul.list li').length == 0) return false;
if ($('#playlist ul.list li.now-playing').prev().length == 0) {
$('#playlist ul.list li:last').dblclick();
} else {
$('#playlist ul.list li.now-playing').prev().dblclick();
if (!audio) {
prev_audio = $(audio).attr('data-id');
}
}
function playNext(auto) {
function setNext() {
if ($('#playlist ul.list li').length == 0) return false;
if ($('#player .shuffle').hasClass('on')) {
$('#playlist ul.list li').rand().dblclick();
next_audio = $('#playlist ul.list li').rand().attr('data-id');
}
if ($('#playlist ul.list li.now-playing').next().length == 0) {
if ((auto && $('#player .repeat').hasClass('on')) || !auto) {
$('#playlist ul.list li:first').dblclick();
if ($('#player .repeat').hasClass('on')) {
next_audio = $('#playlist ul.list li:first').attr('data-id');
}
} else {
$('#playlist ul.list li.now-playing').next().dblclick();
next_audio = $('#playlist ul.list li.now-playing').next().attr('data-id');
}
}
function playPrev() {
return false;
}
function playNext() {
$('#playlist ul.list li[data-id="'+ next_audio +'"]').dblclick();
}
function addToPlaylist(artist, track, length, id) {
$('#playlist ul.list').append($(
'<li data-id="'+ id +'" title="Double-click To Play">'+
@ -121,6 +139,7 @@ function addToPlaylist(artist, track, length, id) {
playTrack(artist, track, id);
$('#playlist li').removeClass('now-playing');
$(this).addClass('now-playing');
setNext();
})
if ($('#playlist ul.list li').length == 1) {
$('#playlist ul.list li:first').dblclick();
@ -129,4 +148,22 @@ function addToPlaylist(artist, track, length, id) {
$('#playlist').jScrollPane();
}
$('#player .playlist .count').html($('#playlist ul.list li').length);
setNext();
}
function addAudio(id) {
if ($('#audio_'+ id).length == 0) {
$('#audiobox').append('<audio id="audio_'+ id +'" src="" preload="preload"></audio>');
$('#audio_'+ id).attr('src', '/listen/'+ id +'.mp3');
}
}
function switchAudio(id) {
if (typeof(audio) != 'undefined' && audio.buffered.length != 0) {
console.log(audio, audio.buffered.length);
audio.pause();
audio.currentTime = 0;
}
if ($('#audio_'+ id).length == 0) {
addAudio(id);
}
audio = document.getElementById('audio_'+ id);
}

View File

@ -132,3 +132,53 @@ h1.artist > span > span.play {
padding: 0.2em;
}
#nav {
position: fixed;
z-index: 6;
top: 0;
left: 50%;
margin-left: -375px;
width: 750px;
height: 25px;
background-color: #000;
border-bottom: #222 1px solid;
}
#nav ul {
margin: 0 5px;
padding: 0;
list-style: none;
}
#nav ul li {
display: inline-block;
width: auto;
margin: 0 5px;
}
#nav ul li a {
color: #CCC;
line-height: 25px;
font-size: 12px;
text-decoration: none;
font-weight: bold;
}
#nav ul li a:hover {
color: #DDD;
}
.corner-fix {
position: fixed;
z-index: 4;
width: 8px;
height: 8px;
background-color: #000;
top: 25px;
left: 50%;
}
.corner-fix.left {
margin-left: -375px;
}
.corner-fix.right {
margin-left: 367px;
}

View File

@ -1,12 +1,21 @@
audio {
width: 0;
height: 0;
position: absolute;
top: -1000px;
left: -1000px;
}
#player {
position: fixed;
z-index: 5;
width: 750px;
height: 50px;
left: 50%;
top: 0;
top: 25px;
margin-left: -375px;
background-color: #000;
font-size: 12px;
border-radius: 8px;
}
#player .prev, #player .next, #player .play, #player .pause {
float: left;
@ -83,6 +92,9 @@
width: 390px;
height: 3px;
}
#player .progress-bar:hover {
cursor: pointer;
}
#player .progress-loaded {
float: left;
width: 0;
@ -95,7 +107,7 @@
height: 6px;
background-color: #013;
margin-top: -4px;
margin-left: 0;
margin-left: -6px;
border: #FFF 3px solid;
border-radius: 6px;
cursor: pointer;
@ -145,10 +157,11 @@
}
#playlist {
position: fixed;
top: 50px;
z-index: 5;
top: 75px;
left: 50%;
width: 750px;
margin-left: -375px;
width: 734px;
margin-left: -367px;
background-color: #000;
opacity: 0.9;
-moz-opacity: 0.9;
@ -178,6 +191,7 @@
}
#playlist ul li.now-playing {
background-color: #013;
font-weight: bold;
}
#playlist ul li .length {
margin: 0 0.5em;

View File

@ -23,7 +23,7 @@
font-size: 20px;
line-height: 35px;
}
#registration input[type="email"], input[type="password"] {
#registration input[type="email"], input[type="password"], input[type="text"] {
width: 230px;
font-size: 20px;
border: #EAEAEA 1px solid;