\n",
"\n",
"# Module: Maid::Tools\n",
"\n",
"
\n",
"\n",
"Includes: \n",
"Deprecated\n",
"\n",
"\n",
"\n",
"Defined in: \n",
"lib/maid/tools.rb\n",
"\n",
"
\n",
"\n",
"## Overview\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"These \"tools\" are methods available in the Maid DSL.\n",
"\n",
"In general, methods are expected to:\n",
"\n",
"- Automatically expand paths (that is, `'~/Downloads/foo.zip'` becomes\n",
" `'/home/username/Downloads/foo.zip'`)\n",
"- Respect the `noop` (`dry-run`) option if it is set\n",
"\n",
"Some methods are not available on all platforms. An `ArgumentError` is\n",
"raised when a command is not available. See tags such as: \\[Mac OS X\\]\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"## Instance Method Summary
collapse\n",
"\n",
"-
[accessed_at](/gems/maid/0.7.0/Maid/Tools#accessed_at-instance_method \"#accessed_at (instance method)\")\n",
"-
[checksum_of](/gems/maid/0.7.0/Maid/Tools#checksum_of-instance_method \"#checksum_of (instance method)\")\n",
"-
[content_types](/gems/maid/0.7.0/Maid/Tools#content_types-instance_method \"#content_types (instance method)\")\n",
"-
[copy](/gems/maid/0.7.0/Maid/Tools#copy-instance_method \"#copy (instance method)\")\n",
"-
[created_at](/gems/maid/0.7.0/Maid/Tools#created_at-instance_method \"#created_at (instance method)\")\n",
"-
[dimensions_px](/gems/maid/0.7.0/Maid/Tools#dimensions_px-instance_method \"#dimensions_px (instance method)\")\n",
"-
[dir](/gems/maid/0.7.0/Maid/Tools#dir-instance_method \"#dir (instance method)\")\n",
"-
[dir_safe](/gems/maid/0.7.0/Maid/Tools#dir_safe-instance_method \"#dir_safe (instance method)\")\n",
"-
[disk_usage](/gems/maid/0.7.0/Maid/Tools#disk_usage-instance_method \"#disk_usage (instance method)\")\n",
"-
[downloaded_from](/gems/maid/0.7.0/Maid/Tools#downloaded_from-instance_method \"#downloaded_from (instance method)\")\n",
"-
[downloading?](/gems/maid/0.7.0/Maid/Tools#downloading%3F-instance_method \"#downloading? (instance method)\")\n",
"-
[dupes_in](/gems/maid/0.7.0/Maid/Tools#dupes_in-instance_method \"#dupes_in (instance method)\")\n",
"-
[duration_s](/gems/maid/0.7.0/Maid/Tools#duration_s-instance_method \"#duration_s (instance method)\")\n",
"-
[escape_glob](/gems/maid/0.7.0/Maid/Tools#escape_glob-instance_method \"#escape_glob (instance method)\")\n",
"-
[files](/gems/maid/0.7.0/Maid/Tools#files-instance_method \"#files (instance method)\")\n",
"-
[find](/gems/maid/0.7.0/Maid/Tools#find-instance_method \"#find (instance method)\")\n",
"-
[git_piston](/gems/maid/0.7.0/Maid/Tools#git_piston-instance_method \"#git_piston (instance method)\")\n",
"-
[ignore_child_dirs](/gems/maid/0.7.0/Maid/Tools#ignore_child_dirs-instance_method \"#ignore_child_dirs (instance method)\")\n",
"-
[last_accessed](/gems/maid/0.7.0/Maid/Tools#last_accessed-instance_method \"#last_accessed (instance method)\")\n",
"-
[locate](/gems/maid/0.7.0/Maid/Tools#locate-instance_method \"#locate (instance method)\")\n",
"-
[location_city](/gems/maid/0.7.0/Maid/Tools#location_city-instance_method \"#location_city (instance method)\")\n",
"-
[media_type](/gems/maid/0.7.0/Maid/Tools#media_type-instance_method \"#media_type (instance method)\")\n",
"-
[mime_type](/gems/maid/0.7.0/Maid/Tools#mime_type-instance_method \"#mime_type (instance method)\")\n",
"-
[mkdir](/gems/maid/0.7.0/Maid/Tools#mkdir-instance_method \"#mkdir (instance method)\")\n",
"-
[modified_at](/gems/maid/0.7.0/Maid/Tools#modified_at-instance_method \"#modified_at (instance method)\")\n",
"-
[move](/gems/maid/0.7.0/Maid/Tools#move-instance_method \"#move (instance method)\")\n",
"-
[newest_dupes_in](/gems/maid/0.7.0/Maid/Tools#newest_dupes_in-instance_method \"#newest_dupes_in (instance method)\")\n",
"-
[remove](/gems/maid/0.7.0/Maid/Tools#remove-instance_method \"#remove (instance method)\")\n",
"-
[rename](/gems/maid/0.7.0/Maid/Tools#rename-instance_method \"#rename (instance method)\")\n",
"-
[size_of](/gems/maid/0.7.0/Maid/Tools#size_of-instance_method \"#size_of (instance method)\")\n",
"-
[spotlight_content_types](/gems/maid/0.7.0/Maid/Tools#spotlight_content_types-instance_method \"#spotlight_content_types (instance method)\")\n",
"-
[sync](/gems/maid/0.7.0/Maid/Tools#sync-instance_method \"#sync (instance method)\")\n",
"-
[trash](/gems/maid/0.7.0/Maid/Tools#trash-instance_method \"#trash (instance method)\")\n",
"-
[tree_empty?](/gems/maid/0.7.0/Maid/Tools#tree_empty%3F-instance_method \"#tree_empty? (instance method)\")\n",
"-
[verbose_dupes_in](/gems/maid/0.7.0/Maid/Tools#verbose_dupes_in-instance_method \"#verbose_dupes_in (instance method)\")\n",
"-
[where_content_type](/gems/maid/0.7.0/Maid/Tools#where_content_type-instance_method \"#where_content_type (instance method)\")\n",
"-
[zipfile_contents](/gems/maid/0.7.0/Maid/Tools#zipfile_contents-instance_method \"#zipfile_contents (instance method)\")\n",
"\n",
"\n",
"\n",
"-
[\\#**accessed_at**(path) ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#accessed_at-instance_method \"#accessed_at (instance method)\")\n",
" \n",
"
\n",
"\n",
" Get the time that a file was last accessed.\n",
"\n",
"
\n",
"-
[\\#**checksum_of**(path) ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#checksum_of-instance_method \"#checksum_of (instance method)\")\n",
" \n",
"
\n",
"\n",
" Get a checksum for a file.\n",
"\n",
"
\n",
"-
[\\#**content_types**(path) ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#content_types-instance_method \"#content_types (instance method)\")\n",
" \n",
"
\n",
"\n",
" Get the content types of a path.\n",
"\n",
"
\n",
"-
[\\#**copy**(sources, destination) ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#copy-instance_method \"#copy (instance method)\")\n",
" \n",
"
\n",
"\n",
" Copy from `sources` to `destination`.\n",
"\n",
"
\n",
"-
[\\#**created_at**(path) ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#created_at-instance_method \"#created_at (instance method)\")\n",
" \n",
"
\n",
"\n",
" Get the creation time of a file.\n",
"\n",
"
\n",
"-
[\\#**dimensions_px**(path) ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#dimensions_px-instance_method \"#dimensions_px (instance method)\")\n",
" \n",
"
\n",
"\n",
" Determine the dimensions of GIF, PNG, JPEG, or TIFF images.\n",
"\n",
"
\n",
"-
[\\#**dir**(globs) ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#dir-instance_method \"#dir (instance method)\")\n",
" \n",
"
\n",
"\n",
" Give all files matching the given glob.\n",
"\n",
"
\n",
"-
[\\#**dir_safe**(globs) ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#dir_safe-instance_method \"#dir_safe (instance method)\")\n",
" \n",
"
\n",
"\n",
" Same as `dir`, but excludes files that are (possibly) being\n",
" downloaded.\n",
"\n",
"
\n",
"-
[\\#**disk_usage**(path) ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#disk_usage-instance_method \"#disk_usage (instance method)\")\n",
" \n",
"
\n",
"\n",
" Calculate disk usage of a given path in kilobytes.\n",
"\n",
"
\n",
"-
[\\#**downloaded_from**(path) ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#downloaded_from-instance_method \"#downloaded_from (instance method)\")\n",
" \n",
"
\n",
"\n",
" \\[Mac OS X\\] Use Spotlight metadata to determine the site from which\n",
" a file was downloaded.\n",
"\n",
"
\n",
"-
[\\#**downloading?**(path) ⇒\n",
" Boolean](/gems/maid/0.7.0/Maid/Tools#downloading%3F-instance_method \"#downloading? (instance method)\")\n",
" \n",
"
\n",
"\n",
" Detect whether the path is currently being downloaded in Chrome,\n",
" Firefox or Safari.\n",
"\n",
"
\n",
"-
[\\#**dupes_in**(globs) ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#dupes_in-instance_method \"#dupes_in (instance method)\")\n",
" \n",
"
\n",
"\n",
" Find all duplicate files in the given globs.\n",
"\n",
"
\n",
"-
[\\#**duration_s**(path) ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#duration_s-instance_method \"#duration_s (instance method)\")\n",
" \n",
"
\n",
"\n",
" \\[Mac OS X\\] Use Spotlight metadata to determine audio length.\n",
"\n",
"
\n",
"-
[\\#**escape_glob**(glob) ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#escape_glob-instance_method \"#escape_glob (instance method)\")\n",
" \n",
"
\n",
"\n",
" Escape characters that have special meaning as a part of path global\n",
" patterns.\n",
"\n",
"
\n",
"-
[\\#**files**(globs) ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#files-instance_method \"#files (instance method)\")\n",
" \n",
"
\n",
"\n",
" Give only files matching the given glob.\n",
"\n",
"
\n",
"-
[\\#**find**(path, &block) ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#find-instance_method \"#find (instance method)\")\n",
" \n",
"
\n",
"\n",
" Find matching files, akin to the Unix utility `find`.\n",
"\n",
"
\n",
"-
[\\#**git_piston**(path) ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#git_piston-instance_method \"#git_piston (instance method)\")\n",
" deprecated **Deprecated.** \n",
"
\n",
"\n",
"
\n",
"-
[\\#**ignore_child_dirs**(arr) ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#ignore_child_dirs-instance_method \"#ignore_child_dirs (instance method)\")\n",
" \n",
"
\n",
"\n",
" Given an array of directories, return a new array without any child\n",
" directories whose parent is already present in that array.\n",
"\n",
"
\n",
"-
[\\#**last_accessed**(path) ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#last_accessed-instance_method \"#last_accessed (instance method)\")\n",
" deprecated **Deprecated.** \n",
"
\n",
"\n",
"
\n",
"-
[\\#**locate**(name) ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#locate-instance_method \"#locate (instance method)\")\n",
" \n",
"
\n",
"\n",
" \\[Mac OS X\\] Use Spotlight to locate all files matching the given\n",
" filename.\n",
"\n",
"
\n",
"-
[\\#**location_city**(path) ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#location_city-instance_method \"#location_city (instance method)\")\n",
" \n",
"
\n",
"\n",
" Determine the city of the given JPEG image.\n",
"\n",
"
\n",
"-
[\\#**media_type**(path) ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#media_type-instance_method \"#media_type (instance method)\")\n",
" \n",
"
\n",
"\n",
" Get the Internet media type of the file.\n",
"\n",
"
\n",
"-
[\\#**mime_type**(path) ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#mime_type-instance_method \"#mime_type (instance method)\")\n",
" \n",
"
\n",
"\n",
" Get the MIME type of the file.\n",
"\n",
"
\n",
"-
[\\#**mkdir**(path, options = {}) ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#mkdir-instance_method \"#mkdir (instance method)\")\n",
" \n",
"
\n",
"\n",
" Create a directory and all of its parent directories.\n",
"\n",
"
\n",
"-
[\\#**modified_at**(path) ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#modified_at-instance_method \"#modified_at (instance method)\")\n",
" \n",
"
\n",
"\n",
" Get the modification time of a file.\n",
"\n",
"
\n",
"-
[\\#**move**(sources, destination) ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#move-instance_method \"#move (instance method)\")\n",
" \n",
"
\n",
"\n",
" Move `sources` to a `destination` directory.\n",
"\n",
"
\n",
"-
[\\#**newest_dupes_in**(globs) ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#newest_dupes_in-instance_method \"#newest_dupes_in (instance method)\")\n",
" \n",
"
\n",
"\n",
" Convenience method that is like `dupes_in` but excludes the oldest\n",
" dupe.\n",
"\n",
"
\n",
"-
[\\#**remove**(paths, options = {})\n",
" ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#remove-instance_method \"#remove (instance method)\")\n",
" \n",
"
\n",
"\n",
" Delete the files at the given path recursively.\n",
"\n",
"
\n",
"-
[\\#**rename**(source, destination)\n",
" ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#rename-instance_method \"#rename (instance method)\")\n",
" \n",
"
\n",
"\n",
" Rename a single file.\n",
"\n",
"
\n",
"-
[\\#**size_of**(path) ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#size_of-instance_method \"#size_of (instance method)\")\n",
" \n",
"
\n",
"\n",
" Get the size of a file.\n",
"\n",
"
\n",
"-
\n",
" [\\#**spotlight_content_types**(path) ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#spotlight_content_types-instance_method \"#spotlight_content_types (instance method)\")\n",
" \n",
"
\n",
"\n",
" \\[Mac OS X\\] Use Spotlight metadata to determine which content types\n",
" a file has.\n",
"\n",
"
\n",
"-
[\\#**sync**(from, to, options = {})\n",
" ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#sync-instance_method \"#sync (instance method)\")\n",
" \n",
"
\n",
"\n",
" Simple sync two files/folders using `rsync`.\n",
"\n",
"
\n",
"-
[\\#**trash**(paths, options = {}) ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#trash-instance_method \"#trash (instance method)\")\n",
" \n",
"
\n",
"\n",
" Move the given paths to the user's trash.\n",
"\n",
"
\n",
"-
[\\#**tree_empty?**(root) ⇒\n",
" Boolean](/gems/maid/0.7.0/Maid/Tools#tree_empty%3F-instance_method \"#tree_empty? (instance method)\")\n",
" \n",
"
\n",
"\n",
" Test whether a directory is either empty, or contains only empty\n",
" directories/subdirectories.\n",
"\n",
"
\n",
"-
[\\#**verbose_dupes_in**(globs) ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#verbose_dupes_in-instance_method \"#verbose_dupes_in (instance method)\")\n",
" \n",
"
\n",
"\n",
" Convenience method for `dupes_in` that excludes the dupe with the\n",
" shortest name.\n",
"\n",
"
\n",
"-
[\\#**where_content_type**(paths,\n",
" filter_types) ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#where_content_type-instance_method \"#where_content_type (instance method)\")\n",
" \n",
"
\n",
"\n",
" Filter an array by content types.\n",
"\n",
"
\n",
"-
[\\#**zipfile_contents**(path) ⇒\n",
" Object](/gems/maid/0.7.0/Maid/Tools#zipfile_contents-instance_method \"#zipfile_contents (instance method)\")\n",
" \n",
"
\n",
"\n",
" List the contents of a zip file.\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"## Instance Method Details\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**accessed_at**(path) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Get the time that a file was last accessed.\n",
"\n",
"In Unix speak, `atime`.\n",
"\n",
"## Examples\n",
"\n",
"``` code\n",
"accessed_at('foo.zip') # => Sat Apr 09 10:50:01 -0400 2011\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"519\n",
"520\n",
"521
| \n",
"# File 'lib/maid/tools.rb', line 519\n",
"\n",
"def accessed_at(path)\n",
" File.atime(expand(path))\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**checksum_of**(path) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Get a checksum for a file.\n",
"\n",
"## Examples\n",
"\n",
"``` code\n",
"checksum_of('foo.zip') # => \"67258d750ca654d5d3c7b06bd2a1c792ced2003e\"\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"557\n",
"558\n",
"559
| \n",
"# File 'lib/maid/tools.rb', line 557\n",
"\n",
"def checksum_of(path)\n",
" Digest::SHA1.hexdigest(File.read(path))\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**content_types**(path) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Get the content types of a path.\n",
"\n",
"Content types can be MIME types, Internet media types or Spotlight\n",
"content types (OS X only).\n",
"\n",
"## Examples\n",
"\n",
"``` code\n",
"content_types('foo.zip') # => [\"public.zip-archive\", \"com.pkware.zip-archive\", \"public.archive\", \"application/zip\", \"application\"]\n",
"content_types('bar.jpg') # => [\"public.jpeg\", \"public.image\", \"image/jpeg\", \"image\"]\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"647\n",
"648\n",
"649
| \n",
"# File 'lib/maid/tools.rb', line 647\n",
"\n",
"def content_types(path)\n",
" [spotlight_content_types(path), mime_type(path), media_type(path)].flatten\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**copy**(sources, destination) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Copy from `sources` to `destination`\n",
"\n",
"The path is not copied if a file already exists at the destination with\n",
"the same name. A warning is logged instead. Note: Similar functionality\n",
"is provided by the sync tool, but this requires installation of the\n",
"`rsync` binary\n",
"\n",
"## Examples\n",
"\n",
"Single path:\n",
"\n",
"``` code\n",
"copy('~/Downloads/foo.zip', '~/Archive/Software/Mac OS X/')\n",
"```\n",
"\n",
"Multiple paths:\n",
"\n",
"``` code\n",
"copy(['~/Downloads/foo.zip', '~/Downloads/bar.zip'], '~/Archive/Software/Mac OS X/')\n",
"copy(dir('~/Downloads/*.zip'), '~/Archive/Software/Mac OS X/')\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"163\n",
"164\n",
"165\n",
"166\n",
"167\n",
"168\n",
"169\n",
"170\n",
"171\n",
"172\n",
"173\n",
"174\n",
"175\n",
"176
| \n",
"# File 'lib/maid/tools.rb', line 163\n",
"\n",
"def copy(sources, destination)\n",
" destination = expand(destination)\n",
"\n",
" expand_all(sources).each do |source|\n",
" target = File.join(destination, File.basename(source))\n",
"\n",
" unless File.exist?(target)\n",
" log("cp #{ sh_escape(source) } #{ sh_escape(destination) }")\n",
" FileUtils.cp(source, destination, @file_options)\n",
" else\n",
" warn("skipping copy because #{ sh_escape(source) } because #{ sh_escape(target) } already exists")\n",
" end\n",
" end\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**created_at**(path) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Get the creation time of a file.\n",
"\n",
"In Unix speak, `ctime`.\n",
"\n",
"## Examples\n",
"\n",
"``` code\n",
"created_at('foo.zip') # => Sat Apr 09 10:50:01 -0400 2011\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"508\n",
"509\n",
"510
| \n",
"# File 'lib/maid/tools.rb', line 508\n",
"\n",
"def created_at(path)\n",
" File.ctime(expand(path))\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**dimensions_px**(path) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Determine the dimensions of GIF, PNG, JPEG, or TIFF images.\n",
"\n",
"Value returned is \\[width, height\\].\n",
"\n",
"## Examples\n",
"\n",
"``` code\n",
"dimensions_px('image.jpg') # => [1024, 768]\n",
"width, height = dimensions_px('image.jpg')\n",
"dimensions_px('image.jpg').join('x') # => \"1024x768\"\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"442\n",
"443\n",
"444
| \n",
"# File 'lib/maid/tools.rb', line 442\n",
"\n",
"def dimensions_px(path)\n",
" Dimensions.dimensions(path)\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**dir**(globs) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Give all files matching the given glob.\n",
"\n",
"Note that the globs are *not* regexps (they're closer to shell globs).\n",
"However, some regexp-like notation can be used, e.g. `?`, `[a-z]`,\n",
"`{tgz,zip}`. For more details, see Ruby's documentation on `Dir.glob`.\n",
"\n",
"The matches are sorted lexically to aid in readability when using\n",
"`--dry-run`.\n",
"\n",
"## Examples\n",
"\n",
"Single glob:\n",
"\n",
"``` code\n",
"dir('~/Downloads/*.zip')\n",
"```\n",
"\n",
"Specifying multiple extensions succinctly:\n",
"\n",
"``` code\n",
"dir('~/Downloads/*.{exe,deb,dmg,pkg,rpm}')\n",
"```\n",
"\n",
"Multiple glob (all are equivalent):\n",
"\n",
"``` code\n",
"dir(['~/Downloads/*.zip', '~/Dropbox/*.zip'])\n",
"dir(%w(~/Downloads/*.zip ~/Dropbox/*.zip))\n",
"dir('~/{Downloads,Dropbox}/*.zip')\n",
"```\n",
"\n",
"Recursing into subdirectories (see also: `find`):\n",
"\n",
"``` code\n",
"dir('~/Music/**/*.m4a')\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"240\n",
"241\n",
"242\n",
"243\n",
"244\n",
"245
| \n",
"# File 'lib/maid/tools.rb', line 240\n",
"\n",
"def dir(globs)\n",
" expand_all(globs).\n",
" map { |glob| Dir.glob(glob) }.\n",
" flatten.\n",
" sort\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**dir_safe**(globs) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Same as `dir`, but excludes files that are (possibly) being downloaded.\n",
"\n",
"## Example\n",
"\n",
"Move Debian/Ubuntu packages that are finished downloading into a\n",
"software directory.\n",
"\n",
"``` code\n",
"move dir_safe('~/Downloads/*.deb'), '~/Archive/Software'\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"256\n",
"257\n",
"258\n",
"259
| \n",
"# File 'lib/maid/tools.rb', line 256\n",
"\n",
"def dir_safe(globs)\n",
" dir(globs).\n",
" reject { |path| downloading?(path) }\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**disk_usage**(path) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Calculate disk usage of a given path in kilobytes.\n",
"\n",
"See also: `Maid::NumericExtensions::SizeToKb`.\n",
"\n",
"## Examples\n",
"\n",
"``` code\n",
"disk_usage('foo.zip') # => 136\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"489\n",
"490\n",
"491\n",
"492\n",
"493\n",
"494\n",
"495\n",
"496\n",
"497\n",
"498\n",
"499
| \n",
"# File 'lib/maid/tools.rb', line 489\n",
"\n",
"def disk_usage(path)\n",
" raw = cmd("du -s #{ sh_escape(path) }")\n",
" # FIXME: This reports in kilobytes, but should probably report in bytes.\n",
" usage_kb = raw.split(/\\s+/).first.to_i\n",
"\n",
" if usage_kb.zero?\n",
" raise "Stopping pessimistically because of unexpected value from du (#{ raw.inspect })"\n",
" else\n",
" usage_kb\n",
" end\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**downloaded_from**(path) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"\\[Mac OS X\\] Use Spotlight metadata to determine the site from which a\n",
"file was downloaded.\n",
"\n",
"## Examples\n",
"\n",
"``` code\n",
"downloaded_from('foo.zip') # => ['http://www.site.com/foo.zip', 'http://www.site.com/']\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"355\n",
"356\n",
"357
| \n",
"# File 'lib/maid/tools.rb', line 355\n",
"\n",
"def downloaded_from(path)\n",
" mdls_to_array(path, 'kMDItemWhereFroms')\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**downloading?**(path) ⇒ Boolean\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Detect whether the path is currently being downloaded in Chrome, Firefox\n",
"or Safari.\n",
"\n",
"See also: `dir_safe`\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Returns:\n",
"\n",
"- (Boolean)\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"362\n",
"363\n",
"364
| \n",
"# File 'lib/maid/tools.rb', line 362\n",
"\n",
"def downloading?(path)\n",
" !!(chrome_downloading?(path) || firefox_downloading?(path) || safari_downloading?(path))\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**dupes_in**(globs) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Find all duplicate files in the given globs.\n",
"\n",
"More often than not, you'll want to use `newest_dupes_in` or\n",
"`verbose_dupes_in` instead of using this method directly.\n",
"\n",
"Globs are expanded as in `dir`, then all non-files are filtered out. The\n",
"remaining files are compared by size, and non-dupes are filtered out.\n",
"The remaining candidates are then compared by checksum. Dupes are\n",
"returned as an array of arrays.\n",
"\n",
"## Examples\n",
"\n",
"``` code\n",
"dupes_in('~/{Downloads,Desktop}/*') # => [\n",
" ['~/Downloads/foo.zip', '~/Downloads/foo (1).zip'],\n",
" ['~/Desktop/bar.txt', '~/Desktop/bar copy.txt']\n",
" ]\n",
"```\n",
"\n",
"Keep the newest dupe:\n",
"\n",
"``` code\n",
"dupes_in('~/Desktop/*', '~/Downloads/*').each do |dupes|\n",
" trash dupes.sort_by { |p| File.mtime(p) }[0..-2]\n",
"end\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"389\n",
"390\n",
"391\n",
"392\n",
"393\n",
"394\n",
"395\n",
"396\n",
"397\n",
"398\n",
"399\n",
"400\n",
"401
| \n",
"# File 'lib/maid/tools.rb', line 389\n",
"\n",
"def dupes_in(globs)\n",
" dupes = []\n",
" files(globs). # Start by filtering out non-files\n",
" group_by { |f| size_of(f) }. # ... then grouping by size, since that's fast\n",
" reject { |s, p| p.length < 2 }. # ... and filter out any non-dupes\n",
" map do |size, candidates|\n",
" dupes += candidates.\n",
" group_by { |p| checksum_of(p) }. # Now group our candidates by a slower checksum calculation\n",
" reject { |c, p| p.length < 2 }. # ... and filter out any non-dupes\n",
" values\n",
" end\n",
" dupes\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**duration_s**(path) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"\\[Mac OS X\\] Use Spotlight metadata to determine audio length.\n",
"\n",
"## Examples\n",
"\n",
"``` code\n",
"duration_s('foo.mp3') # => 235.705\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"466\n",
"467\n",
"468
| \n",
"# File 'lib/maid/tools.rb', line 466\n",
"\n",
"def duration_s(path)\n",
" cmd("mdls -raw -name kMDItemDurationSeconds #{ sh_escape(path) }").to_f\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**escape_glob**(glob) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Escape characters that have special meaning as a part of path global\n",
"patterns.\n",
"\n",
"Useful when using `dir` with file names that may contain `{ } [ ]`\n",
"characters.\n",
"\n",
"## Example\n",
"\n",
"``` code\n",
"escape_glob('test [tmp]') # => 'test \\\\[tmp\\\\]'\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"277\n",
"278\n",
"279
| \n",
"# File 'lib/maid/tools.rb', line 277\n",
"\n",
"def escape_glob(glob)\n",
" glob.gsub(/[\\{\\}\\[\\]]/) { |s| '\\\\' + s }\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**files**(globs) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Give only files matching the given glob.\n",
"\n",
"This is the same as `dir` but only includes actual files (no directories\n",
"or symlinks).\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"265\n",
"266\n",
"267\n",
"268
| \n",
"# File 'lib/maid/tools.rb', line 265\n",
"\n",
"def files(globs)\n",
" dir(globs).\n",
" select { |f| File.file?(f) }\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**find**(path, &block) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Find matching files, akin to the Unix utility `find`.\n",
"\n",
"If no block is given, it will return an array. Otherwise, it acts like\n",
"`Find.find`.\n",
"\n",
"## Examples\n",
"\n",
"Without a block:\n",
"\n",
"``` code\n",
"find('~/Downloads/') # => [...]\n",
"```\n",
"\n",
"Recursing and filtering using a regular expression:\n",
"\n",
"``` code\n",
"find('~/Downloads/').grep(/\\.pdf$/)\n",
"```\n",
"\n",
"(**Note:** It's just Ruby, so any methods in `Array` and `Enumerable`\n",
"can be used.)\n",
"\n",
"Recursing with a block:\n",
"\n",
"``` code\n",
"find('~/Downloads/') do |path|\n",
" # ...\n",
"end\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"329\n",
"330\n",
"331\n",
"332\n",
"333\n",
"334\n",
"335\n",
"336\n",
"337
| \n",
"# File 'lib/maid/tools.rb', line 329\n",
"\n",
"def find(path, &block)\n",
" expanded_path = expand(path)\n",
"\n",
" if block.nil?\n",
" Find.find(expanded_path).to_a\n",
" else\n",
" Find.find(expanded_path, &block)\n",
" end\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**git_piston**(path) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"**Deprecated.**\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Pull and push the `git` repository at the given path.\n",
"\n",
"Since this is deprecated, you might also be interested in\n",
"[SparkleShare](http://sparkleshare.org/), a great `git`-based file\n",
"syncronization project.\n",
"\n",
"## Examples\n",
"\n",
"``` code\n",
"git_piston('~/code/projectname')\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"571\n",
"572\n",
"573\n",
"574\n",
"575
| \n",
"# File 'lib/maid/tools.rb', line 571\n",
"\n",
"def git_piston(path)\n",
" full_path = expand(path)\n",
" stdout = cmd("cd #{ sh_escape(full_path) } && git pull && git push 2>&1")\n",
" log("Fired git piston on #{ sh_escape(full_path) }. STDOUT:\\n\\n#{ stdout }")\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**ignore_child_dirs**(arr) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Given an array of directories, return a new array without any child\n",
"directories whose parent is already present in that array.\n",
"\n",
"## Example\n",
"\n",
"``` code\n",
"ignore_child_dirs([\"foo\", \"foo/a\", \"foo/b\", \"bar\"]) # => [\"foo\", \"bar\"]\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"749\n",
"750\n",
"751\n",
"752\n",
"753\n",
"754\n",
"755
| \n",
"# File 'lib/maid/tools.rb', line 749\n",
"\n",
"def ignore_child_dirs(arr)\n",
" arr.sort { |x, y|\n",
" y.count('/') - x.count('/')\n",
" }.select { |d|\n",
" !arr.include?(File.dirname(d))\n",
" }\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**last_accessed**(path) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"**Deprecated.**\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Alias of `accessed_at`.\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"526\n",
"527\n",
"528\n",
"529
| \n",
"# File 'lib/maid/tools.rb', line 526\n",
"\n",
"def last_accessed(path)\n",
" # Not a normal `alias` so the deprecation notice shows in the docs.\n",
" accessed_at(path)\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**locate**(name) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"\\[Mac OS X\\] Use Spotlight to locate all files matching the given\n",
"filename.\n",
"\n",
"\\[Ubuntu\\] Use `locate` to locate all files matching the given filename.\n",
"\n",
"## Examples\n",
"\n",
"``` code\n",
"locate('foo.zip') # => ['/a/foo.zip', '/b/foo.zip']\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"346\n",
"347\n",
"348
| \n",
"# File 'lib/maid/tools.rb', line 346\n",
"\n",
"def locate(name)\n",
" cmd("#{Maid::Platform::Commands.locate} #{ sh_escape(name) }").split("\\n")\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**location_city**(path) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Determine the city of the given JPEG image.\n",
"\n",
"## Examples\n",
"\n",
"``` code\n",
"loation_city('old_capitol.jpg') # => \"Iowa City, IA, US\"\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"451\n",
"452\n",
"453\n",
"454\n",
"455\n",
"456\n",
"457\n",
"458\n",
"459
| \n",
"# File 'lib/maid/tools.rb', line 451\n",
"\n",
"def location_city(path)\n",
" case mime_type(path)\n",
" when 'image/jpeg'\n",
" gps = EXIFR::JPEG.new(path).gps\n",
" coordinates_string = [gps.latitude, gps.longitude]\n",
" location = Geocoder.search(coordinates_string).first\n",
" [location.city, location.province, location.country_code].join(', ')\n",
" end\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**media_type**(path) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Get the Internet media type of the file.\n",
"\n",
"In other words, the first part of `mime_type`.\n",
"\n",
"## Examples\n",
"\n",
"``` code\n",
"media_type('bar.jpg') # => \"image\"\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"671\n",
"672\n",
"673\n",
"674\n",
"675\n",
"676\n",
"677
| \n",
"# File 'lib/maid/tools.rb', line 671\n",
"\n",
"def media_type(path)\n",
" type = MIME::Types.type_for(path)[0]\n",
"\n",
" if type\n",
" type.media_type\n",
" end\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**mime_type**(path) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Get the MIME type of the file.\n",
"\n",
"## Examples\n",
"\n",
"``` code\n",
"mime_type('bar.jpg') # => \"image/jpeg\"\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"656\n",
"657\n",
"658\n",
"659\n",
"660\n",
"661\n",
"662
| \n",
"# File 'lib/maid/tools.rb', line 656\n",
"\n",
"def mime_type(path)\n",
" type = MIME::Types.type_for(path)[0]\n",
"\n",
" if type\n",
" [type.media_type, type.sub_type].join('/')\n",
" end\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**mkdir**(path, options = {}) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Create a directory and all of its parent directories.\n",
"\n",
"The path of the created directory is returned, which allows for chaining\n",
"(see examples).\n",
"\n",
"## Options\n",
"\n",
"`:mode`\n",
"\n",
"The symbolic and absolute mode can both be used, for example: `0700`,\n",
"`'u=wr,go=rr'`\n",
"\n",
"## Examples\n",
"\n",
"Creating a directory with a specific mode:\n",
"\n",
"``` code\n",
"mkdir('~/Music/Pink Floyd/', :mode => 0644)\n",
"```\n",
"\n",
"Ensuring a directory exists when moving:\n",
"\n",
"``` code\n",
"move('~/Downloads/Pink Floyd*.mp3', mkdir('~/Music/Pink Floyd/'))\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"300\n",
"301\n",
"302\n",
"303\n",
"304\n",
"305
| \n",
"# File 'lib/maid/tools.rb', line 300\n",
"\n",
"def mkdir(path, options = {})\n",
" path = expand(path)\n",
" log("mkdir -p #{ sh_escape(path) }")\n",
" FileUtils.mkdir_p(path, @file_options.merge(options))\n",
" path\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**modified_at**(path) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Get the modification time of a file.\n",
"\n",
"In Unix speak, `mtime`.\n",
"\n",
"## Examples\n",
"\n",
"``` code\n",
"modified_at('foo.zip') # => Sat Apr 09 10:50:01 -0400 2011\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"539\n",
"540\n",
"541
| \n",
"# File 'lib/maid/tools.rb', line 539\n",
"\n",
"def modified_at(path)\n",
" File.mtime(expand(path))\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**move**(sources, destination) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Move `sources` to a `destination` directory.\n",
"\n",
"Movement is only allowed to directories that already exist. If your\n",
"intention is to rename, see the `rename` method.\n",
"\n",
"## Examples\n",
"\n",
"Single path:\n",
"\n",
"``` code\n",
"move('~/Downloads/foo.zip', '~/Archive/Software/Mac OS X/')\n",
"```\n",
"\n",
"Multiple paths:\n",
"\n",
"``` code\n",
"move(['~/Downloads/foo.zip', '~/Downloads/bar.zip'], '~/Archive/Software/Mac OS X/')\n",
"move(dir('~/Downloads/*.zip'), '~/Archive/Software/Mac OS X/')\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"39\n",
"40\n",
"41\n",
"42\n",
"43\n",
"44\n",
"45\n",
"46\n",
"47\n",
"48\n",
"49\n",
"50\n",
"51
| \n",
"# File 'lib/maid/tools.rb', line 39\n",
"\n",
"def move(sources, destination)\n",
" destination = expand(destination)\n",
"\n",
" if File.directory?(destination)\n",
" expand_all(sources).each do |source|\n",
" log("move #{ sh_escape(source) } #{ sh_escape(destination) }")\n",
" FileUtils.mv(source, destination, @file_options)\n",
" end\n",
" else\n",
" # Unix `mv` warns about the target not being a directory with multiple sources. Maid checks the same.\n",
" warn("skipping move because #{ sh_escape(destination) } is not a directory (use 'mkdir' to create first, or use 'rename')")\n",
" end\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**newest_dupes_in**(globs) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Convenience method that is like `dupes_in` but excludes the oldest dupe.\n",
"\n",
"## Example\n",
"\n",
"Keep the oldest dupe (trash the others):\n",
"\n",
"``` code\n",
"trash newest_dupes_in('~/Downloads/*')\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"411\n",
"412\n",
"413\n",
"414\n",
"415
| \n",
"# File 'lib/maid/tools.rb', line 411\n",
"\n",
"def newest_dupes_in(globs)\n",
" dupes_in(globs).\n",
" map { |dupes| dupes.sort_by { |p| File.mtime(p) }[1..-1] }.\n",
" flatten\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**remove**(paths, options = {}) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Delete the files at the given path recursively.\n",
"\n",
"**NOTE**: In most cases, `trash` is a safer choice, since the files will\n",
"be recoverable by retreiving them from the trash. Once you delete a file\n",
"using `remove`, it's gone! Please use `trash` whenever possible and only\n",
"use `remove` when necessary.\n",
"\n",
"## Options\n",
"\n",
"`:force => boolean`\n",
"\n",
"Force deletion (no error is raised if the file does not exist).\n",
"\n",
"`:secure => boolean`\n",
"\n",
"Infrequently needed. See\n",
"[`FileUtils.remove_entry_secure`](https://www.ruby-doc.org/stdlib-1.9.3/libdoc/fileutils/rdoc/FileUtils.html#method-c-remove_entry_secure)\n",
"\n",
"## Examples\n",
"\n",
"Single path:\n",
"\n",
"``` code\n",
"remove('~/Downloads/foo.zip')\n",
"```\n",
"\n",
"Multiple path:\n",
"\n",
"``` code\n",
"remove(['~/Downloads/foo.zip', '~/Downloads/bar.zip'])\n",
"remove(dir('~/Downloads/*.zip'))\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"204\n",
"205\n",
"206\n",
"207\n",
"208\n",
"209\n",
"210\n",
"211
| \n",
"# File 'lib/maid/tools.rb', line 204\n",
"\n",
"def remove(paths, options = {})\n",
" expand_all(paths).each do |path|\n",
" options = @file_options.merge(options)\n",
"\n",
" log("Removing #{ sh_escape(path) }")\n",
" FileUtils.rm_r(path, options)\n",
" end\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**rename**(source, destination) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Rename a single file.\n",
"\n",
"Any directories needed in order to complete the rename are made\n",
"automatically.\n",
"\n",
"Overwriting is not allowed; it logs a warning. If overwriting is\n",
"desired, use `remove` to delete the file first, then use `rename`.\n",
"\n",
"## Examples\n",
"\n",
"Simple rename:\n",
"\n",
"``` code\n",
"rename('foo.zip', 'baz.zip') # \"foo.zip\" becomes \"baz.zip\"\n",
"```\n",
"\n",
"Rename needing directories:\n",
"\n",
"``` code\n",
"rename('foo.zip', 'bar/baz.zip') # \"bar\" is created, \"foo.zip\" becomes \"baz.zip\" within \"bar\"\n",
"```\n",
"\n",
"Attempting to overwrite:\n",
"\n",
"``` code\n",
"rename('foo.zip', 'existing.zip') # \"skipping move of...\"\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"72\n",
"73\n",
"74\n",
"75\n",
"76\n",
"77\n",
"78\n",
"79\n",
"80\n",
"81\n",
"82\n",
"83\n",
"84
| \n",
"# File 'lib/maid/tools.rb', line 72\n",
"\n",
"def rename(source, destination)\n",
" source = expand(source)\n",
" destination = expand(destination)\n",
"\n",
" mkdir(File.dirname(destination))\n",
"\n",
" if File.exist?(destination)\n",
" warn("skipping rename of #{ sh_escape(source) } to #{ sh_escape(destination) } because it would overwrite")\n",
" else\n",
" log("rename #{ sh_escape(source) } #{ sh_escape(destination) }")\n",
" FileUtils.mv(source, destination, @file_options)\n",
" end\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**size_of**(path) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Get the size of a file.\n",
"\n",
"## Examples\n",
"\n",
"``` code\n",
"size_of('foo.zip') # => 2193\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"548\n",
"549\n",
"550
| \n",
"# File 'lib/maid/tools.rb', line 548\n",
"\n",
"def size_of(path)\n",
" File.size(path)\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**spotlight_content_types**(path) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"\\[Mac OS X\\] Use Spotlight metadata to determine which content types a\n",
"file has.\n",
"\n",
"## Examples\n",
"\n",
"``` code\n",
"spotlight_content_types('foo.zip') # => ['public.zip-archive', 'public.archive']\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"635\n",
"636\n",
"637
| \n",
"# File 'lib/maid/tools.rb', line 635\n",
"\n",
"def spotlight_content_types(path)\n",
" mdls_to_array(path, 'kMDItemContentTypeTree')\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**sync**(from, to, options = {}) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Simple sync two files/folders using `rsync`.\n",
"\n",
"The host OS must provide `rsync`. See the `rsync` man page for a\n",
"detailed description.\n",
"\n",
"``` code\n",
"man rsync\n",
"```\n",
"\n",
"## Options\n",
"\n",
"`:delete => boolean` `:verbose => boolean` `:archive => boolean`\n",
"(default `true`) `:update => boolean` (default `true`)\n",
"`:exclude => string` `:prune_empty => boolean`\n",
"\n",
"## Examples\n",
"\n",
"Syncing a directory to a backup:\n",
"\n",
"``` code\n",
"sync('~/music', '/backup/music')\n",
"```\n",
"\n",
"Excluding a path:\n",
"\n",
"``` code\n",
"sync('~/code', '/backup/code', :exclude => '.git')\n",
"```\n",
"\n",
"Excluding multiple paths:\n",
"\n",
"``` code\n",
"sync('~/code', '/backup/code', :exclude => ['.git', '.rvmrc'])\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"607\n",
"608\n",
"609\n",
"610\n",
"611\n",
"612\n",
"613\n",
"614\n",
"615\n",
"616\n",
"617\n",
"618\n",
"619\n",
"620\n",
"621\n",
"622\n",
"623\n",
"624\n",
"625\n",
"626\n",
"627\n",
"628
| \n",
"# File 'lib/maid/tools.rb', line 607\n",
"\n",
"def sync(from, to, options = {})\n",
" # expand removes trailing slash\n",
" # cannot use str[-1] due to ruby 1.8.7 restriction\n",
" from = expand(from) + (from.end_with?('/') ? '/' : '')\n",
" to = expand(to) + (to.end_with?('/') ? '/' : '')\n",
" # default options\n",
" options = { :archive => true, :update => true }.merge(options)\n",
" ops = []\n",
" ops << '-a' if options[:archive]\n",
" ops << '-v' if options[:verbose]\n",
" ops << '-u' if options[:update]\n",
" ops << '-m' if options[:prune_empty]\n",
" ops << '-n' if @file_options[:noop]\n",
"\n",
" Array(options[:exclude]).each do |path|\n",
" ops << "--exclude=#{ sh_escape(path) }"\n",
" end\n",
"\n",
" ops << '--delete' if options[:delete]\n",
" stdout = cmd("rsync #{ ops.join(' ') } #{ sh_escape(from) } #{ sh_escape(to) } 2>&1")\n",
" log("Fired sync from #{ sh_escape(from) } to #{ sh_escape(to) }. STDOUT:\\n\\n#{ stdout }")\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**trash**(paths, options = {}) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Move the given paths to the user's trash.\n",
"\n",
"The path is still moved if a file already exists in the trash with the\n",
"same name. However, the current date and time is appended to the\n",
"filename.\n",
"\n",
"**Note:** the OS-native \"restore\" or \"put back\" functionality for\n",
"trashed files is not currently supported. (See [issue\n",
"\\#63](https://github.com/benjaminoakes/maid/issues/63).) However, they\n",
"can be restored manually, and the Maid log can help assist with this.\n",
"\n",
"## Options\n",
"\n",
"`:remove_over => Fixnum` (e.g. `1.gigabyte`, `1024.megabytes`)\n",
"\n",
"Delete files over the given size rather than moving to the trash.\n",
"\n",
"See also `Maid::NumericExtensions::SizeToKb`\n",
"\n",
"## Examples\n",
"\n",
"Single path:\n",
"\n",
"``` code\n",
"trash('~/Downloads/foo.zip')\n",
"```\n",
"\n",
"Multiple paths:\n",
"\n",
"``` code\n",
"trash(['~/Downloads/foo.zip', '~/Downloads/bar.zip'])\n",
"trash(dir('~/Downloads/*.zip'))\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"113\n",
"114\n",
"115\n",
"116\n",
"117\n",
"118\n",
"119\n",
"120\n",
"121\n",
"122\n",
"123\n",
"124\n",
"125\n",
"126\n",
"127\n",
"128\n",
"129\n",
"130\n",
"131\n",
"132\n",
"133\n",
"134\n",
"135\n",
"136\n",
"137\n",
"138\n",
"139\n",
"140\n",
"141\n",
"142\n",
"143\n",
"144\n",
"145\n",
"146\n",
"147
| \n",
"# File 'lib/maid/tools.rb', line 113\n",
"\n",
"def trash(paths, options = {})\n",
" # ## Implementation Notes\n",
" #\n",
" # Trashing files correctly is surprisingly hard. What Maid ends up doing is one the easiest, most foolproof\n",
" # solutions: moving the file.\n",
" #\n",
" # Unfortunately, that means it's not possile to restore files automatically in OSX or Ubuntu. The previous location\n",
" # of the file is lost.\n",
" #\n",
" # OSX support depends on AppleScript or would require a not-yet-written C extension to interface with the OS. The\n",
" # AppleScript solution is less than ideal: the user has to be logged in, Finder has to be running, and it makes the\n",
" # "trash can sound" every time a file is moved.\n",
" #\n",
" # Ubuntu makes it easy to implement, and there's a Python library for doing so (see `trash-cli`). However, there's\n",
" # not a Ruby equivalent yet.\n",
"\n",
" expand_all(paths).each do |path|\n",
" target = File.join(@trash_path, File.basename(path))\n",
" safe_trash_path = File.join(@trash_path, "#{ File.basename(path) } #{ Time.now.strftime('%Y-%m-%d-%H-%M-%S') }")\n",
"\n",
" if options[:remove_over] &&\n",
" File.exist?(path) &&\n",
" disk_usage(path) > options[:remove_over]\n",
" remove(path)\n",
" end\n",
"\n",
" if File.exist?(path)\n",
" if File.exist?(target)\n",
" rename(path, safe_trash_path)\n",
" else\n",
" move(path, @trash_path)\n",
" end\n",
" end\n",
" end\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**tree_empty?**(root) ⇒ Boolean\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Test whether a directory is either empty, or contains only empty\n",
"directories/subdirectories.\n",
"\n",
"## Example\n",
"\n",
"``` code\n",
"if tree_empty?(dir('~/Downloads/foo'))\n",
" trash('~/Downloads/foo')\n",
"end\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Returns:\n",
"\n",
"- (Boolean)\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"714\n",
"715\n",
"716\n",
"717\n",
"718\n",
"719\n",
"720\n",
"721\n",
"722\n",
"723\n",
"724\n",
"725\n",
"726\n",
"727\n",
"728\n",
"729\n",
"730\n",
"731\n",
"732\n",
"733\n",
"734\n",
"735\n",
"736\n",
"737\n",
"738\n",
"739\n",
"740\n",
"741
| \n",
"# File 'lib/maid/tools.rb', line 714\n",
"\n",
"def tree_empty?(root)\n",
" return nil if File.file?(root)\n",
" return true if Dir.glob(root + '/*').length == 0\n",
"\n",
" ignore = []\n",
"\n",
" # Look for files.\n",
" return false if Dir.glob(root + '/*').select { |f| File.file?(f) }.length > 0\n",
"\n",
" empty_dirs = Dir.glob(root + '/**/*').select { |d|\n",
" File.directory?(d)\n",
" }.reverse.select { |d|\n",
" # `.reverse` sorts deeper directories first.\n",
"\n",
" # If the directory is empty, its parent should ignore it.\n",
" should_ignore = Dir.glob(d + '/*').select { |n|\n",
" !ignore.include?(n)\n",
" }.length == 0\n",
"\n",
" ignore << d if should_ignore\n",
"\n",
" should_ignore\n",
" }\n",
"\n",
" Dir.glob(root + '/*').select { |n|\n",
" !empty_dirs.include?(n)\n",
" }.length == 0\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**verbose_dupes_in**(globs) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Convenience method for `dupes_in` that excludes the dupe with the\n",
"shortest name.\n",
"\n",
"This is ideal for dupes like `foo.zip`, `foo (1).zip`, `foo copy.zip`.\n",
"\n",
"## Example\n",
"\n",
"Keep the dupe with the shortest name (trash the others):\n",
"\n",
"``` code\n",
"trash verbose_dupes_in('~/Downloads/*')\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"427\n",
"428\n",
"429\n",
"430\n",
"431
| \n",
"# File 'lib/maid/tools.rb', line 427\n",
"\n",
"def verbose_dupes_in(globs)\n",
" dupes_in(globs).\n",
" map { |dupes| dupes.sort_by { |p| File.basename(p).length }[1..-1] }.\n",
" flatten\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**where_content_type**(paths, filter_types) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"Filter an array by content types.\n",
"\n",
"Content types can be MIME types, internet media types or Spotlight\n",
"content types (OS X only).\n",
"\n",
"If you need your rules to work on multiple platforms, it's recommended\n",
"to avoid using Spotlight content types.\n",
"\n",
"## Examples\n",
"\n",
"### Using media types\n",
"\n",
"``` code\n",
"where_content_type(dir('~/Downloads/*'), 'video')\n",
"where_content_type(dir('~/Downloads/*'), ['image', 'audio'])\n",
"```\n",
"\n",
"### Using MIME types\n",
"\n",
"``` code\n",
"where_content_type(dir('~/Downloads/*'), 'image/jpeg')\n",
"```\n",
"\n",
"### Using Spotlight content types\n",
"\n",
"Less portable, but richer data in some cases.\n",
"\n",
"``` code\n",
"where_content_type(dir('~/Downloads/*'), 'public.image')\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"701\n",
"702\n",
"703\n",
"704
| \n",
"# File 'lib/maid/tools.rb', line 701\n",
"\n",
"def where_content_type(paths, filter_types)\n",
" filter_types = Array(filter_types)\n",
" Array(paths).select { |p| !(filter_types & content_types(p)).empty? }\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"###
permalink \\#**zipfile_contents**(path) ⇒ Object\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"List the contents of a zip file.\n",
"\n",
"## Examples\n",
"\n",
"``` code\n",
"zipfile_contents('foo.zip') # => ['foo.exe', 'README.txt', 'subdir/anything.txt']\n",
"```\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\\[View source\\]\n",
"\n",
"
\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"475\n",
"476\n",
"477\n",
"478\n",
"479\n",
"480
| \n",
"# File 'lib/maid/tools.rb', line 475\n",
"\n",
"def zipfile_contents(path)\n",
" # It might be nice to use `glob` from `Zip::FileSystem`, but it seems buggy. (Subdirectories aren't included.)\n",
" Zip::File.open(path) do |zip_file|\n",
" zip_file.entries.map { |entry| entry.name }.sort\n",
" end\n",
"end
| \n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"
\n",
"\n",
"