Created
August 28, 2012 17:46
-
-
Save kyv/3501320 to your computer and use it in GitHub Desktop.
upload.rb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Rockola API | |
#http://rockola.flujos.org | |
# | |
#Copyright 2012, kev | |
#Licensed under the GPL Version 2 license. | |
# | |
#Descripción: interaccion con media (audio) | |
require 'rubygems' | |
require 'sinatra' | |
require 'fileutils' | |
require 'data_mapper' | |
require 'bcrypt' | |
require 'taglib' | |
require 'json' | |
require 'open-uri' | |
require 'hpricot' | |
require 'librmpd' | |
require 'digest/md5' | |
require 'sinatra/opencaptcha' | |
use Rack::Session::Cookie, :key => 'rack.session', | |
:path => '/', | |
:secret => '3c5f185eed89c2bf687f0fcd94d058d50087a2a9fc1f734735898e4acc48f2b7' | |
#set :dump_errors, false | |
set :html_path, '/srv/http/rockola/files/' #hard links to /srv/media | |
set :store_path, '/srv/media/' #git-media store media files | |
set :nginx_tmp, '/tmp/' | |
unless File.exists? settings.nginx_tmp + '1' | |
range = 0..9 | |
range.each do |i| | |
dir = settings.nginx_tmp + i.to_s | |
FileUtils.mkdir_p dir | |
FileUtils.chown 'http', 'http', dir | |
end | |
end | |
DataMapper::Logger.new(STDOUT, :debug) #depurar db | |
# inicializar base de datos | |
DataMapper.setup(:default, ENV['DATABASE_URL'] || "sqlite3://#{Dir.pwd}/rock.db") | |
class User | |
include DataMapper::Resource | |
property :id, Serial, :key => true | |
property :pass, String, :required => true, length: 10..255 | |
property :salt, String, :required => true | |
property :email, String, :required => true, :unique => true, format: :email_address | |
property :created_at, DateTime | |
has n, :medias | |
end | |
class Media | |
include DataMapper::Resource | |
property :id, Serial | |
property :name, String, :required => true | |
property :md5, String, :required => true, :key => true, :unique_index => true | |
property :type, String, :required => true | |
property :path, String, :required => true, :length => 150 | |
property :size, String, :required => true | |
property :title, String, :length => 150 | |
property :artist, String, :length => 150 | |
property :genre, String, :length => 150 | |
property :duration, String | |
property :bitrate, String | |
property :channels, String | |
property :tags, String, :length => 100 | |
property :created_at, DateTime | |
belongs_to :user | |
end | |
class Bara | |
include DataMapper::Resource | |
property :id, Serial | |
property :path, String, :required => true | |
property :playtime, String, :required => true | |
#has n, :medias | |
end | |
DataMapper.finalize | |
Media.auto_upgrade! | |
User.auto_upgrade! | |
helpers do | |
def admin? | |
not @login.nil? # or if session[:login] not in db | |
end | |
def getuser; return @login; end | |
def protected! ; halt [ 401, 'Not Authorized' ] unless admin? ; end | |
def get_params(md5) ; return Media.all(:md5 => md5); end | |
end | |
before do | |
@login = session[:login].inspect | |
user = User.first(:email=>session[:login]) | |
unless user.nil? | |
id = user.id | |
end | |
end | |
post '/update' do | |
unless admin? | |
redirect "/login" | |
end | |
title = params[:title] | |
artist= params[:artist] | |
genre = params[:genre] | |
tags = params[:tags] | |
id = params[:id] | |
media = Media.first(id) | |
media.update( title: title, artist: artist, genre: genre, tags: tags) | |
end | |
post '/upload' do | |
data = Hash.new | |
if defined? params['archivo.md5'] | |
data[:md5] = params['archivo.md5'] | |
data[:name] = params['archivo.name'] | |
data[:type] = params['archivo.content_type'] | |
data[:path] = params['archivo.path'] | |
data[:size] = params['archivo.size'] | |
end | |
# if defined? params['md5'] | |
# md5 = params['md5'] | |
# name = params['name'] | |
# type = params['content_type'] | |
# path = params['path'] | |
# size = params['size'] | |
# end | |
unless admin? | |
h = Hash.new | |
h[:type] = 'error' | |
return h.to_json | |
end | |
user = User.first(:email=>session[:login]) | |
id = user.id | |
store = settings.store_path + "/" + data[:md5] | |
finpath = settings.html_path + "/" + user.id.to_s + "/" + data[:name] | |
unless File.exists? settings.store_path | |
FileUtils.mkdir_p settings.store_path | |
end | |
unless File.exists? "#{settings.html_path}/#{user.id.to_s}" | |
FileUtils.mkdir_p "#{settings.html_path}/#{user.id.to_s}" | |
end | |
if File.exists? store | |
#flash[:upload] = 'File Exists' | |
else | |
FileUtils.cp(data[:path], store) | |
FileUtils.ln(store, finpath) | |
#flash[:upload] = 'New file: ' + data[:name] | |
end | |
media_data = get_tags(finpath) | |
if media_data[:genre].nil? | |
genre = 'nil' | |
else | |
genre = media_data[:genre][0..50] | |
end | |
if media_data[:artist].nil? | |
media_data[:artist] = 'nil' | |
end | |
if media_data[:title].nil? | |
media_data[:title] = 'nil' | |
end | |
data[:title] = media_data[:title] | |
data[:artist] = media_data[:artist] | |
data[:genre] = media_data[:genre] | |
data[:duration] = media_data[:duration] | |
data[:channels] = media_data[:channels] | |
data[:bitrate] = media_data[:bitrate] | |
data[:tags] = "#{media_data[:artist]}, #{genre}" | |
data[:user_id] = user.id | |
media = Array.new | |
media.push(Media.create(data)) | |
return media.to_json | |
end | |
get '/session' do | |
var = @login.to_s | |
if var == 'nil' | |
return nil | |
else | |
return 'user' | |
end | |
end | |
get '/search' do | |
if params[:artist].nil? | |
params[:artist] = 'xxx' | |
end | |
if params[:title].nil? | |
params[:title] = 'xxx' | |
end | |
media = Media.all(:title.like => "%#{params[:title]}%") | Media.all(:artist.like => "%#{params[:artist]}%") | |
media.to_json | |
end | |
get '/tags' do | |
tags = Hash.new(0) | |
Media.all(:order => [ :id.desc ]).each do |media| | |
media.tags.split(',').each do |tag| | |
tag = tag.strip | |
tags[tag] += 1 | |
end | |
end | |
return tags.to_json | |
end | |
get '/media' do | |
data = [] | |
media = Media.all(:order => [ :id.desc ], :limit => 20) | |
media.each do |f| | |
hash = {} # convertir class a hash, y borrar metodos no necesarios | |
f.instance_variables.each {|var| hash[var.to_s.delete("@")] = f.instance_variable_get(var) } | |
hash.delete("_repository"); hash.delete("_key");hash.delete("_collection"); hash.delete("#"); hash.delete("_persistence_state") | |
if f.name.match(/.mp3$/) | |
hash[:mp3] = "audio/#{f.user_id}/#{f.name}" | |
end | |
if f.name.match(/.og(g|a)$/) | |
hash[:oga] = "audio/#{f.user_id}/#{f.name}" | |
end | |
data.push(hash) | |
end | |
data.to_json | |
end | |
get '/current' do | |
mpd = MPD.new 'localhost', 6600 | |
mpd.connect | |
c = mpd.current_song | |
mpd.disconnect | |
mpd = nil | |
file = c.file.force_encoding('UTF-8') | |
path = settings.html_path+ file | |
name = File.basename(file) | |
return get_media(name).to_json | |
end | |
get '/cola' do | |
list = [] | |
mpd = MPD.new 'localhost', 6600 | |
mpd.connect | |
playlist = mpd.playlist | |
mpd.disconnect | |
playlist.each do |song| | |
h = Hash.new | |
file = song.file.force_encoding('UTF-8') | |
path = settings.html_path+ '/'+ file | |
name = File.basename(file) | |
get_media(name).each do |song| | |
list.push(song) | |
end | |
end | |
list.to_json | |
end | |
def get_media(song_name) | |
list = [] | |
mpd = MPD.new 'localhost', 6600 | |
mpd.connect | |
current = mpd.current_song | |
mpd.disconnect | |
Media.all(:name.like => song_name).each do |song| | |
h = Hash.new | |
unless song.title.nil? | |
h[:title] = song.title.force_encoding('UTF-8') | |
end | |
unless song.artist.nil? | |
h[:artist] = song.artist.force_encoding('UTF-8') | |
end | |
unless song.genre.nil? | |
h[:genre] = song.genre.force_encoding('UTF-8') | |
end | |
if song.respond_to?('time') | |
h[:duration] = song.time | |
end | |
h[:file] = song.name.force_encoding('UTF-8') | |
if song.name.match(/.mp3$/) | |
h[:mp3] = "audio/#{song.user_id}/#{song.name}" | |
end | |
if song.name.match(/.og(g|a)$/) | |
h[:oga] = "audio/#{song.user.id}/#{song.name}" | |
end | |
if song.id == current.id | |
h[:current] = true | |
end | |
list.push(h) | |
end | |
return list | |
end | |
get '/users' do | |
unless admin? | |
redirect "/login" | |
end | |
users = User.all(:order => [ :id.desc ], :limit => 20).to_json | |
end | |
get '/media/:md5' do | |
media = get_params(params[:md5]).to_json | |
end | |
get '/logout' do | |
session[:login] = nil | |
@login = nil | |
if session[:login].nil? && @login.nil? | |
return 'Vuelvas pronto' | |
else | |
return 'oops fallas al salir' | |
end | |
end | |
post '/login' do | |
unless open_captcha_valid? | |
return 'Captcha invalido, intenta nuevamente' | |
end | |
email=params[:email] | |
pass=params[:password] | |
if params[:registro] == "true" | |
salt = BCrypt::Engine.generate_salt | |
pass_hash = BCrypt::Engine.hash_secret(pass, salt) | |
User.create(email: email, pass: pass_hash, salt: salt) | |
end | |
user = User.first(:email=>email) | |
if user.nil? | |
return 'No existe tal usuario, intenta nuevamente' | |
end | |
salt = user.salt | |
pass_hash = BCrypt::Engine.hash_secret(pass, salt) | |
if User.all(:pass=>pass_hash, :email=>user.email) | |
session[:login] = user.email | |
return 'Benvenidos '+ user.email | |
else | |
return 'Error Incomprensible' | |
end | |
end | |
def get_tags(file) | |
data = {} | |
TagLib::FileRef.open(file) do |file| | |
prop = file.audio_properties | |
tag = file.tag | |
data = {:duration => prop.length, :bitrate => prop.bitrate, :channels => prop.channels} | |
unless tag.artist.nil? | |
data[:artist] = tag.artist | |
end | |
unless tag.title.nil? | |
data[:title] = tag.title | |
end | |
unless tag.genre.nil? | |
data[:genre] = tag.genre | |
end | |
end | |
return data | |
end | |
get '/icestat' do | |
url = "http://radio.flujos.org:8000" | |
res = '' | |
open(url, "User-Agent" => "Ruby/#{RUBY_VERSION}", | |
"From" => "[email protected]", | |
"Referer" => "http://www.flujos.org/") { |f| | |
res = f.read | |
} | |
doc = Hpricot(res) | |
#@streamdata.to_json | |
#@streamdata.each do |mount| | |
mounts = [] | |
h = Hash.new | |
(doc/"/html/body/div").each do |data| | |
doc_x = Hpricot(data.inner_html) | |
mount = doc_x.search("h3").inner_html.match(/\/.*$/) | |
title = doc_x.search("//td[@class='streamdata']")[0] | |
desc = doc_x.search("//td[@class='streamdata']")[1] | |
type = doc_x.search("//td[@class='streamdata']")[2] | |
created_at = doc_x.search("//td[@class='streamdata']")[3] | |
current = doc_x.search("//td[@class='streamdata']")[-1] | |
#regex = /Genre\:\s*(.*$)/ | |
#genre = doc_x.search("//td").inner_html.to_s.match(regex) | |
h = {'mount' => mount, 'title' => title, 'description' => desc, 'type' => type, 'created_at' => created_at, 'current' => current } | |
mounts.push(h) | |
end | |
#h = { 'title'=> mount[0], 'description' => mount[1], 'type' => mount[2], 'created_at' => mount[3], 'bitrate' => mount[4], 'listeners' => mount[5], 'peak' => mount[6], 'genre' => mount[7], 'url' => mount[8], 'song' => mount[9] } | |
#@mounts << (doc_x/"table").inner_html | |
return mounts[1..-2].to_json | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment