gnome-wallpaper-changer 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +55 -0
- data/Rakefile +2 -0
- data/bin/gnome-wallpaper-changer +4 -0
- data/gnome-wallpaper-changer.gemspec +23 -0
- data/gnome-wallpaper-changer.sublime-project +8 -0
- data/lib/gnome-wallpaper-changer.rb +27 -0
- data/lib/gnome-wallpaper-changer/configuration.rb +200 -0
- data/lib/gnome-wallpaper-changer/controller.rb +147 -0
- data/lib/gnome-wallpaper-changer/reloader.rb +16 -0
- data/lib/gnome-wallpaper-changer/resizer.rb +30 -0
- data/lib/gnome-wallpaper-changer/runner.rb +108 -0
- data/lib/gnome-wallpaper-changer/updater.rb +86 -0
- data/lib/gnome-wallpaper-changer/version.rb +7 -0
- data/public/javascript/jquery-1.7.2.min.js +4 -0
- data/public/javascript/jquery-ui-1.8.21.custom.min.js +17 -0
- data/public/javascript/jquery.color.js +667 -0
- data/public/javascript/updater.js +211 -0
- data/public/stylesheets/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/public/stylesheets/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/public/stylesheets/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/public/stylesheets/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/public/stylesheets/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/public/stylesheets/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/public/stylesheets/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/public/stylesheets/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/public/stylesheets/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/public/stylesheets/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/public/stylesheets/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/public/stylesheets/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/public/stylesheets/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/public/stylesheets/smoothness/jquery-ui-1.8.21.custom.css +339 -0
- data/public/stylesheets/updater.css +92 -0
- data/views/index.haml +40 -0
- metadata +162 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Valeri Sokolov
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# Gnome::Wallpaper::Changer
|
2
|
+
|
3
|
+
A utility to periodically rotate the wallpaper in Gnome.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
$ gem install gnome-wallpaper-changer
|
8
|
+
|
9
|
+
### Prerequisites
|
10
|
+
|
11
|
+
* Ruby 1.9.3, properly setup to build native gems
|
12
|
+
* libgd2
|
13
|
+
|
14
|
+
## Usage
|
15
|
+
|
16
|
+
GWChanger runs as a daemon. It has a built-in web server providing the configuration interface.
|
17
|
+
|
18
|
+
After installation, run:
|
19
|
+
|
20
|
+
gnome-wallpaper-changer
|
21
|
+
|
22
|
+
Then go to http://localhost:12345.
|
23
|
+
You can override the port using the `--port` option; this setting will be preserved for future runs.
|
24
|
+
|
25
|
+
The wallpaper rotation will be initially disabled; set the interval to a non-zero value to enable. Double-click an image to use it immediately.
|
26
|
+
|
27
|
+
GWChanger looks for wallpaper images in several directories; the default ones are `/usr/share/backgrounds` and `~/Pictures`.
|
28
|
+
You can add or remove them or selectively exclude specific files.
|
29
|
+
|
30
|
+
You can set GWChanger to run automatically at login; this is disabled by default.
|
31
|
+
|
32
|
+
If something goes wrong, you can reset your configuration and start from scratch by running:
|
33
|
+
|
34
|
+
gnome-wallpaper-changer --reset
|
35
|
+
|
36
|
+
To stop the daemon, run:
|
37
|
+
|
38
|
+
gnome-wallpaper-changer --kill
|
39
|
+
|
40
|
+
## Known issues and limitations
|
41
|
+
|
42
|
+
* Chrome sometimes mixes up the image previews, apparently due to its caching strategy.
|
43
|
+
* Directories are not scanned recursively.
|
44
|
+
|
45
|
+
### Ruby managers and autostart
|
46
|
+
|
47
|
+
Multiple Ruby managers, such as RVM, heavily modify the environment in order to work. This may prevent the autostarted script from locating the correct Ruby and installed gems. GWChanger will detect RVM and try to generate a wrapper with a fixed environment, but alternative managers are not supported at this point.
|
48
|
+
|
49
|
+
## Contributing
|
50
|
+
|
51
|
+
1. Fork it
|
52
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
53
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
54
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
55
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/gnome-wallpaper-changer/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Valeri Sokolov"]
|
6
|
+
gem.email = ["ulfurinn@ulfurinn.net"]
|
7
|
+
gem.description = %q{A wallpaper rotation daemon with a browser-based interface.}
|
8
|
+
gem.summary = %q{A wallpaper rotation daemon with a browser-based interface.}
|
9
|
+
gem.homepage = "https://github.com/ulfurinn/gnome-wallpaper-changer"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "gnome-wallpaper-changer"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = Gnome::Wallpaper::Changer::VERSION
|
17
|
+
|
18
|
+
gem.add_dependency "thin"
|
19
|
+
gem.add_dependency "sinatra"
|
20
|
+
gem.add_dependency "haml"
|
21
|
+
gem.add_dependency "json"
|
22
|
+
gem.add_dependency "fastimage_resize"
|
23
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
|
3
|
+
module Gnome
|
4
|
+
module Wallpaper
|
5
|
+
module Changer
|
6
|
+
|
7
|
+
CONFIG_DIR = "#{ENV['HOME']}/.config/gnome-wallpaper-changer"
|
8
|
+
|
9
|
+
CONFIG_FILE = "#{CONFIG_DIR}/config.yml"
|
10
|
+
THUMB_DIR = "#{CONFIG_DIR}/thumbs"
|
11
|
+
|
12
|
+
PID_FILE = "#{CONFIG_DIR}/updater.pid"
|
13
|
+
LOG_FILE = "#{CONFIG_DIR}/updater.log"
|
14
|
+
|
15
|
+
AUTOSTART = "#{ENV['HOME']}/.config/autostart/gnome-wallpaper-changer.desktop"
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
require "gnome-wallpaper-changer/version"
|
22
|
+
require "gnome-wallpaper-changer/reloader"
|
23
|
+
require "gnome-wallpaper-changer/configuration"
|
24
|
+
require "gnome-wallpaper-changer/controller"
|
25
|
+
require "gnome-wallpaper-changer/updater"
|
26
|
+
require "gnome-wallpaper-changer/resizer"
|
27
|
+
require "gnome-wallpaper-changer/runner"
|
@@ -0,0 +1,200 @@
|
|
1
|
+
require "yaml"
|
2
|
+
|
3
|
+
module Gnome::Wallpaper::Changer
|
4
|
+
class Configuration
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def self.autosaving *attrs
|
11
|
+
attrs.each do |attribute|
|
12
|
+
|
13
|
+
define_method "autosaving_#{attribute}_set".to_sym do |value|
|
14
|
+
self.send "real_#{attribute}_set".to_sym, value
|
15
|
+
self.save!
|
16
|
+
end
|
17
|
+
|
18
|
+
alias_method "real_#{attribute}_set".to_sym, "#{attribute}=".to_sym
|
19
|
+
alias_method "#{attribute}=".to_sym, "autosaving_#{attribute}_set".to_sym
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
public
|
25
|
+
|
26
|
+
attr_accessor :interval, :port, :active, :folders, :files
|
27
|
+
|
28
|
+
def interval= value
|
29
|
+
@interval = if value < 60
|
30
|
+
60
|
31
|
+
else
|
32
|
+
value
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
autosaving :interval, :port, :active, :folders, :files
|
37
|
+
alias_method :active?, :active
|
38
|
+
|
39
|
+
def default_config
|
40
|
+
{
|
41
|
+
interval: 60 * 10,
|
42
|
+
port: 12345,
|
43
|
+
active: false,
|
44
|
+
folders: [ {
|
45
|
+
path: ENV['HOME'] + '/Pictures',
|
46
|
+
excluded: []
|
47
|
+
}, {
|
48
|
+
path: '/usr/share/backgrounds',
|
49
|
+
excluded: []
|
50
|
+
}
|
51
|
+
],
|
52
|
+
files: [ ]
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
def current_config
|
57
|
+
{
|
58
|
+
version: VERSION,
|
59
|
+
port: self.port,
|
60
|
+
interval: self.interval,
|
61
|
+
active: self.active?,
|
62
|
+
folders: self.folders,
|
63
|
+
files: self.files
|
64
|
+
}
|
65
|
+
end
|
66
|
+
|
67
|
+
def reset!
|
68
|
+
if File.exists?( CONFIG_FILE )
|
69
|
+
FileUtils.rm CONFIG_FILE
|
70
|
+
end
|
71
|
+
uninstall_autostart!
|
72
|
+
end
|
73
|
+
|
74
|
+
def load
|
75
|
+
|
76
|
+
unless Dir.exists?( CONFIG_DIR )
|
77
|
+
FileUtils.mkdir_p CONFIG_DIR
|
78
|
+
end
|
79
|
+
|
80
|
+
config = if File.exists?( CONFIG_FILE )
|
81
|
+
YAML.load File.read( CONFIG_FILE )
|
82
|
+
else
|
83
|
+
default_config
|
84
|
+
end
|
85
|
+
|
86
|
+
default_config.keys.each do |key|
|
87
|
+
self.send "#{key}=".to_sym, config[key]
|
88
|
+
end
|
89
|
+
|
90
|
+
save unless File.exists?( CONFIG_FILE )
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
def save!
|
95
|
+
File.open CONFIG_FILE, "w" do |io|
|
96
|
+
io.write current_config.to_yaml
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def include_file folder, file
|
101
|
+
# => basic sanity check...
|
102
|
+
if File.dirname(file) == folder
|
103
|
+
folder = folders.find { |f| f[:path] == folder }
|
104
|
+
return false unless folder
|
105
|
+
folder[:excluded].delete file
|
106
|
+
save!
|
107
|
+
true
|
108
|
+
else
|
109
|
+
false
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def include_all folder
|
114
|
+
folder = folders.find { |f| f[:path] == folder }
|
115
|
+
if folder
|
116
|
+
folder[:excluded] = []
|
117
|
+
save!
|
118
|
+
true
|
119
|
+
else
|
120
|
+
false
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def exclude_file folder, file
|
125
|
+
# => basic sanity check...
|
126
|
+
if File.dirname(file) == folder
|
127
|
+
folder = folders.find { |f| f[:path] == folder }
|
128
|
+
return false unless folder
|
129
|
+
folder[:excluded] << file unless folder[:excluded].include?( file )
|
130
|
+
save!
|
131
|
+
true
|
132
|
+
else
|
133
|
+
false
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def exclude_all folder
|
138
|
+
folder = folders.find { |f| f[:path] == folder }
|
139
|
+
if folder
|
140
|
+
folder[:excluded] = Updater.get_files_in_folder folder[:path]
|
141
|
+
save!
|
142
|
+
true
|
143
|
+
else
|
144
|
+
false
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def add_folder folder
|
149
|
+
if folders.find{ |f| f[:path] == folder }
|
150
|
+
false
|
151
|
+
else
|
152
|
+
folders << { path: folder, excluded: [] }
|
153
|
+
save!
|
154
|
+
true
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def remove_folder folder
|
159
|
+
folders.reject! { |f| f[:path] == folder }
|
160
|
+
save!
|
161
|
+
end
|
162
|
+
|
163
|
+
def install_autostart!
|
164
|
+
bin = begin
|
165
|
+
require "rvm"
|
166
|
+
wrapper = RVM.path + "/bin/" + RVM.current.environment_name + "_gnome-wallpaper-changer"
|
167
|
+
if !File.exists? wrapper
|
168
|
+
RVM.current.wrapper RVM.current.environment_name, RVM.current.environment_name, "gnome-wallpaper-changer"
|
169
|
+
end
|
170
|
+
wrapper
|
171
|
+
rescue
|
172
|
+
Gem.bindir( Gem.dir ) + '/gnome-wallpaper-changer'
|
173
|
+
end
|
174
|
+
puts "Detected bin: #{bin}"
|
175
|
+
File.open AUTOSTART, "w" do |io|
|
176
|
+
io.puts "[Desktop Entry]"
|
177
|
+
io.puts "Type=Application"
|
178
|
+
io.puts "Terminal=false"
|
179
|
+
io.puts "Name=Wallpaper Changer"
|
180
|
+
io.puts "Comment=Periodically changes the Gnome wallpaper"
|
181
|
+
io.puts "Exec=#{bin} --autostart"
|
182
|
+
end
|
183
|
+
rescue Gem::GemNotFoundException => e
|
184
|
+
puts "Cannot activate autostart with a development version"
|
185
|
+
end
|
186
|
+
|
187
|
+
def uninstall_autostart!
|
188
|
+
FileUtils.rm AUTOSTART if autostart_installed?
|
189
|
+
end
|
190
|
+
|
191
|
+
def autostart_installed?
|
192
|
+
File.exists? AUTOSTART
|
193
|
+
end
|
194
|
+
|
195
|
+
end
|
196
|
+
|
197
|
+
extend ClassMethods
|
198
|
+
|
199
|
+
end
|
200
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
require "sinatra/base"
|
2
|
+
require "json"
|
3
|
+
|
4
|
+
module Gnome::Wallpaper::Changer
|
5
|
+
|
6
|
+
class Controller < Sinatra::Base
|
7
|
+
|
8
|
+
def self.main_file
|
9
|
+
__FILE__
|
10
|
+
end
|
11
|
+
|
12
|
+
def sanitize_path folder
|
13
|
+
if folder.empty?
|
14
|
+
return nil
|
15
|
+
end
|
16
|
+
|
17
|
+
folder_pn = Pathname.new folder
|
18
|
+
|
19
|
+
if folder_pn.relative?
|
20
|
+
return nil
|
21
|
+
end
|
22
|
+
|
23
|
+
folder_pn = folder_pn.expand_path
|
24
|
+
|
25
|
+
if !folder_pn.exist?
|
26
|
+
return nil
|
27
|
+
end
|
28
|
+
|
29
|
+
folder_pn.to_s
|
30
|
+
end
|
31
|
+
|
32
|
+
set :root, File.join(File.dirname(main_file), "..", "..")
|
33
|
+
set :haml, :format => :html5
|
34
|
+
|
35
|
+
get '/' do
|
36
|
+
haml :index
|
37
|
+
end
|
38
|
+
|
39
|
+
get '/autostart' do
|
40
|
+
content_type :json
|
41
|
+
{ enabled: Configuration.autostart_installed? }.to_json
|
42
|
+
end
|
43
|
+
|
44
|
+
post '/autostart' do
|
45
|
+
if params[:enable] == "true"
|
46
|
+
Configuration.install_autostart!
|
47
|
+
else
|
48
|
+
Configuration.uninstall_autostart!
|
49
|
+
end
|
50
|
+
content_type :json
|
51
|
+
{ enabled: Configuration.autostart_installed? }.to_json
|
52
|
+
end
|
53
|
+
|
54
|
+
get '/interval' do
|
55
|
+
content_type :json
|
56
|
+
{ interval: Configuration.active? ? Configuration.interval / 60 : 0 }.to_json
|
57
|
+
end
|
58
|
+
|
59
|
+
post '/interval' do
|
60
|
+
interval = params[:interval].to_i
|
61
|
+
if interval > 0
|
62
|
+
Configuration.active = true
|
63
|
+
Configuration.interval = interval * 60 rescue nil
|
64
|
+
else
|
65
|
+
Configuration.active = false
|
66
|
+
end
|
67
|
+
Updater.reschedule!
|
68
|
+
|
69
|
+
content_type :json
|
70
|
+
{ interval: Configuration.active? ? Configuration.interval / 60 : 0 }.to_json
|
71
|
+
end
|
72
|
+
|
73
|
+
post '/include' do
|
74
|
+
result = if params[:file]
|
75
|
+
Configuration.include_file params[:folder], params[:file]
|
76
|
+
else
|
77
|
+
Configuration.include_all params[:folder]
|
78
|
+
end
|
79
|
+
content_type :json
|
80
|
+
{ result: result }.to_json
|
81
|
+
end
|
82
|
+
|
83
|
+
post '/exclude' do
|
84
|
+
result = if params[:file]
|
85
|
+
Configuration.exclude_file params[:folder], params[:file]
|
86
|
+
else
|
87
|
+
Configuration.exclude_all params[:folder]
|
88
|
+
end
|
89
|
+
content_type :json
|
90
|
+
{ result: result }.to_json
|
91
|
+
end
|
92
|
+
|
93
|
+
post '/add' do
|
94
|
+
|
95
|
+
folder = sanitize_path params[:folder]
|
96
|
+
return nil.to_json if folder.nil?
|
97
|
+
|
98
|
+
result = Configuration.add_folder folder
|
99
|
+
content_type :json
|
100
|
+
if result
|
101
|
+
Updater.get_expanded_configuration(params[:folder])
|
102
|
+
else
|
103
|
+
nil
|
104
|
+
end.to_json
|
105
|
+
end
|
106
|
+
|
107
|
+
post '/remove' do
|
108
|
+
Configuration.remove_folder params[:folder]
|
109
|
+
''
|
110
|
+
end
|
111
|
+
|
112
|
+
post '/change' do
|
113
|
+
path = params[:file]
|
114
|
+
if Updater.known_file? path
|
115
|
+
Updater.force_update path
|
116
|
+
end
|
117
|
+
""
|
118
|
+
end
|
119
|
+
|
120
|
+
get '/wallpapers' do
|
121
|
+
content_type :json
|
122
|
+
Updater.get_expanded_configuration(params[:folder]).to_json
|
123
|
+
end
|
124
|
+
|
125
|
+
get '/file' do
|
126
|
+
path = params[:path]
|
127
|
+
if Updater.known_file? path
|
128
|
+
if thumb = Resizer.resize(path)
|
129
|
+
send_file thumb
|
130
|
+
else
|
131
|
+
500
|
132
|
+
end
|
133
|
+
else
|
134
|
+
403
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
get '/folder-suggest' do
|
139
|
+
term = params[:term]
|
140
|
+
lookup_dir = term.gsub /[^\/]+$/, ""
|
141
|
+
partial = term[ ( term.rindex('/') + 1 )..-1 ]
|
142
|
+
Pathname.new(lookup_dir).children.select { |child| child.directory? && child.basename.to_s.index( partial ) == 0 && child.basename.to_s[0] != '.' }.map(&:to_s).sort_by(&:downcase).to_json
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|