sonice 2.0.0 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
-