qtunes 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -3,3 +3,4 @@
3
3
  Gemfile.lock
4
4
  pkg/*
5
5
  .rvmrc
6
+ .sass-cache
@@ -4,6 +4,8 @@ require 'rack-flash'
4
4
  require 'digest/sha2'
5
5
  require 'audioinfo'
6
6
  require 'qtunes/paginatable'
7
+ require 'compass'
8
+ require 'susy'
7
9
 
8
10
  module Qtunes
9
11
  class Server < Sinatra::Base
@@ -17,7 +19,13 @@ module Qtunes
17
19
  set :static, true
18
20
 
19
21
  before do
20
- @current = self.class.song_to_hash(player.file) rescue {}
22
+ @current = self.class.song_to_hash(player.file)
23
+ end
24
+
25
+ get '/screen.css' do
26
+ require 'susy'
27
+ content_type 'text/css', :charset => 'utf-8'
28
+ scss :screen
21
29
  end
22
30
 
23
31
  get '/' do
@@ -27,8 +35,10 @@ module Qtunes
27
35
  end
28
36
 
29
37
  get '/library' do
30
- @page = params[:page] ? params[:page].to_i : 1
31
- @songs = library.values.extend(Qtunes::Paginatable).page(@page)
38
+ #@page = params[:page] ? params[:page].to_i : 1
39
+ @page = params[:page] || 'a'
40
+ #@songs = library.values.extend(Qtunes::Paginatable).page(@page)
41
+ @songs = library_by_first_letter_of_artist[@page] || []
32
42
 
33
43
  erb :songs
34
44
  end
@@ -68,6 +78,21 @@ module Qtunes
68
78
  self.class.queue
69
79
  end
70
80
 
81
+ def self.library_by_first_letter_of_artist
82
+ @library_by_first_letter_of_artist ||= begin
83
+ result = Hash.new{|h,k| h[k] = Array.new }
84
+ library.values.inject(result) do |res,song|
85
+ key = song['artist'] ? string_to_ascii(song['artist']).downcase[0,1] : ''
86
+ res[key] << song
87
+ res
88
+ end
89
+ end
90
+ end
91
+
92
+ def library_by_first_letter_of_artist
93
+ self.class.library_by_first_letter_of_artist
94
+ end
95
+
71
96
  def self.library
72
97
  @library ||= begin
73
98
  print "Loading library..."
@@ -81,6 +106,15 @@ module Qtunes
81
106
  self.class.library
82
107
  end
83
108
 
109
+ def self.string_to_ascii(s)
110
+ require 'unicode'
111
+ Unicode::normalize_KD(s).gsub(/[^A-Za-z0-9\s_-]+/,'')
112
+ end
113
+
114
+ def string_to_ascii(s)
115
+ self.class.string_to_ascii(s)
116
+ end
117
+
84
118
  helpers do
85
119
  include Rack::Utils
86
120
  alias_method :h, :escape_html
@@ -98,8 +132,22 @@ module Qtunes
98
132
  Digest::SHA256.hexdigest(path)[0,10]
99
133
  end
100
134
 
135
+
136
+ # Get the information for a song.
137
+ #
138
+ # path - String representing location of song
139
+ #
140
+ # Examples
141
+ #
142
+ # song_to_hash '~/Music/song2.mp3'
143
+ # # => {'path' => '~/Music/song2.mp3', 'id' => '12345', ...}
144
+ #
145
+ # Returns Hash with info of song or empty Hash in case path is nil.
101
146
  def self.song_to_hash(path)
102
147
  result = {}
148
+
149
+ return result if not path
150
+
103
151
  begin
104
152
  result.merge!(AudioInfo.open(path).to_h)
105
153
  rescue AudioInfoError
@@ -121,6 +169,12 @@ module Qtunes
121
169
  configure do
122
170
  puts "Configure"
123
171
 
172
+ Compass.configuration do |config|
173
+ config.project_path = dir
174
+ config.sass_dir = "#{dir}/server/views"
175
+ end
176
+ set :scss, Compass.sass_engine_options
177
+
124
178
  Qtunes::Server.library
125
179
  end
126
180
  end
@@ -0,0 +1,12 @@
1
+ // Imports -------------------------------------------------------------------
2
+
3
+ @import "susy";
4
+
5
+ // Grid ----------------------------------------------------------------------
6
+
7
+ $total-cols : 12;
8
+ $col-width : 6em;
9
+ $gutter-width : 1em;
10
+ $side-gutter-width : $gutter-width;
11
+
12
+ $show-grid-backgrounds : true;
@@ -0,0 +1,9 @@
1
+ <div class='pagination'>
2
+ <% ('a'..'z').each do |e| %>
3
+ <% if library_by_first_letter_of_artist.has_key?(e) %>
4
+ <a href="?page=<%= e %>"><%= e %></a>
5
+ <% else %>
6
+ <span><%= e %></span>
7
+ <% end %>
8
+ <% end %>
9
+ </div>
@@ -3,15 +3,12 @@
3
3
  %>
4
4
  <div class="<%= klasses.join(' ') %>">
5
5
  <% if not defined?(current) %>
6
- <span class="controls">
7
- <% if queue[song['id']] %>
8
- <a href="/remove/<%= song['id'] %>" title="remove from queue">-</a>
9
- <% else %>
10
- <a href="/add/<%= song['id'] %>" title="add to queue">+</a>
11
- <% end %>
12
- </span>
6
+ <% if queue[song['id']] %>
7
+ <a href="/remove/<%= song['id'] %>" title="remove from queue">--</a>
8
+ <% else %>
9
+ <a href="/add/<%= song['id'] %>" title="add to queue">+</a>
10
+ <% end %>
13
11
  <% end %>
14
-
15
12
  <span class="artist"><%= song['artist'] && !song['artist'].empty? ? song['artist'] : song['path'] %></span>
16
13
  <span class="title"><%= song['title'] %></span>
17
14
  <span class="album"><%= song['album'] %></span>
@@ -2,24 +2,34 @@
2
2
  <html>
3
3
  <head>
4
4
  <title>Qtunes</title>
5
- <link rel="stylesheet" href="/base.css" type="text/css" />
5
+ <link rel="stylesheet" href="/screen.css" type="text/css" />
6
6
  </head>
7
7
 
8
8
  <body>
9
- <h1><a href='/'>Qtunes</a></h1>
9
+ <div class='container'>
10
+ <div class='header'>
11
+ <h1><a href='/'>Qtunes</a></h1>
10
12
 
11
- <div class="navigation">
12
- <a href="/">Queue</a>
13
- <a href="/library">Library</a>
14
- </div>
13
+ <ul class="nav">
14
+ <li>
15
+ <a href="/">Queue (<%= queue.size %>)</a>
16
+ </li>
17
+ <li>
18
+ <a href="/library">Library</a>
19
+ </li>
20
+ </ul>
21
+ </div>
15
22
 
16
- <% if flash[:notice] %>
17
- <p class="notice"><%= flash[:notice] %></p>
18
- <% end %>
19
- <% if flash[:error] %>
20
- <p class="error"><%= flash[:error] %></p>
21
- <% end %>
23
+ <div class='main'>
24
+ <% if flash[:notice] %>
25
+ <p class="flash notice"><%= flash[:notice] %></p>
26
+ <% end %>
27
+ <% if flash[:error] %>
28
+ <p class="flash error"><%= flash[:error] %></p>
29
+ <% end %>
22
30
 
23
- <%= yield %>
31
+ <%= yield %>
32
+ </div>
33
+ </div>
24
34
  </body>
25
35
  </html>
@@ -0,0 +1,116 @@
1
+ // Imports -------------------------------------------------------------------
2
+
3
+ @import "base";
4
+ @import "compass/reset";
5
+ @import "compass/typography/lists/horizontal-list";
6
+
7
+
8
+ html {
9
+ font-family: Helmet, Freesans, sans-serif;
10
+ }
11
+
12
+ body {
13
+ color: #5E7894;
14
+ }
15
+
16
+ a {
17
+ color: #5E7894;
18
+ text-decoration: none;
19
+ &:hover {
20
+ color: #000;
21
+ }
22
+ }
23
+
24
+ .flash {
25
+ font-weight: bold;
26
+ text-align: center;
27
+ border: 1px solid #485460;
28
+ padding: 10px;
29
+ }
30
+
31
+
32
+ h1 {
33
+ padding: 0;
34
+ letter-spacing: -3px;
35
+ color: #000;
36
+ font-size: 4em;
37
+ font-weight: bold;
38
+ a {
39
+ display: block;
40
+ }
41
+ }
42
+
43
+ /* Layout ------------------------------------------------------------------*/
44
+ .container {
45
+ @include container;
46
+ //@include susy-grid-background;
47
+ width:100%;
48
+ }
49
+
50
+ .header {
51
+ @include full;
52
+
53
+ .nav {
54
+ @include horizontal-list;
55
+ margin: 10px 0px;
56
+ font-weight: bold;
57
+ font-size: 1.5em;
58
+ li {
59
+ padding-right: 30px;
60
+ }
61
+ }
62
+ }
63
+
64
+ .main {
65
+ @include full;
66
+ }
67
+
68
+ .pagination {
69
+ a {
70
+ font-size: 3em;
71
+ font-weight: bold;
72
+ text-transform: uppercase;
73
+ padding: 0px 4px;
74
+ }
75
+ }
76
+
77
+ .song {
78
+ letter-spacing: -1px;
79
+ background-color: #D0E4FA;
80
+ border-top: 2px solid #fff;
81
+ padding: .5em 0px .5em 10px;
82
+ font-size: 1.25em;
83
+ font-weight: bold;
84
+ font-size: 2.2em;
85
+
86
+ &.current, &.current * {
87
+ background-color: #485460;
88
+ color: #FFF !important;
89
+ }
90
+
91
+ .artist {
92
+ letter-spacing: -2px;
93
+ color: #485460;
94
+ font-size: 150%;
95
+ }
96
+
97
+ .title {
98
+ padding-left: 10px;
99
+ font-size: 120%;
100
+ }
101
+
102
+ .album {
103
+ margin-left: 10px;
104
+ letter-spacing: -2px;
105
+ font-size: 110%;
106
+ color: grey;
107
+ }
108
+
109
+ a {
110
+ float: right;
111
+ font-size: 130%;
112
+ font-family: Arial black;
113
+ letter-spacing: -5px;
114
+ padding-right: 10px;
115
+ }
116
+ }
@@ -1,22 +1,15 @@
1
1
  <%= erb :_song, {}, {:song => @current, :current => true} %>
