desktop 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/CHANGELOG.md +6 -0
- data/CONTRIBUTING.md +13 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +86 -0
- data/Rakefile +9 -0
- data/bin/desktop +9 -0
- data/desktop.gemspec +30 -0
- data/img/example.gif +0 -0
- data/lib/desktop.rb +5 -0
- data/lib/desktop/cli.rb +76 -0
- data/lib/desktop/http.rb +16 -0
- data/lib/desktop/image.rb +17 -0
- data/lib/desktop/local_image.rb +9 -0
- data/lib/desktop/osx.rb +79 -0
- data/lib/desktop/version.rb +3 -0
- data/lib/desktop/web_image.rb +10 -0
- data/test/desktop/cli_test.rb +42 -0
- data/test/desktop/http_test.rb +16 -0
- data/test/desktop/image_test.rb +21 -0
- data/test/desktop/local_image_test.rb +18 -0
- data/test/desktop/osx_test.rb +38 -0
- data/test/desktop/web_image_test.rb +14 -0
- data/test/fixtures/web_image_data.yml +1668 -0
- data/test/test_helper.rb +13 -0
- metadata +191 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 28652a5faa1e08cb547b3f1cd0128c8e7c331df7
|
4
|
+
data.tar.gz: e36b75e377891d7517e027cd7766e73b877245b3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 36f705143fce3e7aaa4f434e7cbdbc0351a1341973ebe3a697684426779d5bd98772d3222931e508b599bf87b397dfed9026185e8f5758e3e4f04a46068c3321
|
7
|
+
data.tar.gz: 9efb951a5cd055b0b7ee9311be4d815aff9ce5ab1bbccb0dee923e21fec4df5198728a25d0fb4e92da617c25bd9c0736fff28189ab95d2b64ad6762f5d101b71
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
data/CHANGELOG.md
ADDED
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# Contributing
|
2
|
+
|
3
|
+
Want to contribute? Awesome! Thank you so much.
|
4
|
+
|
5
|
+
## How?
|
6
|
+
|
7
|
+
1. [Fork it](https://help.github.com/articles/fork-a-repo)
|
8
|
+
2. Create a feature branch (`git checkout -b my-new-feature`)
|
9
|
+
3. Commit changes, **with tests** (`git commit -am 'Add some feature'`)
|
10
|
+
4. Run the tests (`rake test`)
|
11
|
+
5. Push to the branch (`git push origin my-new-feature`)
|
12
|
+
6. Create new [Pull
|
13
|
+
Request](https://help.github.com/articles/using-pull-requests)
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Chris Hunt
|
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,86 @@
|
|
1
|
+
# Desktop
|
2
|
+
|
3
|
+
### A decent way to change your desktop image.
|
4
|
+
|
5
|
+
Since the introduction of
|
6
|
+
[Spaces](http://en.wikipedia.org/wiki/Spaces_(software)) in Mac OS X, changing
|
7
|
+
the desktop image has been a chore for those of us who enjoy the same image on
|
8
|
+
all spaces and monitors; each has its own image that must be updated
|
9
|
+
individually. Lucky for you, a recent breakthrough in technology had made changing
|
10
|
+
your desktop **drag-n-drop easy**.
|
11
|
+
|
12
|
+
**desktop** lets us update the desktop image on every space and monitor *at the
|
13
|
+
same time* from the command line.
|
14
|
+
|
15
|
+
![](img/example.gif)
|
16
|
+
|
17
|
+
## Installation
|
18
|
+
|
19
|
+
**desktop** can be installed from [RubyGems](http://rubygems.org/gems/desktop).
|
20
|
+
|
21
|
+
```bash
|
22
|
+
$ gem install desktop
|
23
|
+
```
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
Usage can be seen from the command line:
|
28
|
+
|
29
|
+
```bash
|
30
|
+
$ desktop help
|
31
|
+
Commands:
|
32
|
+
desktop help [COMMAND] # Describe available commands or one specific command
|
33
|
+
desktop set IMAGE_PATH # Set all desktops to the image at IMAGE_PATH
|
34
|
+
```
|
35
|
+
|
36
|
+
Desktop images can be set using a file path:
|
37
|
+
|
38
|
+
```bash
|
39
|
+
$ desktop set /path/to/image.jpg
|
40
|
+
```
|
41
|
+
|
42
|
+
Or a web URL:
|
43
|
+
|
44
|
+
```bash
|
45
|
+
$ desktop set http://desktops.amazing/image.jpg
|
46
|
+
```
|
47
|
+
|
48
|
+
The `set` command is optional:
|
49
|
+
|
50
|
+
```bash
|
51
|
+
$ desktop /path/to/image.jpg
|
52
|
+
```
|
53
|
+
|
54
|
+
### Usage in your awesome app
|
55
|
+
|
56
|
+
Want to include the features of **desktop** in your awesome app? Please do!
|
57
|
+
|
58
|
+
Add the gem to your Gemfile:
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
gem 'desktop'
|
62
|
+
```
|
63
|
+
|
64
|
+
Require the library:
|
65
|
+
|
66
|
+
```ruby
|
67
|
+
require 'desktop'
|
68
|
+
```
|
69
|
+
|
70
|
+
And use the same CLI interface that you already know:
|
71
|
+
```ruby
|
72
|
+
Desktop::CLI.start %w[set path/to/image.jpg]
|
73
|
+
```
|
74
|
+
|
75
|
+
|
76
|
+
## Contributing
|
77
|
+
Please see the [Contributing
|
78
|
+
Document](https://github.com/chrishunt/desktop/blob/master/CONTRIBUTING.md)
|
79
|
+
|
80
|
+
## Changelog
|
81
|
+
Please see the [Changelog
|
82
|
+
Document](https://github.com/chrishunt/desktop/blob/master/CHANGELOG.md)
|
83
|
+
|
84
|
+
## License
|
85
|
+
Copyright (C) 2014 Chris Hunt, [MIT
|
86
|
+
License](https://github.com/chrishunt/desktop/blob/master/LICENSE.txt)
|
data/Rakefile
ADDED
data/bin/desktop
ADDED
data/desktop.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'desktop/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "desktop"
|
8
|
+
spec.version = Desktop::VERSION
|
9
|
+
spec.authors = ["Chris Hunt"]
|
10
|
+
spec.email = ["c@chrishunt.co"]
|
11
|
+
spec.summary = %q{A decent way to change your desktop image}
|
12
|
+
spec.description = %q{A decent way to change your desktop image}
|
13
|
+
spec.homepage = "https://github.com/chrishunt/desktop"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "faraday", "~> 0.9"
|
22
|
+
spec.add_dependency "thor", "~> 0.19"
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
25
|
+
spec.add_development_dependency "minitest", "~> 5.3"
|
26
|
+
spec.add_development_dependency "pry", "~> 0.9.12"
|
27
|
+
spec.add_development_dependency "rake", "~> 10.3"
|
28
|
+
spec.add_development_dependency "vcr", "~> 2.9"
|
29
|
+
spec.add_development_dependency "webmock", "~> 1.8"
|
30
|
+
end
|
data/img/example.gif
ADDED
Binary file
|
data/lib/desktop.rb
ADDED
data/lib/desktop/cli.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'desktop'
|
3
|
+
|
4
|
+
module Desktop
|
5
|
+
class CLI < Thor
|
6
|
+
desc 'set IMAGE_PATH', 'Set all desktops to the image at IMAGE_PATH'
|
7
|
+
long_desc <<-LONGDESC
|
8
|
+
`desktop set` will set the desktop image of all spaces on all monitors to
|
9
|
+
the image at `IMAGE_PATH`.
|
10
|
+
|
11
|
+
> $ desktop set /path/to/image.png
|
12
|
+
|
13
|
+
`IMAGE_PATH` can be a local file path or a URL.
|
14
|
+
|
15
|
+
> $ desktop set http://url.to/image.jpg
|
16
|
+
LONGDESC
|
17
|
+
option :default_image_path, :hide => true
|
18
|
+
option :skip_reload, :type => :boolean, :hide => true
|
19
|
+
def set(path, already_failed = false)
|
20
|
+
osx = OSX.new(options[:default_image_path], options[:skip_reload])
|
21
|
+
image = HTTP.uri?(path) ? WebImage.new(path) : LocalImage.new(path)
|
22
|
+
|
23
|
+
begin
|
24
|
+
osx.desktop_image = image
|
25
|
+
rescue OSX::DesktopImagePermissionsError => e
|
26
|
+
fail_with_permissions_error if already_failed
|
27
|
+
|
28
|
+
print_permissions_message
|
29
|
+
osx.update_desktop_image_permissions
|
30
|
+
puts
|
31
|
+
set path, true
|
32
|
+
rescue OSX::DesktopImageMissingError
|
33
|
+
fail_with_missing_image_error image
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def fail_with_permissions_error
|
40
|
+
print "Sorry, but I was unable to change your desktop image. "
|
41
|
+
puts "The permissions are still incorrect."
|
42
|
+
puts
|
43
|
+
puts "Did you type your password incorrectly?"
|
44
|
+
puts
|
45
|
+
print_issues_message
|
46
|
+
abort
|
47
|
+
end
|
48
|
+
|
49
|
+
def fail_with_missing_image_error(image)
|
50
|
+
puts "Sorry, but it looks like the image you provided does not exist:"
|
51
|
+
puts
|
52
|
+
puts image.path
|
53
|
+
puts
|
54
|
+
print_issues_message
|
55
|
+
abort
|
56
|
+
end
|
57
|
+
|
58
|
+
def print_permissions_message
|
59
|
+
print "It looks like this is the first time you've tried to change "
|
60
|
+
puts "your desktop."
|
61
|
+
puts
|
62
|
+
print "We need to make your desktop image writable before we can "
|
63
|
+
puts "change it. This only needs to be done once."
|
64
|
+
puts
|
65
|
+
puts "$ #{OSX.chown_command}"
|
66
|
+
puts "$ #{OSX.chmod_command}"
|
67
|
+
puts
|
68
|
+
end
|
69
|
+
|
70
|
+
def print_issues_message
|
71
|
+
puts "Please create an issue if you think this is my fault:"
|
72
|
+
puts
|
73
|
+
puts "https://github.com/chrishunt/desktop/issues/new"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/lib/desktop/http.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
module Desktop
|
5
|
+
class HTTP
|
6
|
+
def self.connection
|
7
|
+
Faraday
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.uri?(path)
|
11
|
+
%w[http https].include? URI.parse(path).scheme
|
12
|
+
rescue URI::BadURIError, URI::InvalidURIError
|
13
|
+
false
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/desktop/osx.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'sqlite3'
|
2
|
+
|
3
|
+
module Desktop
|
4
|
+
class OSX
|
5
|
+
attr_reader :desktop_image_path, :skip_reload
|
6
|
+
class DesktopImagePermissionsError < StandardError; end
|
7
|
+
class DesktopImageMissingError < StandardError; end
|
8
|
+
|
9
|
+
def self.desktop_image=(image)
|
10
|
+
self.new.desktop_image = image
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.update_desktop_image_permissions
|
14
|
+
self.new.update_desktop_image_permissions
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.chown_command
|
18
|
+
self.new.chown_command
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.chmod_command
|
22
|
+
self.new.chmod_command
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize(desktop_image_path = nil, skip_reload = false)
|
26
|
+
@skip_reload = skip_reload
|
27
|
+
@desktop_image_path = desktop_image_path || default_desktop_image_path
|
28
|
+
end
|
29
|
+
|
30
|
+
def desktop_image=(image)
|
31
|
+
write_default_desktop image
|
32
|
+
clear_custom_desktop_image
|
33
|
+
reload_desktop unless skip_reload
|
34
|
+
rescue Errno::EACCES => e
|
35
|
+
raise DesktopImagePermissionsError.new(e)
|
36
|
+
rescue Errno::ENOENT => e
|
37
|
+
raise DesktopImageMissingError.new(e)
|
38
|
+
end
|
39
|
+
|
40
|
+
def update_desktop_image_permissions
|
41
|
+
system(chown_command) && system(chmod_command)
|
42
|
+
end
|
43
|
+
|
44
|
+
def chown_command
|
45
|
+
"sudo chown root:staff #{desktop_image_path}"
|
46
|
+
end
|
47
|
+
|
48
|
+
def chmod_command
|
49
|
+
"sudo chmod 664 #{desktop_image_path}"
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def write_default_desktop(image)
|
55
|
+
File.open(desktop_image_path, 'w') do |desktop|
|
56
|
+
desktop.write image.data
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def clear_custom_desktop_image
|
61
|
+
db = SQLite3::Database.new(desktop_image_db_path)
|
62
|
+
db.execute 'DELETE FROM data'
|
63
|
+
db.execute 'VACUUM data'
|
64
|
+
db.close
|
65
|
+
end
|
66
|
+
|
67
|
+
def reload_desktop
|
68
|
+
system 'killall Dock'
|
69
|
+
end
|
70
|
+
|
71
|
+
def default_desktop_image_path
|
72
|
+
'/System/Library/CoreServices/DefaultDesktop.jpg'
|
73
|
+
end
|
74
|
+
|
75
|
+
def desktop_image_db_path
|
76
|
+
File.expand_path '~/Library/Application Support/Dock/desktoppicture.db'
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|