macos-tags 0.1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 82c78fd9522862d6b9cb20ab934d95a3fa360149aa65407cd2cafd6dcd4147ce
4
+ data.tar.gz: 20ce035ae6cf80790deb97a309374093df9ecc6bf34935a2711e0702daae0d7b
5
+ SHA512:
6
+ metadata.gz: 3029529f13d354ba29bcc84066200a4674fe9b685e63e9573592e18045866bb3daf45f224fbc6d1985c2985cfdf73f366fc3ead2625edbabb2172d67a12187fe
7
+ data.tar.gz: 1ef9c59fa9c593325c831e5225e410bd72001525f2c719a8a3648ebc61808cb24e3ecb0f804433b1246ddadbb87b5253c1a6cb023a028e260f87b0915cf3d50d
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ Gemfile.lock
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.0
data/CHANGELOG.md ADDED
@@ -0,0 +1,9 @@
1
+ # Changelog
2
+
3
+ ## [0.1.0] - 2021-05-06
4
+
5
+ ### Added
6
+ - Find all tags in the system
7
+ - Find all tags on a file
8
+ - Find files by tag
9
+ - Release the initial version to rubygems.org
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
data/LICENSE.md ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2021 Nice cabbage LLC
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,82 @@
1
+ # macos-tags
2
+
3
+ Port of [dmkskn/macos-tags](https://github.com/dmkskn/macos-tags) to Ruby
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'macos-tags'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ ```shell
16
+ $ bundle install
17
+ ```
18
+
19
+ Or install it yourself as:
20
+
21
+ ```shell
22
+ $ gem install macos-tags
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ ```ruby
28
+ require 'macos-tags'
29
+ ```
30
+
31
+ ### Get all tags
32
+
33
+ ```ruby
34
+ MacosTags.all_tags
35
+ => [
36
+ #<struct MacosTags::Tag label="Urgent", color=#<MacosTags::Color @name="yellow" @value=5>>,
37
+ ]
38
+ ```
39
+
40
+ ### Find files by tag
41
+
42
+ ```ruby
43
+ > MacosTags.find_files(tag: "Urgent")
44
+ => [
45
+ "files"...
46
+ ]
47
+ ```
48
+
49
+ ### Count files by tag
50
+
51
+ ```ruby
52
+ > MacosTags.count(tag: "Urgent")
53
+ => 22
54
+ ```
55
+
56
+ ### List tags on the file
57
+
58
+
59
+ ```ruby
60
+ MacosTags.tags(file: "/Users/me/Documents/note.txt")
61
+ =>
62
+ [
63
+ #<struct MacosTags::Tag label="Urgent", color=#<MacosTags::Color @name="red" @value=6>>,
64
+ #<struct MacosTags::Tag label="Important", color=#<MacosTags::Color @name="yellow" @value=5>>
65
+ ]
66
+ ```
67
+
68
+ ## TODOs
69
+
70
+ - [ ] Enable it to add tags
71
+ - [ ] Enable it to remove tags
72
+
73
+ ## Development
74
+
75
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
76
+
77
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
78
+
79
+ ## Contributing
80
+
81
+ Bug reports and pull requests are welcome on GitHub at https://github.com/tomoya55/macos-tags.
82
+
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ require 'rake/testtask'
2
+ require 'bundler'
3
+
4
+ Bundler::GemHelper.install_tasks
5
+
6
+ task default: [:test]
7
+
8
+ Rake::TestTask.new do |test|
9
+ # test.libs << "tests"
10
+ # test.libs << "lib"
11
+ test.test_files = Dir['tests/**/test_*.rb']
12
+ test.verbose = true
13
+ end
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "macos-tags"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/lib/macos-tags.rb ADDED
@@ -0,0 +1,135 @@
1
+ require 'ffi-xattr'
2
+ require 'cfpropertylist'
3
+ require 'shellwords'
4
+
5
+ module MacosTags
6
+ XATTR_TAGS = "com.apple.metadata:_kMDItemUserTags"
7
+ XATTR_FINDER_INFO = "com.apple.FinderInfo"
8
+ ALL_TAGS_PLIST_PATH = "#{Dir.home}/Library/SyncedPreferences/com.apple.finder.plist"
9
+
10
+ class Color
11
+ DEFINITIONS = {
12
+ none: 0,
13
+ gray: 1,
14
+ green: 2,
15
+ purple: 3,
16
+ blue: 4,
17
+ yellow: 5,
18
+ red: 6,
19
+ orange: 7,
20
+ }
21
+
22
+ attr_reader :name, :value
23
+
24
+ def initialize(_value)
25
+ @name, @value = DEFINITIONS.find { |k,v| v == _value } || [:none, 0]
26
+ end
27
+
28
+ def inspect
29
+ "#<MacosTags::Color @name=\"#{name}\" @value=#{value}>"
30
+ end
31
+ end
32
+
33
+ def all_tags
34
+ FinderPlist.new.tags
35
+ end
36
+ module_function :all_tags
37
+
38
+ def find_files(tag:)
39
+ Mdfinder.find_files(tag_name: tag)
40
+ end
41
+ module_function :find_files
42
+
43
+ def count(tag:)
44
+ Mdfinder.count(tag_name: tag)
45
+ end
46
+ module_function :count
47
+
48
+ def tags(file:)
49
+ TagParser.new(file).tags
50
+ end
51
+ module_function :tags
52
+
53
+ class Mdfinder
54
+ def self.count(tag_name:)
55
+ new.count(tag_name: tag_name)
56
+ end
57
+
58
+ def self.find_files(tag_name:)
59
+ new.find_files(tag_name: tag_name)
60
+ end
61
+
62
+ def count(tag_name:)
63
+ _count(tag_query(tag_name))
64
+ end
65
+
66
+ def find_files(tag_name:)
67
+ _query(tag_query(tag_name))
68
+ end
69
+
70
+ private
71
+
72
+ def _count(query)
73
+ ret = _query("-count", query)
74
+ ret[0].to_i
75
+ end
76
+
77
+ def _query(*params)
78
+ `mdfind #{Shellwords.join(params)}`.split("\n")
79
+ end
80
+
81
+ def tag_query(tag)
82
+ "kMDItemUserTags == \"#{tag}\""
83
+ end
84
+ end
85
+
86
+ class Tag < Struct.new(:label, :color, keyword_init: true)
87
+ end
88
+
89
+ class FinderPlist
90
+ attr_reader :plist
91
+ def initialize
92
+ @plist = CFPropertyList::List.new
93
+ load
94
+ end
95
+
96
+ def tags
97
+ parse_find_tags.map do |v|
98
+ Tag.new(label: v.value["n"].value, color: Color.new(v.value["l"].value))
99
+ end
100
+ end
101
+
102
+ private
103
+
104
+ def load
105
+ plist.load_binary(ALL_TAGS_PLIST_PATH)
106
+ end
107
+
108
+ def parse_find_tags
109
+ plist.value.value["values"].value["FinderTagDict"].value["value"].value["FinderTags"].value
110
+ rescue
111
+ []
112
+ end
113
+ end
114
+
115
+ class TagParser
116
+ attr_reader :xattr, :plist
117
+ def initialize(file)
118
+ @xattr = Xattr.new(file)
119
+ @plist = CFPropertyList::List.new
120
+ end
121
+
122
+ def tags
123
+ parse_raw_tags.value.map do |raw_tag|
124
+ label, color_val = raw_tag.value.split("\n")
125
+ Tag.new(label: label, color: Color.new(color_val.to_i))
126
+ end
127
+ end
128
+
129
+ private
130
+
131
+ def parse_raw_tags
132
+ plist.load_binary_str(xattr[XATTR_TAGS])
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,3 @@
1
+ module MacosTags
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,34 @@
1
+ require_relative 'lib/macos-tags/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "macos-tags"
5
+ spec.version = MacosTags::VERSION
6
+ spec.authors = ["Tomoya Hirano"]
7
+ spec.email = ["hiranotomoya@gmail.com"]
8
+
9
+ spec.summary = %q{Ruby interface to get macos Finder tags}
10
+ spec.description = %q{Ruby interface to get macos Finder tags}
11
+ spec.homepage = "https://github.com/tomoya55/macos-tags"
12
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
13
+
14
+ spec.metadata["allowed_push_host"] = "https://rubygems.org/"
15
+
16
+ spec.metadata["homepage_uri"] = spec.homepage
17
+ spec.metadata["source_code_uri"] = spec.homepage
18
+ spec.metadata["changelog_uri"] = "https://github.com/tomoya55/macos-tags/blob/main/CHANGELOG.md"
19
+
20
+ # Specify which files should be added to the gem when it is released.
21
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
22
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
23
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
24
+ end
25
+ spec.bindir = "bin"
26
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
27
+ spec.require_paths = ["lib"]
28
+ spec.add_dependency "ffi-xattr"
29
+ spec.add_dependency "CFPropertyList"
30
+ spec.add_dependency "rexml"
31
+
32
+ spec.add_development_dependency "rake"
33
+ spec.add_development_dependency "minitest"
34
+ end
@@ -0,0 +1,5 @@
1
+ require 'minitest/autorun'
2
+
3
+ Dir.glob(File.join(File.dirname(__FILE__), '..', 'lib', '**', '*.rb')) do |f|
4
+ require_relative f
5
+ end
@@ -0,0 +1,9 @@
1
+ require_relative './test_helper'
2
+
3
+ describe MacosTags do
4
+ describe ".all_tags" do
5
+ it "must returns tags list" do
6
+ _(MacosTags.all_tags).must_be_kind_of(Array)
7
+ end
8
+ end
9
+ end
metadata ADDED
@@ -0,0 +1,132 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: macos-tags
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Tomoya Hirano
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-05-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ffi-xattr
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: CFPropertyList
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rexml
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Ruby interface to get macos Finder tags
84
+ email:
85
+ - hiranotomoya@gmail.com
86
+ executables:
87
+ - console
88
+ - setup
89
+ extensions: []
90
+ extra_rdoc_files: []
91
+ files:
92
+ - ".gitignore"
93
+ - ".ruby-version"
94
+ - CHANGELOG.md
95
+ - Gemfile
96
+ - LICENSE.md
97
+ - README.md
98
+ - Rakefile
99
+ - bin/console
100
+ - bin/setup
101
+ - lib/macos-tags.rb
102
+ - lib/macos-tags/version.rb
103
+ - macos-tags.gemspec
104
+ - tests/test_helper.rb
105
+ - tests/test_macos_tags.rb
106
+ homepage: https://github.com/tomoya55/macos-tags
107
+ licenses: []
108
+ metadata:
109
+ allowed_push_host: https://rubygems.org/
110
+ homepage_uri: https://github.com/tomoya55/macos-tags
111
+ source_code_uri: https://github.com/tomoya55/macos-tags
112
+ changelog_uri: https://github.com/tomoya55/macos-tags/blob/main/CHANGELOG.md
113
+ post_install_message:
114
+ rdoc_options: []
115
+ require_paths:
116
+ - lib
117
+ required_ruby_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: 2.3.0
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ requirements: []
128
+ rubygems_version: 3.2.15
129
+ signing_key:
130
+ specification_version: 4
131
+ summary: Ruby interface to get macos Finder tags
132
+ test_files: []