2
2
 
3
- <% if @page %>
4
- <a href="?page=<%= @page - 1 %>">Previous</a>
5
- <a href="?page=<%= @page + 1 %>">Next</a>
6
- <% end %>
3
+ <% if @songs.any? %>
4
+ <%= erb :_paginate_artists if @page %>
7
5
 
8
- <% @songs.each_with_index do |song,ix| %>
9
- <%= erb :_song, {}, {:song => song} %>
10
- <% end %>
6
+ <% @songs.each_with_index do |song,ix| %>
7
+ <%= erb :_song, {}, {:song => song} %>
8
+ <% end %>
11
9
 
12
- <% if @songs.empty? %>
10
+ <%= erb :_paginate_artists if @page %>
11
+ <% else %>
13
12
  <div class="content">
14
13
  No more songs found!
15
14
  </div>
16
15
  <% end %>
17
-
18
- <% if @page %>
19
- <a href="?page=<%= @page - 1 %>">Previous</a>
20
- <a href="?page=<%= @page + 1 %>">Next</a>
21
- <% end %>
22
-
@@ -1,3 +1,3 @@
1
1
  module Qtunes
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  end
@@ -19,10 +19,13 @@ Gem::Specification.new do |s|
19
19
  s.require_paths = ["lib"]
20
20
 
