maid 0.1.0.beta.3 → 0.1.0.beta.4
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.
- data/.travis.yml +3 -0
- data/CONTRIBUTING.rdoc +15 -3
- data/Gemfile.lock +1 -1
- data/README.rdoc +6 -131
- data/TODO.rdoc +45 -0
- data/lib/maid/app.rb +21 -2
- data/lib/maid/maid.rb +1 -1
- data/lib/maid/rules.sample.rb +60 -0
- data/lib/maid/version.rb +1 -1
- data/script/micro-maid.sh +18 -0
- data/spec/lib/maid/app_spec.rb +10 -0
- data/spec/lib/maid/tools_spec.rb +2 -1
- metadata +8 -4
data/.travis.yml
ADDED
data/CONTRIBUTING.rdoc
CHANGED
@@ -1,12 +1,24 @@
|
|
1
1
|
= Contributing
|
2
2
|
|
3
|
-
|
3
|
+
Wow, you want to contribute? That's awesome! Thanks!
|
4
|
+
|
5
|
+
To make things easier on you, I've compiled some Notes and Guidelines.
|
4
6
|
|
5
7
|
== Notes
|
6
8
|
|
7
|
-
*
|
9
|
+
* This is a Ruby Gem, built using Bundler. For a walkthrough of how that works, see http://railscasts.com/episodes/245-new-gem-with-bundler.
|
10
|
+
* `rake install` builds and installs the gem, but you'll probably need to do `sudo rake install`. This lets you test the `maid` command.
|
8
11
|
* Keep in mind that the gemspec only looks at files in the VCS (git).
|
9
12
|
|
10
13
|
== Guidelines
|
11
14
|
|
12
|
-
*
|
15
|
+
* Looking for something to do? Anything in the TODO file is a good place to start.
|
16
|
+
* Whenever possible, retain compatibility with Ruby 1.8.7.
|
17
|
+
|
18
|
+
== Note on Patches/Pull Requests
|
19
|
+
|
20
|
+
* Fork the project.
|
21
|
+
* Make your feature addition or bug fix.
|
22
|
+
* Add tests for it. This is important so I don't break it in a future version unintentionally.
|
23
|
+
* Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
24
|
+
* Send me a pull request. Bonus points for topic branches.
|
data/Gemfile.lock
CHANGED
data/README.rdoc
CHANGED
@@ -10,6 +10,8 @@ Maid is inspired by the Mac OS X shareware program Hazel[http://www.noodlesoft.c
|
|
10
10
|
|
11
11
|
Your rules are defined in Ruby, so easy rules are easy and difficult rules are possible.
|
12
12
|
|
13
|
+
http://travis-ci.org/benjaminoakes/maid.png ({More info}[http://travis-ci.org/benjaminoakes/maid])
|
14
|
+
|
13
15
|
== Installation
|
14
16
|
|
15
17
|
Maid is currently in beta, but I encourage you to give it a try. I'm using it on several computers daily.
|
@@ -40,7 +42,7 @@ Maid rules are defined using Ruby, with some common operations made easier with
|
|
40
42
|
Maid.rules do
|
41
43
|
rule 'Old files downloaded while developing/testing' do
|
42
44
|
dir('~/Downloads/*').each do |path|
|
43
|
-
if downloaded_from(path).any? {|u| u.match 'http://localhost'} && 1.week.since?
|
45
|
+
if downloaded_from(path).any? {|u| u.match 'http://localhost'} && 1.week.since?(last_accessed(path))
|
44
46
|
trash(path)
|
45
47
|
end
|
46
48
|
end
|
@@ -92,138 +94,11 @@ Example for every day at 1am:
|
|
92
94
|
|
93
95
|
Both Mac OS X and Linux support callbacks when folders are changed, and that may be a forthcoming feature in Maid. That said, I find cron to take care of most of my needs.
|
94
96
|
|
95
|
-
== Sample
|
96
|
-
|
97
|
-
Here's a sampling from my <tt>~/.maid/rules.rb</tt> file to get you started:
|
98
|
-
|
99
|
-
software_archive_path = '~/Reference/Software/'
|
100
|
-
|
101
|
-
osx_app_extensions = %w[app dmg pkg wdgt]
|
102
|
-
osx_app_patterns = osx_app_extensions.map { |ext| (/\.#{ext}\/$/) }
|
103
|
-
linux_app_archive_path = "#{software_archive_path}/Linux/"
|
104
|
-
osx_app_archive_path = "#{software_archive_path}/Mac OS X/"
|
105
|
-
win_app_archive_path = "#{software_archive_path}/Windows XP/"
|
106
|
-
|
107
|
-
Maid.rules do
|
108
|
-
rule 'Files downloaded while developing' do
|
109
|
-
dir('~/Downloads/*').select do |path|
|
110
|
-
if downloaded_from(path).any? { |url| url.match(/^http:\/\/localhost:/) || url.match('staging.yourcompany.com') }
|
111
|
-
trash(path)
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
rule 'MP3s likely to be music' do
|
117
|
-
dir('~/Downloads/*.mp3').each do |path|
|
118
|
-
if duration_s(path) > 30.0
|
119
|
-
move(path, '~/Music/iTunes/iTunes Media/Automatically Add to iTunes/')
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
rule 'Accidentally downloaded HTML' do # this basically only happens to me on accident
|
125
|
-
dir('~/Downloads/*.html').each do |path|
|
126
|
-
trash(path)
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
rule 'Linux ISOs, etc' do
|
131
|
-
dir('~/Downloads/*.iso').each do |path|
|
132
|
-
move(path, software_archive_path)
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
rule 'Linux applications in Debian packages' do
|
137
|
-
dir('~/Downloads/*.deb').each do |path|
|
138
|
-
move(path, linux_app_archive_path)
|
139
|
-
end
|
140
|
-
end
|
97
|
+
== Sample
|
141
98
|
|
142
|
-
|
143
|
-
dir('~/Downloads/*.dmg').each do |path|
|
144
|
-
move(path, osx_app_archive_path)
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
rule 'Mac OS X applications in zip files' do
|
149
|
-
dir('~/Downloads/*.zip').select do |path|
|
150
|
-
candidates = zipfile_contents(path)
|
151
|
-
candidates.any? { |c| osx_app_patterns.any? { |re| c.match(re) } }
|
152
|
-
end.each do |path|
|
153
|
-
move(path, osx_app_archive_path)
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
rule 'Windows applications' do
|
158
|
-
dir('~/Downloads/*.exe').each do |path|
|
159
|
-
move(path, win_app_archive_path)
|
160
|
-
end
|
161
|
-
end
|
99
|
+
For a sample rules file, run:
|
162
100
|
|
163
|
-
|
164
|
-
dir('~/Downloads/*.zip').select do |path|
|
165
|
-
candidates = zipfile_contents(path)
|
166
|
-
candidates.any? { |candidate| candidate.match(/\.exe$/) }
|
167
|
-
end.each do |path|
|
168
|
-
move(path, win_app_archive_path)
|
169
|
-
end
|
170
|
-
end
|
171
|
-
|
172
|
-
rule 'Accidental Wikipedia downloads' do
|
173
|
-
dir('~/Downloads/*').each do |path|
|
174
|
-
if downloaded_from(path).any? { |url| url.match('wikipedia') }
|
175
|
-
trash(path)
|
176
|
-
end
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
# If you store your working files in ~/Outbox/ (like Ethan Schoonover's "Kinkless Desktop"), you can have them automatically filed away...
|
181
|
-
|
182
|
-
rule 'JS snippets I write' do
|
183
|
-
dir('~/Outbox/*.js').each do |path|
|
184
|
-
if 1.weeks.ago > File.atime(path)
|
185
|
-
move(path, '~/Projects/snippets/javascript/')
|
186
|
-
end
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
rule 'Ruby snippets' do
|
191
|
-
dir('~/Outbox/*.rb').each do |path|
|
192
|
-
if 1.week.ago > File.atime(path)
|
193
|
-
move(path, '~/Projects/snippets/ruby/')
|
194
|
-
end
|
195
|
-
end
|
196
|
-
end
|
197
|
-
|
198
|
-
rule 'Email drafts' do
|
199
|
-
dir('~/Outbox/*.eml').each do |path|
|
200
|
-
if 1.week.ago > File.atime(path)
|
201
|
-
move(path, '~/Archive/Misc Drafts/')
|
202
|
-
end
|
203
|
-
end
|
204
|
-
end
|
205
|
-
|
206
|
-
rule 'Misc notes' do
|
207
|
-
%w[md markdown rtf txt].inject([]) { |all, ext| all + dir("~/Outbox/*.#{ext}") }.each do |path|
|
208
|
-
if 1.week.ago > File.atime(path)
|
209
|
-
move(path, '~/Archive/Misc Notes/')
|
210
|
-
end
|
211
|
-
end
|
212
|
-
end
|
213
|
-
|
214
|
-
rule 'Misc Screenshots' do
|
215
|
-
dir('~/Outbox/Screen shot *').each do |path|
|
216
|
-
if 1.week.ago > File.atime(path)
|
217
|
-
move(path, '~/Archive/Misc Screenshots/')
|
218
|
-
end
|
219
|
-
end
|
220
|
-
end
|
221
|
-
|
222
|
-
rule 'Clear my working "temp" directory' do
|
223
|
-
trash('~/tmp')
|
224
|
-
FileUtils.mkdir_p(File.expand_path('~/tmp'))
|
225
|
-
end
|
226
|
-
end
|
101
|
+
maid sample
|
227
102
|
|
228
103
|
== Warranty
|
229
104
|
|
data/TODO.rdoc
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
= TODO
|
2
|
+
|
3
|
+
== v0.1.0
|
4
|
+
|
5
|
+
It's in beta right now. Here's what's left for the first release:
|
6
|
+
|
7
|
+
* Turn off forced noop before release
|
8
|
+
|
9
|
+
== Future Releases
|
10
|
+
|
11
|
+
Some of these might not happen, but they're being thought about. Feel free to add your own.
|
12
|
+
|
13
|
+
* Better user documentation of the DSL (in Maid::Tools)
|
14
|
+
* Man pages, e.g. maid(1) and maid(5)
|
15
|
+
* I've read http://ozmm.org/posts/man_what.html and http://rcrowley.org/articles/man-pages-vs-rubygems.html and I'm not too happy with the available tools for this
|
16
|
+
* Use a Cocoa interface to get Spotlight results
|
17
|
+
* "Watch" rules that use Folder Actions on OS X (and icron on Linux?). Something like:
|
18
|
+
|
19
|
+
Maid.rules do
|
20
|
+
watch '~/Downloads' do
|
21
|
+
rule 'watch rule 1' do
|
22
|
+
# ...
|
23
|
+
end
|
24
|
+
|
25
|
+
rule 'watch rule 2' do
|
26
|
+
# ...
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
rule 'normal rule 3' do
|
31
|
+
# ...
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
* Guard has some similar "watch" functionality. Here's what they use:
|
36
|
+
* FSEvent support on Mac OS X 10.5+ (without RubyCocoa!, rb-fsevent gem, >= 0.3.5 required).
|
37
|
+
* Inotify support on Linux (rb-inotify gem, >= 0.5.1 required).
|
38
|
+
* Directory Change Notification support on Windows (rb-fchange, >= 0.0.2 required).
|
39
|
+
* Polling on the other operating systems (help us to support more OS).
|
40
|
+
* Automatic & Super fast (when polling is not used) files modifications detection (even new files are detected).
|
41
|
+
* Possibly: notifications
|
42
|
+
* Growl notifications (growlnotify & growl gem required).
|
43
|
+
* Libnotify notifications (libnotify gem required).
|
44
|
+
|
45
|
+
* GUI for configuring easy rules
|
data/lib/maid/app.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
1
3
|
require 'rubygems'
|
2
4
|
require 'thor'
|
3
5
|
|
@@ -5,6 +7,10 @@ class Maid::App < Thor
|
|
5
7
|
check_unknown_options!
|
6
8
|
default_task 'clean'
|
7
9
|
|
10
|
+
def self.sample_rules_path
|
11
|
+
File.join(File.dirname(Maid::Maid::DEFAULTS[:rules_path]), 'rules.sample.rb')
|
12
|
+
end
|
13
|
+
|
8
14
|
desc 'clean', 'Clean based on rules'
|
9
15
|
method_option :rules, :type => :string, :aliases => %w[-r]
|
10
16
|
method_option :noop, :type => :boolean, :aliases => %w[-n --dry-run]
|
@@ -22,6 +28,16 @@ class Maid::App < Thor
|
|
22
28
|
say Maid::VERSION
|
23
29
|
end
|
24
30
|
|
31
|
+
desc 'sample', "Create sample rules at #{self.sample_rules_path}"
|
32
|
+
def sample
|
33
|
+
path = self.class.sample_rules_path
|
34
|
+
|
35
|
+
FileUtils.mkdir_p(File.dirname(path))
|
36
|
+
File.open(path, 'w').puts(File.read(File.join(File.dirname(__FILE__), 'rules.sample.rb')))
|
37
|
+
|
38
|
+
say "Sample rules created at #{path.inspect}", :green
|
39
|
+
end
|
40
|
+
|
25
41
|
no_tasks do
|
26
42
|
def maid_options(options)
|
27
43
|
h = {}
|
@@ -29,8 +45,11 @@ class Maid::App < Thor
|
|
29
45
|
if options['noop']
|
30
46
|
# You're testing, so a simple log goes to STDOUT and no actions are taken
|
31
47
|
h[:file_options] = {:noop => true}
|
32
|
-
|
33
|
-
|
48
|
+
|
49
|
+
unless options['silent']
|
50
|
+
h[:log_device] = STDOUT
|
51
|
+
h[:log_formatter] = lambda { |_, _, _, msg| "#{msg}\n" }
|
52
|
+
end
|
34
53
|
end
|
35
54
|
|
36
55
|
if options['rules']
|
data/lib/maid/maid.rb
CHANGED
@@ -0,0 +1,60 @@
|
|
1
|
+
# Sample Maid rules file -- a sampling to get you started.
|
2
|
+
#
|
3
|
+
# To use, remove ".sample" from the filename. Test using:
|
4
|
+
#
|
5
|
+
# maid -n
|
6
|
+
#
|
7
|
+
# For more help on Maid:
|
8
|
+
#
|
9
|
+
# * Run `maid help`
|
10
|
+
# * Read the README at http://github.com/benjaminoakes/maid
|
11
|
+
# * For more DSL helper methods, please see the documentation of Maid::Tools.
|
12
|
+
# * Come up with some cool tools of your own? Fork, make your changes, and send me a pull request on GitHub!
|
13
|
+
# * Ask me a question over email (hello@benjaminoakes.com) or twitter (@benjaminoakes)
|
14
|
+
#
|
15
|
+
Maid.rules do
|
16
|
+
rule 'MP3s likely to be music' do
|
17
|
+
dir('~/Downloads/*.mp3').each do |path|
|
18
|
+
if duration_s(path) > 30.0
|
19
|
+
move(path, '~/Music/iTunes/iTunes Media/Automatically Add to iTunes/')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
rule 'Old files downloaded while developing/testing' do
|
25
|
+
dir('~/Downloads/*').each do |path|
|
26
|
+
if downloaded_from(path).any? {|u| u.match 'http://localhost' || u.match('http://staging.yourcompany.com') } && 1.week.since?(last_accessed(path))
|
27
|
+
trash(path)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
rule 'Linux ISOs, etc' do
|
33
|
+
dir('~/Downloads/*.iso').each { |p| trash p }
|
34
|
+
end
|
35
|
+
|
36
|
+
rule 'Linux applications in Debian packages' do
|
37
|
+
dir('~/Downloads/*.deb').each { |p| trash p }
|
38
|
+
end
|
39
|
+
|
40
|
+
rule 'Mac OS X applications in disk images' do
|
41
|
+
dir('~/Downloads/*.dmg').each { |p| trash p }
|
42
|
+
end
|
43
|
+
|
44
|
+
rule 'Mac OS X applications in zip files' do
|
45
|
+
dir('~/Downloads/*.zip').select do |path|
|
46
|
+
candidates = zipfile_contents(path)
|
47
|
+
candidates.any? { |c| c.match(/\.app$/) }
|
48
|
+
end.each { |p| trash p }
|
49
|
+
end
|
50
|
+
|
51
|
+
rule 'Misc Screenshots' do
|
52
|
+
dir('~/Desktop/Screen shot *').each do |path|
|
53
|
+
if 1.week.since?(last_accessed(path))
|
54
|
+
move(path, '~/Documents/Misc Screenshots/')
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Add your own rules here.
|
60
|
+
end
|
data/lib/maid/version.rb
CHANGED
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env sh
|
2
|
+
# Script for testing Maid from scratch on MicroCore Linux (a 10 MB Linux distribution which is enough to run Maid)
|
3
|
+
|
4
|
+
if [ `whoami` == 'root' ]; then
|
5
|
+
mkdir maid
|
6
|
+
cd maid
|
7
|
+
tce-fetch.sh ruby.tcz
|
8
|
+
tce-load -i ruby.tcz
|
9
|
+
wget http://production.cf.rubygems.org/rubygems/rubygems-1.8.5.tgz
|
10
|
+
tar xvfz rubygems-1.8.5.tgz
|
11
|
+
cd rubygems-1.8.5
|
12
|
+
ruby setup.rb
|
13
|
+
# wget http://githubredir.debian.net/github/benjaminoakes/maid/0~master.tar.gz -O maid-master.tar.gz
|
14
|
+
# tar xvfz maid-master.tar.gz
|
15
|
+
gem install maid --pre
|
16
|
+
else
|
17
|
+
echo This should be run as root.
|
18
|
+
fi
|
data/spec/lib/maid/app_spec.rb
CHANGED
@@ -45,6 +45,10 @@ module Maid
|
|
45
45
|
@app.clean
|
46
46
|
end
|
47
47
|
|
48
|
+
it 'should not be silent if not given the --silent option' do
|
49
|
+
capture_stdout { App.start(['clean']) }.string.should_not == ''
|
50
|
+
end
|
51
|
+
|
48
52
|
it 'should be silent if given the --silent option' do
|
49
53
|
# TODO It might even make sense to wrap "maid.clean" in capture_stdout { }...
|
50
54
|
capture_stdout { App.start(['clean', '--silent']) }.string.should == ''
|
@@ -59,6 +63,12 @@ module Maid
|
|
59
63
|
end
|
60
64
|
end
|
61
65
|
|
66
|
+
describe App, 'sample rules' do
|
67
|
+
it 'should be able to run' do
|
68
|
+
lambda { App.start(%w[clean --silent --noop --rules=lib/maid/rules.sample.rb]) }.should_not raise_error(SyntaxError)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
62
72
|
describe App, '#version' do
|
63
73
|
it 'should print out the gem version' do
|
64
74
|
app = App.new
|
data/spec/lib/maid/tools_spec.rb
CHANGED
@@ -49,7 +49,8 @@ module Maid
|
|
49
49
|
end
|
50
50
|
|
51
51
|
it 'should use a safe path if the target exists' do
|
52
|
-
|
52
|
+
# Without an offset, ISO8601 parses to local time, which is what we want here.
|
53
|
+
Timecop.freeze(Time.parse('2011-05-22T16:53:52')) do
|
53
54
|
File.stub!(:exist?).and_return(true)
|
54
55
|
@maid.should_receive(:move).with(@path, "#{@trash_path}/foo.zip 2011-05-22-16-53-52")
|
55
56
|
@maid.trash(@path)
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: maid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 62196411
|
5
5
|
prerelease: 6
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
9
|
- 0
|
10
10
|
- beta
|
11
|
-
-
|
12
|
-
version: 0.1.0.beta.
|
11
|
+
- 4
|
12
|
+
version: 0.1.0.beta.4
|
13
13
|
platform: ruby
|
14
14
|
authors:
|
15
15
|
- Benjamin Oakes
|
@@ -17,7 +17,7 @@ autorequire:
|
|
17
17
|
bindir: bin
|
18
18
|
cert_chain: []
|
19
19
|
|
20
|
-
date: 2011-06-
|
20
|
+
date: 2011-06-17 00:00:00 Z
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
23
23
|
name: thor
|
@@ -111,6 +111,7 @@ extra_rdoc_files: []
|
|
111
111
|
files:
|
112
112
|
- .gitignore
|
113
113
|
- .rspec
|
114
|
+
- .travis.yml
|
114
115
|
- CONTRIBUTING.rdoc
|
115
116
|
- Gemfile
|
116
117
|
- Gemfile.lock
|
@@ -118,15 +119,18 @@ files:
|
|
118
119
|
- Maidfile
|
119
120
|
- README.rdoc
|
120
121
|
- Rakefile
|
122
|
+
- TODO.rdoc
|
121
123
|
- bin/maid
|
122
124
|
- lib/maid.rb
|
123
125
|
- lib/maid/app.rb
|
124
126
|
- lib/maid/maid.rb
|
125
127
|
- lib/maid/numeric_extensions.rb
|
126
128
|
- lib/maid/rule.rb
|
129
|
+
- lib/maid/rules.sample.rb
|
127
130
|
- lib/maid/tools.rb
|
128
131
|
- lib/maid/version.rb
|
129
132
|
- maid.gemspec
|
133
|
+
- script/micro-maid.sh
|
130
134
|
- spec/lib/maid/app_spec.rb
|
131
135
|
- spec/lib/maid/maid_spec.rb
|
132
136
|
- spec/lib/maid/numeric_extensions_spec.rb
|