sonice 2.0.0 → 2.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 3663e23a3502f84a181a07d3a65323993980b9b0c97860b138b36e1fbd983f84
4
+ data.tar.gz: 121da492eac569ac3dced778d5e47212445fb35d0f38f265862e34ac4bd47c3d
5
+ SHA512:
6
+ metadata.gz: f034dd6cae0e045236effdfb114f6ab75718d6fb3ec9d2d5e5f005c55caabb1f7f9aee664de70693ea5415eefb7a88fe04e27c21da6a98f70a8b585f2aa378ac
7
+ data.tar.gz: f70229248edc86a3ef54fc4b74ebac8dd5225bd9735d36c17618229dc3ca588f2249de18b34dd8a9bd99dd2030305054f3e204e8adf07aa7255ce97068164235
@@ -0,0 +1,3 @@
1
+ {
2
+ "esversion": 6
3
+ }
@@ -0,0 +1,105 @@
1
+ Style/StringLiterals:
2
+ Enabled: false
3
+
4
+ Layout/BeginEndAlignment: # (new in 0.91)
5
+ Enabled: true
6
+ Layout/EmptyLinesAroundAttributeAccessor: # (new in 0.83)
7
+ Enabled: true
8
+ Layout/SpaceAroundMethodCallOperator: # (new in 0.82)
9
+ Enabled: true
10
+ Lint/BinaryOperatorWithIdenticalOperands: # (new in 0.89)
11
+ Enabled: true
12
+ Lint/ConstantDefinitionInBlock: # (new in 0.91)
13
+ Enabled: true
14
+ Lint/DeprecatedOpenSSLConstant: # (new in 0.84)
15
+ Enabled: true
16
+ Lint/DuplicateElsifCondition: # (new in 0.88)
17
+ Enabled: true
18
+ Lint/DuplicateRequire: # (new in 0.90)
19
+ Enabled: true
20
+ Lint/DuplicateRescueException: # (new in 0.89)
21
+ Enabled: true
22
+ Lint/EmptyConditionalBody: # (new in 0.89)
23
+ Enabled: true
24
+ Lint/EmptyFile: # (new in 0.90)
25
+ Enabled: true
26
+ Lint/FloatComparison: # (new in 0.89)
27
+ Enabled: true
28
+ Lint/HashCompareByIdentity: # (new in 0.93)
29
+ Enabled: true
30
+ Lint/IdentityComparison: # (new in 0.91)
31
+ Enabled: true
32
+ Lint/MissingSuper: # (new in 0.89)
33
+ Enabled: true
34
+ Lint/MixedRegexpCaptureTypes: # (new in 0.85)
35
+ Enabled: true
36
+ Lint/OutOfRangeRegexpRef: # (new in 0.89)
37
+ Enabled: true
38
+ Lint/RaiseException: # (new in 0.81)
39
+ Enabled: true
40
+ Lint/RedundantSafeNavigation: # (new in 0.93)
41
+ Enabled: true
42
+ Lint/SelfAssignment: # (new in 0.89)
43
+ Enabled: true
44
+ Lint/StructNewOverride: # (new in 0.81)
45
+ Enabled: true
46
+ Lint/TopLevelReturnWithArgument: # (new in 0.89)
47
+ Enabled: true
48
+ Lint/TrailingCommaInAttributeDeclaration: # (new in 0.90)
49
+ Enabled: true
50
+ Lint/UnreachableLoop: # (new in 0.89)
51
+ Enabled: true
52
+ Lint/UselessMethodDefinition: # (new in 0.90)
53
+ Enabled: true
54
+ Lint/UselessTimes: # (new in 0.91)
55
+ Enabled: true
56
+ Style/AccessorGrouping: # (new in 0.87)
57
+ Enabled: true
58
+ Style/BisectedAttrAccessor: # (new in 0.87)
59
+ Enabled: true
60
+ Style/CaseLikeIf: # (new in 0.88)
61
+ Enabled: true
62
+ Style/ClassEqualityComparison: # (new in 0.93)
63
+ Enabled: true
64
+ Style/CombinableLoops: # (new in 0.90)
65
+ Enabled: true
66
+ Style/ExplicitBlockArgument: # (new in 0.89)
67
+ Enabled: true
68
+ Style/ExponentialNotation: # (new in 0.82)
69
+ Enabled: true
70
+ Style/GlobalStdStream: # (new in 0.89)
71
+ Enabled: true
72
+ Style/HashAsLastArrayItem: # (new in 0.88)
73
+ Enabled: true
74
+ Style/HashEachMethods: # (new in 0.80)
75
+ Enabled: true
76
+ Style/HashLikeCase: # (new in 0.88)
77
+ Enabled: true
78
+ Style/HashTransformKeys: # (new in 0.80)
79
+ Enabled: true
80
+ Style/HashTransformValues: # (new in 0.80)
81
+ Enabled: true
82
+ Style/KeywordParametersOrder: # (new in 0.90)
83
+ Enabled: true
84
+ Style/OptionalBooleanParameter: # (new in 0.89)
85
+ Enabled: true
86
+ Style/RedundantAssignment: # (new in 0.87)
87
+ Enabled: true
88
+ Style/RedundantFetchBlock: # (new in 0.86)
89
+ Enabled: true
90
+ Style/RedundantFileExtensionInRequire: # (new in 0.88)
91
+ Enabled: true
92
+ Style/RedundantRegexpCharacterClass: # (new in 0.85)
93
+ Enabled: true
94
+ Style/RedundantRegexpEscape: # (new in 0.85)
95
+ Enabled: true
96
+ Style/RedundantSelfAssignment: # (new in 0.90)
97
+ Enabled: true
98
+ Style/SingleArgumentDig: # (new in 0.89)
99
+ Enabled: true
100
+ Style/SlicingWithRange: # (new in 0.83)
101
+ Enabled: true
102
+ Style/SoleNestedConditional: # (new in 0.89)
103
+ Enabled: true
104
+ Style/StringConcatenation: # (new in 0.89)
105
+ Enabled: true
@@ -0,0 +1 @@
1
+ 2.7.1
@@ -0,0 +1,42 @@
1
+ Changelog
2
+ =========
3
+
4
+ So Nice tries its best to follow Semantic Versioning.
5
+
6
+ ## Unreleased
7
+
8
+ ## v2.2.1
9
+
10
+ - Remove rake executable in gemspec.
11
+ - Bump anyplayer dependency
12
+
13
+ ## v2.2.0
14
+
15
+ Fixes:
16
+
17
+ - Remove background image since LastFM API doesn’t contain images
18
+
19
+ Dependencies:
20
+
21
+ - Bump anyplayer dependency
22
+ - Remove Haml dependency
23
+ - Bump Sinatra dependency
24
+ - Replace Thin by Webrick
25
+
26
+ ## v2.1.2
27
+
28
+ Dependencies:
29
+
30
+ - Fix Sinatra upgrade (#22)
31
+ - Fix Thin dependency so as not to break with thin versions > 2
32
+
33
+ ## v2.1.1
34
+
35
+ Fixes:
36
+
37
+ - Fix LastFM JavaScript (thanks @datagutt)
38
+ - Fix Thin dependency with Sinatra
39
+
40
+ ## v2.1.0 (2013-12-18)
41
+
42
+ First Gem version.
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source "http://rubygems.org"
2
4
 
3
5
  # Gem dependencies in gemspec
@@ -1,40 +1,61 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sonice (1.0.0)
5
- anyplayer (> 1.1.1)
6
- haml
4
+ sonice (2.2.1)
5
+ anyplayer (>= 1.2.1)
7
6
  sinatra
8
- thin
7
+ webrick
9
8
  xml-simple
10
9
 
11
10
  GEM
12
11
  remote: http://rubygems.org/
13
12
  specs:
14
- anyplayer (1.1.2)
13
+ anyplayer (1.2.1)
15
14
  ruby-mpd (~> 0.3.0)
16
- daemons (1.1.9)
17
- eventmachine (1.0.3)
18
- haml (4.0.3)
19
- tilt
20
- rack (1.5.2)
21
- rack-protection (1.5.0)
15
+ ast (2.4.1)
16
+ mustermann (1.1.1)
17
+ ruby2_keywords (~> 0.0.1)
18
+ parallel (1.19.2)
19
+ parser (2.7.2.0)
20
+ ast (~> 2.4.1)
21
+ rack (2.2.3)
22
+ rack-protection (2.1.0)
22
23
  rack
23
- ruby-mpd (0.3.0)
24
- sinatra (1.4.3)
25
- rack (~> 1.4)
26
- rack-protection (~> 1.4)
27
- tilt (~> 1.3, >= 1.3.4)
28
- thin (1.5.1)
29
- daemons (>= 1.0.9)
30
- eventmachine (>= 0.12.6)
31
- rack (>= 1.0.0)
32
- tilt (1.4.1)
33
- xml-simple (1.1.2)
24
+ rainbow (3.0.0)
25
+ rake (13.0.1)
26
+ regexp_parser (1.8.1)
27
+ rexml (3.2.4)
28
+ rubocop (0.93.0)
29
+ parallel (~> 1.10)
30
+ parser (>= 2.7.1.5)
31
+ rainbow (>= 2.2.2, < 4.0)
32
+ regexp_parser (>= 1.8)
33
+ rexml
34
+ rubocop-ast (>= 0.6.0)
35
+ ruby-progressbar (~> 1.7)
36
+ unicode-display_width (>= 1.4.0, < 2.0)
37
+ rubocop-ast (0.7.1)
38
+ parser (>= 2.7.1.5)
39
+ ruby-mpd (0.3.3)
40
+ ruby-progressbar (1.10.1)
41
+ ruby2_keywords (0.0.2)
42
+ sinatra (2.1.0)
43
+ mustermann (~> 1.0)
44
+ rack (~> 2.2)
45
+ rack-protection (= 2.1.0)
46
+ tilt (~> 2.0)
47
+ tilt (2.0.10)
48
+ unicode-display_width (1.7.0)
49
+ webrick (1.7.0)
50
+ xml-simple (1.1.7)
34
51
 
35
52
  PLATFORMS
36
53
  ruby
37
54
 
38
55
  DEPENDENCIES
39
- rack
56
+ rake
57
+ rubocop
40
58
  sonice!
59
+
60
+ BUNDLED WITH
61
+ 2.1.4
data/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
  So Nice ♫
2
2
  =======
3
3
 
4
- > Everynight with my star friends
5
- >
6
- > We eat caviar and drink champage
4
+ [![Gem Version](https://badge.fury.io/rb/sonice.png)](http://badge.fury.io/rb/sonice)
5
+
6
+ > “Everynight with my star friends, we eat caviar and drink champage
7
7
 
8
8
  A small Web interface to play, pause, change volume or skip the currently
9
9
  playing song in iTunes Mac, iTunes Windows, Spotify Mac, MPD, Rhythmbox, Amarok and XMMS2.
@@ -14,7 +14,7 @@ playing song in iTunes Mac, iTunes Windows, Spotify Mac, MPD, Rhythmbox, Amarok
14
14
  Install
15
15
  -------
16
16
 
17
- Make sure you have Ruby and Rubygems installed. You can then type in a terminal:
17
+ Make sure you have Ruby > 1.9 and Rubygems installed. You can then type in a terminal:
18
18
 
19
19
  ```bash
20
20
  $ gem install sonice
data/Rakefile CHANGED
@@ -1,4 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler'
2
- require 'rake/testtask'
3
4
 
4
5
  Bundler::GemHelper.install_tasks
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rake' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require "pathname"
12
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
26
+ require "rubygems"
27
+ require "bundler/setup"
28
+
29
+ load Gem.bin_path("rake", "rake")
data/bin/sonice CHANGED
@@ -1,3 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
2
4
  require 'sonice/command_line'
3
5
  Sonice::CommandLine.parse(ARGV)
data/config.ru CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # You can start sonice using this configuration file by typing:
2
4
  # bundle exec thin start
3
5
 
@@ -8,4 +10,3 @@
8
10
 
9
11
  require "sonice"
10
12
  run Sonice::App
11
-
@@ -1,13 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Standard library
2
4
  require 'open-uri'
3
5
 
4
6
  # Gems
5
7
  require 'anyplayer'
6
8
  require 'sinatra'
7
- require 'haml'
8
9
  require 'xmlsimple' # xml-simple gem
9
10
  require 'json'
10
- require 'thin'
11
11
 
12
12
  # So Nice
13
+ require 'sonice/noplayer'
13
14
  require 'sonice/app'
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Sonice
4
+ # Sinatra application
2
5
  class App < Sinatra::Base
3
6
  set :port, ENV['SONICE_PORT'] || 3000
4
7
  set :controls, ENV['SONICE_CONTROLS'] != '0'
@@ -7,47 +10,47 @@ module Sonice
7
10
 
8
11
  set :logging, true
9
12
  set :static, true
10
- set :public_dir, File.expand_path('../public', __FILE__)
11
- set :views, File.expand_path('../views', __FILE__)
12
- set :haml, format: :html5
13
+ set :public_dir, File.expand_path('public', __dir__)
14
+ set :views, File.expand_path('views', __dir__)
13
15
  set :protection, except: :frame_options
16
+ set :server, :webrick
14
17
 
15
- def player
16
- @@player ||= begin
17
- puts "Looking for a player..."
18
- player = Anyplayer::Selector.new.player
19
- abort "Error: no music player launched!" if !player
20
- puts "Connected to #{player.name}"
21
- player
22
- end
18
+ def player_instance
19
+ return @player if @player&.launched?
20
+
21
+ @player = Anyplayer::Selector.new.player || Noplayer.new
23
22
  end
24
23
 
25
24
  put '/player' do
26
- if settings.voting
27
- player.vote if params['vote']
28
- end
25
+ player = player_instance
26
+
27
+ player.vote if settings.voting && params['vote']
29
28
 
30
29
  if settings.controls
31
- methods = %w(playpause prev next voldown volup) & params.keys
30
+ methods = %w[playpause prev next voldown volup] & params.keys
32
31
  methods.each { |method| player.send(method) }
33
32
  end
34
33
 
35
- if !request.xhr?
36
- redirect '/'
37
- end
34
+ redirect "/" unless request.xhr?
38
35
  end
39
36
 
40
37
  get '/' do
38
+ player = player_instance
39
+
41
40
  @title = player.track
42
41
  @artist = player.artist
43
42
  @album = player.album
43
+ @connected = player.launched?
44
+
44
45
  if request.xhr?
45
46
  content_type :json
46
- { :title => @title, :artist => @artist, :album => @album }.to_json
47
+ { title: @title,
48
+ artist: @artist,
49
+ album: @album,
50
+ connected: @connected }.to_json
47
51
  else
48
- haml :index
52
+ erb :index
49
53
  end
50
54
  end
51
-
52
55
  end
53
56
  end
@@ -1,9 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "sonice"
2
4
  require 'sonice/version'
3
5
 
4
6
  module Sonice
7
+ # Module CommandLine
5
8
  module CommandLine
6
- extend self
9
+ module_function
7
10
 
8
11
  def parse(argv)
9
12
  case argv
@@ -19,7 +22,6 @@ module Sonice
19
22
  puts "Usage: sonice [--version]"
20
23
  exit(1)
21
24
  end
22
-
23
25
  end
24
26
  end
25
27
  end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sonice
4
+ # A null-object that represents a player when none was found.
5
+ class Noplayer < Anyplayer::Player
6
+ def playing?
7
+ false
8
+ end
9
+
10
+ def play; end
11
+
12
+ def pause; end
13
+
14
+ def voldown; end
15
+
16
+ def volup; end
17
+
18
+ def volume; end
19
+
20
+ def track
21
+ nil
22
+ end
23
+
24
+ def artist
25
+ nil
26
+ end
27
+
28
+ def album
29
+ nil
30
+ end
31
+
32
+ def launched?
33
+ false
34
+ end
35
+
36
+ def name
37
+ "no player"
38
+ end
39
+ end
40
+ end
@@ -8,11 +8,6 @@ Array.prototype.random = function() {
8
8
 
9
9
  /* jQuery helpers */
10
10
 
11
- // Change CSS background image
12
- $.fn.background = function(bg) {
13
- return $(this).css('backgroundImage', bg ? 'url('+bg+')' : 'none')
14
- }
15
-
16
11
  // Assigns keyboard keys to elements and adds them to the title attributes
17
12
  // Needs the data-keyboard-key attribute on elements and optionally accepts
18
13
  // the data-keyboard-name attribute
@@ -29,47 +24,6 @@ $.fn.keyboardShortcut = function() {
29
24
  })
30
25
  }
31
26
 
32
-
33
- /* So nice helpers */
34
-
35
- // Get a new artist image from Last.fm via jsonp
36
- // When found calls the `callback` with the image url as the first argument
37
- function artistImage(artist, callback) {
38
- // Commented out because Last.fm does not support this URL anymore.
39
-
40
- // if (!artist)
41
- // return callback()
42
- // var cb = function() { callback(cache[artist].random()) },
43
- // cache = artistImage.cache
44
- // artist = encodeURI(artist)
45
-
46
- // // Deliver from cache
47
- // if (cache.hasOwnProperty(artist)) {
48
- // // execute the callback asynchronously to minimize codepaths
49
- // setTimeout(cb, 10)
50
- // return
51
- // }
52
-
53
- // // Load
54
- // var last_fm_uri = "http://ws.audioscrobbler.com/2.0/?format=json&method=artist.getimages&artist=%s&api_key=5636ca9fea36d0323a76638385aab1f3"
55
- // $.ajax({
56
- // url: last_fm_uri.replace('%s', artist),
57
- // dataType: 'jsonp',
58
- // success: function(obj) {
59
- // if (obj.images.image) {
60
- // cache[artist] = $.map(obj.images.image, function(img) {
61
- // return img.sizes.size[0]['#text']
62
- // })
63
- // cb()
64
- // } else {
65
- // callback()
66
- // }
67
- // }
68
- // })
69
- }
70
- artistImage.cache = {}
71
-
72
-
73
27
  $(function() {
74
28
  // Object that contains all the song info
75
29
  var currentSong = {}
@@ -81,12 +35,15 @@ $(function() {
81
35
  currentSong = obj = obj || {}
82
36
 
83
37
  var artist = obj.artist || '',
84
- album = obj.album || '',
85
- title = obj.title || ''
38
+ album = obj.album || '',
39
+ title = obj.title || '',
40
+ connected = !!obj.connected
86
41
 
87
42
  $('#title' ).text(title)
88
43
  $('#artist').text(artist)
89
44
  $('#album' ).text(album)
45
+ $('[data-sonice-show-if-connected]')[connected ? 'show' : 'hide']()
46
+ $('[data-sonice-hide-if-connected]')[connected ? 'hide' : 'show']()
90
47
 
91
48
  if (!title)
92
49
  $('title').text('So nice')
@@ -95,16 +52,6 @@ $(function() {
95
52
 
96
53
  if (artistChange || songChange)
97
54
  $('#vote').removeAttr('disabled').show()
98
-
99
- if (artistChange)
100
- changeBackground()
101
- }
102
-
103
- // Change background on the body regularly
104
- var changeBackground = function(){
105
- artistImage(currentSong.artist, function(url) {
106
- $('body').background(url)
107
- })
108
55
  }
109
56
 
110
57
  // XHR updating the text regularly
@@ -118,7 +65,7 @@ $(function() {
118
65
 
119
66
  // XHR overriding the buttons
120
67
  $(document).on('click', 'input', function(e) {
121
- e.preventDefault();
68
+ e.preventDefault()
122
69
 
123
70
  $.ajax({
124
71
  type: 'put',
@@ -133,12 +80,10 @@ $(function() {
133
80
  $(this).attr('disabled', true).fadeOut(500)
134
81
  })
135
82
 
136
- update();
83
+ update()
137
84
  setInterval(update, 500)
138
- setInterval(changeBackground, 10000)
139
85
 
140
86
  // Keyboard shortcuts
141
- $('input').keyboardShortcut()
87
+ $('[data-key]').keyboardShortcut()
142
88
 
143
89
  })
144
-
@@ -1,13 +1,15 @@
1
1
  body {
2
2
  padding: 2em;
3
3
  margin: 0;
4
- background-color: black;
4
+ background-color: #555;
5
+ color: white;
6
+ font: 1.5em Helvetica, sans-serif;
7
+
8
+ /* Prepare for having a background-image */
5
9
  background-position: center center fixed no-repeat;
6
- background-repeat: bo-repeat;
10
+ background-repeat: no-repeat;
7
11
  background-attachment: fixed;
8
12
  background-size: cover;
9
- color: white;
10
- font: 1.5em Helvetica, sans-serif;
11
13
  }
12
14
 
13
15
  /* Overlay image */
@@ -31,19 +33,19 @@ h1, h2, h3 {
31
33
  text-shadow: black 0 0 7px;
32
34
  }
33
35
 
34
- h1 {
35
- font-size: 230%;
36
- }
36
+ h1 {
37
+ font-size: 230%;
38
+ }
37
39
 
38
- h2 {
39
- font-size: 150%;
40
- }
40
+ h2 {
41
+ font-size: 150%;
42
+ }
41
43
 
42
- h3 {
43
- font-size: 100%;
44
- margin-top: 1ex;
45
- font-weight: normal;
46
- }
44
+ h3 {
45
+ font-size: 100%;
46
+ margin-top: 1ex;
47
+ font-weight: normal;
48
+ }
47
49
 
48
50
  form {
49
51
  opacity: .5;
@@ -52,35 +54,33 @@ form {
52
54
  left: 42px;
53
55
  }
54
56
 
55
- form:hover {
56
- opacity: 1;
57
- }
58
-
59
- input {
60
- font-size: 1em;
61
- color: inherit;
62
- text-decoration: none;
63
- padding: .2em .3em;
64
- background: #222;
65
- color: #aaa;
66
- -webkit-border-radius: .4em;
67
- -moz-border-radius: .4em;
68
- -o-border-radius: .4em;
69
- border-radius: .4em;
70
- border: .1em solid #222;
71
- cursor: pointer;
72
- width: 2em;
73
- height: 2em;
74
-
75
- }
57
+ form:hover {
58
+ opacity: 1;
59
+ }
76
60
 
77
- input:hover {
78
- border-color: inherit;
79
- }
61
+ input {
62
+ font-size: 1em;
63
+ color: inherit;
64
+ text-decoration: none;
65
+ padding: .2em .3em;
66
+ background: #222;
67
+ color: #aaa;
68
+ -webkit-border-radius: .4em;
69
+ -moz-border-radius: .4em;
70
+ -o-border-radius: .4em;
71
+ border-radius: .4em;
72
+ border: .1em solid #222;
73
+ cursor: pointer;
74
+ width: 2em;
75
+ height: 2em;
76
+ }
80
77
 
81
- @media (max-width:800px) {
82
- input {
83
- font-size: 2em;
84
- }
85
- }
78
+ input:hover {
79
+ border-color: inherit;
80
+ }
86
81
 
82
+ @media (max-width:800px) {
83
+ input {
84
+ font-size: 2em;
85
+ }
86
+ }
@@ -1,3 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Module Sonice
1
4
  module Sonice
2
- VERSION = "2.0.0"
5
+ VERSION = "2.2.1"
3
6
  end
@@ -0,0 +1,81 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>
5
+ <% if !@artist && !@title %>
6
+ So Nice ♫
7
+ <% else %>
8
+ <%= [@artist, @title].compact.join(" — ") %>
9
+ <% end %>
10
+ </title>
11
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
12
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
13
+ <link rel="stylesheet" href="/stylesheet.css" />
14
+ </head>
15
+ <body>
16
+ <h1 id="title"><%= @title %></h1>
17
+ <h2 id="artist"><%= @artist %></h2>
18
+ <h3 id="album"><%= @album %></h3>
19
+
20
+ <h1 style="display:none" data-sonice-hide-if-connected>Connecting…</h1>
21
+
22
+ <form method="post" action="player" data-sonice-show-if-connected>
23
+ <input name="_method" type="hidden" value="put">
24
+ <% if settings.controls %>
25
+ <input
26
+ type="button"
27
+ value="▶"
28
+ id="playpause"
29
+ name="playpause"
30
+ title="Play/Pause"
31
+ data-key-name="space"
32
+ data-key=" "
33
+ />
34
+ <input
35
+ type="button"
36
+ value="←"
37
+ id="prev"
38
+ name="prev"
39
+ title="Previous"
40
+ data-key="p"
41
+ />
42
+ <input
43
+ type="button"
44
+ value="→"
45
+ id="next"
46
+ name="next"
47
+ title="Next"
48
+ data-key="n"
49
+ />
50
+ <input
51
+ type="button"
52
+ value="♪"
53
+ id="voldown"
54
+ name="voldown"
55
+ title="Quieter"
56
+ data-key="-"
57
+ />
58
+ <input
59
+ type="button"
60
+ value="♫"
61
+ id="volup"
62
+ name="volup"
63
+ title="Louder"
64
+ data-key="+"
65
+ />
66
+ <% end %>
67
+ <% if settings.voting %>
68
+ <input
69
+ type="button"
70
+ value="↡"
71
+ id="vote"
72
+ name="vote"
73
+ title="Vote to Skip"
74
+ data-key="s"
75
+ />
76
+ <% end %>
77
+ </form>
78
+ <script src="/jquery.min.js"></script>
79
+ <script src="/script.js"></script>
80
+ </body>
81
+ </html>
@@ -1,27 +1,31 @@
1
- # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.push File.expand_path('lib', __dir__)
3
4
  require "sonice/version"
4
5
 
5
6
  Gem::Specification.new do |s|
6
- s.name = "sonice"
7
- s.version = Sonice::VERSION
8
- s.platform = Gem::Platform::RUBY
9
- s.authors = ["Sunny Ripert"]
10
- s.email = ["sunny@sunfox.org"]
11
- s.homepage = "http://github.com/sunny/so-nice"
12
- s.summary = %q{Web interface to control your current music player}
13
- s.description = %q{Small Web interface to control iTunes, Spotify, Rdio, MPD, Rhythmbox, Amarok and XMMS2. ♫}
14
- s.license = 'WTFPL'
7
+ s.name = "sonice"
8
+ s.version = Sonice::VERSION
9
+ s.platform = Gem::Platform::RUBY
10
+ s.authors = ["Sunny Ripert"]
11
+ s.email = ["sunny@sunfox.org"]
12
+ s.homepage = "http://github.com/sunny/so-nice"
13
+ s.summary = "Web interface to control your current music player"
14
+ s.description =
15
+ "Small Web interface to control iTunes, Spotify, Rdio, MPD, Rhythmbox, " \
16
+ "Amarok and XMMS2. ♫"
17
+ s.license = "WTFPL"
15
18
 
16
- s.files = `git ls-files`.split("\n")
17
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
19
  s.require_paths = ["lib"]
20
+ s.files = `git ls-files`.split("\n")
21
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
22
+ s.executables = ["sonice"]
20
23
 
21
- s.add_runtime_dependency 'anyplayer', '> 1.1.1'
24
+ s.add_runtime_dependency 'anyplayer', '>= 1.2.1'
22
25
  s.add_runtime_dependency 'sinatra'
23
- s.add_runtime_dependency 'haml'
26
+ s.add_runtime_dependency 'webrick'
24
27
  s.add_runtime_dependency 'xml-simple'
25
- s.add_runtime_dependency 'thin'
26
- s.add_development_dependency 'rack'
28
+
29
+ s.add_development_dependency 'rake'
30
+ s.add_development_dependency 'rubocop'
27
31
  end
metadata CHANGED
@@ -1,110 +1,97 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sonice
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
5
- prerelease:
4
+ version: 2.2.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Sunny Ripert
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-12-18 00:00:00.000000000 Z
11
+ date: 2020-12-19 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: anyplayer
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>'
17
+ - - ">="
20
18
  - !ruby/object:Gem::Version
21
- version: 1.1.1
19
+ version: 1.2.1
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>'
24
+ - - ">="
28
25
  - !ruby/object:Gem::Version
29
- version: 1.1.1
26
+ version: 1.2.1
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: sinatra
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - ">="
36
32
  - !ruby/object:Gem::Version
37
33
  version: '0'
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - ">="
44
39
  - !ruby/object:Gem::Version
45
40
  version: '0'
46
41
  - !ruby/object:Gem::Dependency
47
- name: haml
42
+ name: webrick
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - ">="
52
46
  - !ruby/object:Gem::Version
53
47
  version: '0'
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ! '>='
52
+ - - ">="
60
53
  - !ruby/object:Gem::Version
61
54
  version: '0'
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: xml-simple
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
- - - ! '>='
59
+ - - ">="
68
60
  - !ruby/object:Gem::Version
69
61
  version: '0'
70
62
  type: :runtime
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
- - - ! '>='
66
+ - - ">="
76
67
  - !ruby/object:Gem::Version
77
68
  version: '0'
78
69
  - !ruby/object:Gem::Dependency
79
- name: thin
70
+ name: rake
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
- - - ! '>='
73
+ - - ">="
84
74
  - !ruby/object:Gem::Version
85
75
  version: '0'
86
- type: :runtime
76
+ type: :development
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
- - - ! '>='
80
+ - - ">="
92
81
  - !ruby/object:Gem::Version
93
82
  version: '0'
94
83
  - !ruby/object:Gem::Dependency
95
- name: rack
84
+ name: rubocop
96
85
  requirement: !ruby/object:Gem::Requirement
97
- none: false
98
86
  requirements:
99
- - - ! '>='
87
+ - - ">="
100
88
  - !ruby/object:Gem::Version
101
89
  version: '0'
102
90
  type: :development
103
91
  prerelease: false
104
92
  version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
93
  requirements:
107
- - - ! '>='
94
+ - - ">="
108
95
  - !ruby/object:Gem::Version
109
96
  version: '0'
110
97
  description: Small Web interface to control iTunes, Spotify, Rdio, MPD, Rhythmbox,
@@ -116,46 +103,50 @@ executables:
116
103
  extensions: []
117
104
  extra_rdoc_files: []
118
105
  files:
119
- - .gitignore
106
+ - ".gitignore"
107
+ - ".jshintrc"
108
+ - ".rubocop.yml"
109
+ - ".ruby-version"
110
+ - CHANGELOG.md
120
111
  - Gemfile
121
112
  - Gemfile.lock
122
113
  - README.md
123
114
  - Rakefile
115
+ - bin/rake
124
116
  - bin/sonice
125
117
  - config.ru
126
118
  - lib/sonice.rb
127
119
  - lib/sonice/app.rb
128
120
  - lib/sonice/command_line.rb
121
+ - lib/sonice/noplayer.rb
129
122
  - lib/sonice/public/favicon.ico
130
123
  - lib/sonice/public/jquery.min.js
131
124
  - lib/sonice/public/script.js
132
125
  - lib/sonice/public/stylesheet.css
133
126
  - lib/sonice/version.rb
134
- - lib/sonice/views/index.haml
127
+ - lib/sonice/views/index.erb
135
128
  - sonice.gemspec
136
129
  homepage: http://github.com/sunny/so-nice
137
130
  licenses:
138
131
  - WTFPL
132
+ metadata: {}
139
133
  post_install_message:
140
134
  rdoc_options: []
141
135
  require_paths:
142
136
  - lib
143
137
  required_ruby_version: !ruby/object:Gem::Requirement
144
- none: false
145
138
  requirements:
146
- - - ! '>='
139
+ - - ">="
147
140
  - !ruby/object:Gem::Version
148
141
  version: '0'
149
142
  required_rubygems_version: !ruby/object:Gem::Requirement
150
- none: false
151
143
  requirements:
152
- - - ! '>='
144
+ - - ">="
153
145
  - !ruby/object:Gem::Version
154
146
  version: '0'
155
147
  requirements: []
156
- rubyforge_project:
157
- rubygems_version: 1.8.23
148
+ rubygems_version: 3.1.2
158
149
  signing_key:
159
- specification_version: 3
150
+ specification_version: 4
160
151
  summary: Web interface to control your current music player
161
152
  test_files: []
@@ -1,31 +0,0 @@
1
- !!! 5
2
- %html
3
- %head
4
- %title
5
- - if !@artist && !@title
6
- So nice
7
- - else
8
- = [@artist, @title].compact.join(" — ")
9
- %meta{'http-equiv' => 'Content-Type', :content => 'text/html; charset=utf-8'}
10
- %meta{:name => 'viewport', :content => 'width=device-width, initial-scale=1.0' }
11
- %link{:rel => 'stylesheet', :href => '/stylesheet.css'}
12
-
13
- %body{:style => @image_uri ? "background-image:url(#{@image_uri})" : nil }
14
- %h1#title= @title
15
- %h2#artist= @artist
16
- %h3#album= @album
17
-
18
- %form{:method => 'post', :action => 'player'}
19
- %input{:type => "hidden", :name => "_method", :value => "put"}
20
- - if settings.controls
21
- %input#playpause{:type=>'button', :value=>'▸', :name=>'playpause', :title=>"Play/Pause", :'data-key'=>" ", :'data-key-name'=>"space"}
22
- %input#prev{ :type=>'button', :value=>'←', :name=>'prev', :title=>"Previous", :'data-key'=>"p"}
23
- %input#next{ :type=>'button', :value=>'→', :name=>'next', :title=>"Next", :'data-key'=>"n"}
24
- %input#voldown{ :type=>'button', :value=>'♪', :name=>'voldown', :title=>"Quieter", :'data-key'=>"-"}
25
- %input#volup{ :type=>'button', :value=>'♫', :name=>'volup', :title=>"Louder", :'data-key'=>"+"}
26
- - if settings.voting
27
- %input#vote{ :type=>'button', :value=>'↡', :name=>'vote', :title=>"Vote to Skip", :'data-key' => "s" }
28
-
29
- %script{:src => '/jquery.min.js'}
30
- %script{:src => '/script.js'}
31
-