desktop 1.0.0

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
+ SHA1:
3
+ metadata.gz: 28652a5faa1e08cb547b3f1cd0128c8e7c331df7
4
+ data.tar.gz: e36b75e377891d7517e027cd7766e73b877245b3
5
+ SHA512:
6
+ metadata.gz: 36f705143fce3e7aaa4f434e7cbdbc0351a1341973ebe3a697684426779d5bd98772d3222931e508b599bf87b397dfed9026185e8f5758e3e4f04a46068c3321
7
+ data.tar.gz: 9efb951a5cd055b0b7ee9311be4d815aff9ce5ab1bbccb0dee923e21fec4df5198728a25d0fb4e92da617c25bd9c0736fff28189ab95d2b64ad6762f5d101b71
@@ -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
@@ -0,0 +1,6 @@
1
+ # Changelog
2
+
3
+ ##v1.0.0
4
+ *2014-06-01*
5
+
6
+ - Initial release
@@ -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
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in desktop.gemspec
4
+ gemspec
@@ -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.
@@ -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)
@@ -0,0 +1,9 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ desc 'Run all tests'
4
+ task :test do
5
+ $LOAD_PATH.unshift 'test'
6
+ Dir.glob('./test/**/*_test.rb') { |f| require f }
7
+ end
8
+
9
+ task default: :test
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'desktop'
4
+
5
+ if ARGV.size == 1 && !%w[set help].include?(ARGV.first)
6
+ ARGV.unshift('set')
7
+ end
8
+
9
+ Desktop::CLI.start ARGV
@@ -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
Binary file
@@ -0,0 +1,5 @@
1
+ require 'desktop/cli'
2
+ require 'desktop/local_image'
3
+ require 'desktop/osx'
4
+ require 'desktop/version'
5
+ require 'desktop/web_image'
@@ -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
@@ -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
@@ -0,0 +1,17 @@
1
+ module Desktop
2
+ class Image
3
+ attr_reader :path
4
+
5
+ def initialize(path)
6
+ @path = path
7
+ end
8
+
9
+ def filename
10
+ File.basename path
11
+ end
12
+
13
+ def data
14
+ raise NotImplementedError
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,9 @@
1
+ require 'desktop/image'
2
+
3
+ module Desktop
4
+ class LocalImage < Image
5
+ def data
6
+ File.read path
7
+ end
8
+ end
9
+ end
@@ -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
@@ -0,0 +1,3 @@
1
+ module Desktop
2
+ VERSION = '1.0.0'
3
+ end
@@ -0,0 +1,10 @@
1
+ require 'desktop/http'
2
+ require 'desktop/image'
3
+
4
+ module Desktop
5
+ class WebImage < Image
6
+ def data
7
+ HTTP.connection.get(path).body
8
+ end
9
+ end
10
+ end