21
21
  s.add_development_dependency "shotgun"
22
+ s.add_development_dependency "compass"
23
+ s.add_development_dependency "compass-susy-plugin"
22
24
 
23
25
  s.add_runtime_dependency "sinatra", "~> 1.2.6"
24
26
  s.add_runtime_dependency "rack-flash", "~> 0.1.2"
25
27
  s.add_runtime_dependency "thor", "~> 0.14.6"
26
28
  s.add_runtime_dependency "cocaine", "~> 0.2.0"
27
29
  s.add_runtime_dependency "ruby-audioinfo", "~> 0.1.7"
30
+ s.add_runtime_dependency "unicode", "~> 0.4.0"
28
31
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qtunes
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,12 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-08-31 00:00:00.000000000 +02:00
12
+ date: 2011-09-02 00:00:00.000000000 +02:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: shotgun
17
- requirement: &21068820 !ruby/object:Gem::Requirement
17
+ requirement: &14671020 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,32 @@ dependencies:
22
22
  version: '0'
23
23
  type: :development
24
24
  prerelease: false
25
- version_requirements: *21068820
25
+ version_requirements: *14671020
26
+ - !ruby/object:Gem::Dependency
27
+ name: compass
28
+ requirement: &14670600 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: *14670600
37
+ - !ruby/object:Gem::Dependency
38
+ name: compass-susy-plugin
39
+ requirement: &14670180 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ type: :development
46
+ prerelease: false
47
+ version_requirements: *14670180
26
48
  - !ruby/object:Gem::Dependency
27
49
  name: sinatra
28
- requirement: &21068320 !ruby/object:Gem::Requirement
50
+ requirement: &14669680 !ruby/object:Gem::Requirement
29
51
  none: false
30
52
  requirements:
31
53
  - - ~>
@@ -33,10 +55,10 @@ dependencies:
33
55
  version: 1.2.6
34
56
  type: :runtime
35
57
  prerelease: false
36
- version_requirements: *21068320
58
+ version_requirements: *14669680
37
59
  - !ruby/object:Gem::Dependency
38
60
  name: rack-flash
39
- requirement: &21067820 !ruby/object:Gem::Requirement
61
+ requirement: &14669180 !ruby/object:Gem::Requirement
40
62
  none: false
41
63
  requirements:
42
64
  - - ~>
@@ -44,10 +66,10 @@ dependencies:
44
66
  version: 0.1.2
45
67
  type: :runtime
46
68
  prerelease: false
47
- version_requirements: *21067820
69
+ version_requirements: *14669180
48
70
  - !ruby/object:Gem::Dependency
49
71
  name: thor
50
- requirement: &21067360 !ruby/object:Gem::Requirement
72
+ requirement: &14668720 !ruby/object:Gem::Requirement
51
73
  none: false
52
74
  requirements:
53
75
  - - ~>
@@ -55,10 +77,10 @@ dependencies:
55
77
  version: 0.14.6
56
78
  type: :runtime
57
79
  prerelease: false
58
- version_requirements: *21067360
80
+ version_requirements: *14668720
59
81
  - !ruby/object:Gem::Dependency
60
82
  name: cocaine
61
- requirement: &21066900 !ruby/object:Gem::Requirement
83
+ requirement: &14668260 !ruby/object:Gem::Requirement
62
84
  none: false
63
85
  requirements:
64
86
  - - ~>
@@ -66,10 +88,10 @@ dependencies:
66
88
  version: 0.2.0
67
89
  type: :runtime
68
90
  prerelease: false
69
- version_requirements: *21066900
91
+ version_requirements: *14668260
70
92
  - !ruby/object:Gem::Dependency
71
93
  name: ruby-audioinfo
72
- requirement: &21066440 !ruby/object:Gem::Requirement
94
+ requirement: &14667800 !ruby/object:Gem::Requirement
73
95
  none: false
74
96
  requirements:
75
97
  - - ~>
@@ -77,7 +99,18 @@ dependencies:
77
99
  version: 0.1.7
78
100
  type: :runtime
79
101
  prerelease: false
80
- version_requirements: *21066440
102
+ version_requirements: *14667800
103
+ - !ruby/object:Gem::Dependency
104
+ name: unicode
105
+ requirement: &14667340 !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: 0.4.0
111
+ type: :runtime
112
+ prerelease: false
113
+ version_requirements: *14667340
81
114
  description: add songs to queue, let cmus eat it
82
115
  email:
83
116
  - gert@thinkcreate.nl
@@ -96,9 +129,11 @@ files:
96
129
  - lib/qtunes/paginatable.rb
97
130
  - lib/qtunes/player.rb
98
131
  - lib/qtunes/server.rb
99
- - lib/qtunes/server/public/base.css
132
+ - lib/qtunes/server/views/_base.scss
133
+ - lib/qtunes/server/views/_paginate_artists.erb
100
134
  - lib/qtunes/server/views/_song.erb
101
135
  - lib/qtunes/server/views/layout.erb
136
+ - lib/qtunes/server/views/screen.scss
102
137
  - lib/qtunes/server/views/songs.erb
103
138
  - lib/qtunes/version.rb
104
139
  - qtunes.gemspec
@@ -1,133 +0,0 @@
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: left;
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.current, .song.current * {
74
- background-color: #485460;
75
- color: #FFF !important;
76
- }
77
- .song a:hover{
78
- color: #000 !important;
79
- }
80
- .song .artist{
81
- font-size: 3em;
82
- letter-spacing: -5px;
83
- color: #485460;
84
- }
85
- .song .artist a{
86
- }
87
- .song .title{
88
- padding-left: 10px;
89
- font-size: 2.2em;
90
- letter-spacing: -4px;
91
- }
92
- .song .album{
93
- margin-left: 10px;
94
- font-size: 1.1em;
95
- letter-spacing: -2px;
96
- }
97
- .song .album a{
98
- color: #438FDF;
99
- }
100
- .song .controls{
101
- float: right;
102
- font-size: 6em;
103
- margin: -.5em -5px;
104
- text-transform: uppercase;
105
- }
106
- .votes{
107
- background-color: #485460;
108
- padding: 5px 5px 0px 5px;
109
- }
110
- .votes img{
111
- border: 1px solid #5E7894;
112
- }
113
- .votes img:hover{
114
- border: 1px solid #D0E4FA;
115
- }
116
-
117
- /*
118
- * PROFILE
119
- */
120
- .profile_box{
121
- margin-right: 10px;
122
- float: left;
123
- font-size: 1.1em;
124
- }
125
- .bio{
126
- padding: 15px 0;
127
- }
128
- .favorite_artists{
129
- margin: 0 15px;
130
- }
131
- .favorite_artists h2{
132
- color: #485460;
133
- }