spotlight 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 youpy
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.rdoc ADDED
@@ -0,0 +1,33 @@
1
+ = spotlight
2
+
3
+ Description goes here.
4
+
5
+ == Synopsis
6
+
7
+ require 'spotlight'
8
+
9
+ === Finds files matching a given query
10
+
11
+ query = Spotlight::Query.new('kMDItemKind = "JPEG image" && kMDItemPixelHeight > 2000')
12
+ query.execute.map {|item|
13
+ puts item.get(:kMDItemPath)
14
+ }
15
+
16
+ === Gets the metadata attributes for the specified file
17
+
18
+ item = Spotlight::Item.new('/Users/youpy/foo')
19
+ item.get(:kMDItemKind)
20
+
21
+ == Note on Patches/Pull Requests
22
+
23
+ * Fork the project.
24
+ * Make your feature addition or bug fix.
25
+ * Add tests for it. This is important so I don't break it in a
26
+ future version unintentionally.
27
+ * Commit, do not mess with rakefile, version, or history.
28
+ (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)
29
+ * Send me a pull request. Bonus points for topic branches.
30
+
31
+ == Copyright
32
+
33
+ Copyright (c) 2010 youpy. See LICENSE for details.
@@ -0,0 +1,7 @@
1
+ require "mkmf"
2
+ require "rbconfig"
3
+
4
+ $LDFLAGS += ' -framework CoreFoundation -framework CoreServices'
5
+
6
+ have_header("md_item_native")
7
+ create_makefile("md_item_native")
@@ -0,0 +1,107 @@
1
+ #include "md_item_native.h"
2
+
3
+ static VALUE rb_cMDItemNative;
4
+
5
+ struct ItemObject {
6
+ MDItemRef item;
7
+ };
8
+
9
+ CFStringRef CString2CFString(char *str) {
10
+ return CFStringCreateWithCString(kCFAllocatorDefault,
11
+ str,
12
+ CFStringGetSystemEncoding());
13
+ }
14
+
15
+ MDItemRef getItem(VALUE obj) {
16
+ struct ItemObject *itemObject;
17
+
18
+ Data_Get_Struct(obj, struct ItemObject, itemObject);
19
+ return itemObject->item;
20
+ }
21
+
22
+ void cMDItemNative_free(void *ptr) {
23
+ MDItemRef item = (MDItemRef)(((struct ItemObject *)ptr)->item);
24
+
25
+ if(item != NULL) {
26
+ CFRelease(item);
27
+ }
28
+
29
+ free(ptr);
30
+ /* printf("cMDItemNative_free()\n"); */
31
+ }
32
+
33
+ VALUE createInstanceFromMDItem(MDItemRef item) {
34
+ struct ItemObject *itemObject;
35
+
36
+ itemObject = malloc(sizeof(struct ItemObject));
37
+ itemObject->item = item;
38
+
39
+ return Data_Wrap_Struct(rb_cMDItemNative, 0, cMDItemNative_free, itemObject);
40
+ }
41
+
42
+ static VALUE cMDItemNative_new(int argc, VALUE *argv, VALUE klass)
43
+ {
44
+ VALUE filename, obj;
45
+ MDItemRef item;
46
+ CFStringRef cfFilename;
47
+
48
+ rb_scan_args(argc, argv, "1", &filename);
49
+
50
+ cfFilename = CString2CFString(StringValuePtr(filename));
51
+ item = MDItemCreate(kCFAllocatorDefault, cfFilename);
52
+
53
+ if(item != NULL) {
54
+ obj = createInstanceFromMDItem(item);
55
+ } else {
56
+ rb_raise(rb_eArgError, "no such file or directory");
57
+ }
58
+
59
+ CFRelease(cfFilename);
60
+
61
+ return obj;
62
+ }
63
+
64
+ static VALUE cMDItemNative_get(int argc, VALUE *argv, VALUE self)
65
+ {
66
+ MDItemRef item = getItem(self);
67
+ CFStringRef itemValue, cfAttrName;
68
+ VALUE attrName, result;
69
+ char *tmpptr;
70
+ int stringSize;
71
+
72
+ rb_scan_args(argc, argv, "1", &attrName);
73
+
74
+ if(TYPE(attrName) == T_SYMBOL) {
75
+ cfAttrName = (CFStringRef)CString2CFString(rb_id2name(SYM2ID(attrName)));
76
+ } else {
77
+ cfAttrName = (CFStringRef)CString2CFString(StringValuePtr(attrName));
78
+ }
79
+
80
+ itemValue = (CFStringRef)MDItemCopyAttribute(item, cfAttrName);
81
+
82
+ if(itemValue != NULL) {
83
+ stringSize = CFStringGetMaximumSizeForEncoding(CFStringGetLength(itemValue), kCFStringEncodingUTF8) + 1;
84
+ tmpptr = (char *)malloc(sizeof(char) * stringSize);
85
+
86
+ CFStringGetCString(itemValue, tmpptr, stringSize, kCFStringEncodingUTF8);
87
+
88
+ result = rb_str_new2(tmpptr);
89
+
90
+ free(tmpptr);
91
+ CFRelease(cfAttrName);
92
+ CFRelease(itemValue);
93
+ } else {
94
+ return Qnil;
95
+ }
96
+
97
+ return result;
98
+ }
99
+
100
+ void Init_md_item_native(void){
101
+ VALUE rb_mSpotlight;
102
+
103
+ rb_mSpotlight = rb_define_module("Spotlight");
104
+ rb_cMDItemNative = rb_define_class_under(rb_mSpotlight, "MDItemNative", rb_cObject);
105
+ rb_define_singleton_method(rb_cMDItemNative, "new", cMDItemNative_new, -1);
106
+ rb_define_method(rb_cMDItemNative, "get", cMDItemNative_get, -1);
107
+ }
@@ -0,0 +1,9 @@
1
+ #ifndef MD_ITEM_NATIVE_H
2
+ #define MD_ITEM_NATIVE_H
3
+
4
+ #include <ruby.h>
5
+ #include </System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/Metadata.framework/Versions/A/Headers/MDItem.h>
6
+
7
+ VALUE createInstanceFromMDItem(MDItemRef item);
8
+
9
+ #endif
@@ -0,0 +1,6 @@
1
+ require "mkmf"
2
+ require "rbconfig"
3
+
4
+ $LDFLAGS += ' -framework CoreFoundation -framework CoreServices'
5
+
6
+ create_makefile("md_query_native")
@@ -0,0 +1,112 @@
1
+ #include <ruby.h>
2
+ #include </System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/Metadata.framework/Versions/A/Headers/MDQuery.h>
3
+ #include "../md_item_native/md_item_native.h"
4
+
5
+ struct QueryObject {
6
+ CFStringRef queryString;
7
+ MDQueryRef query;
8
+ };
9
+
10
+ CFStringRef CString2CFString(char *str) {
11
+ return CFStringCreateWithCString(kCFAllocatorDefault,
12
+ str,
13
+ CFStringGetSystemEncoding());
14
+ }
15
+
16
+ MDQueryRef getQuery(VALUE obj) {
17
+ struct QueryObject *queryObject;
18
+
19
+ Data_Get_Struct(obj, struct QueryObject, queryObject);
20
+ return queryObject->query;
21
+ }
22
+
23
+ void cMDQueryNative_free(void *ptr) {
24
+ MDQueryRef query = (MDQueryRef)(((struct QueryObject *)ptr)->query);
25
+ CFStringRef queryString = (CFStringRef)(((struct QueryObject *)ptr)->queryString);
26
+
27
+ if(query != NULL) {
28
+ CFRelease(query);
29
+ }
30
+
31
+ if(queryString != NULL) {
32
+ CFRelease(queryString);
33
+ }
34
+
35
+ free(ptr);
36
+ /* printf("cMDQueryNative_free()\n"); */
37
+ }
38
+
39
+ static VALUE cMDQueryNative_new(int argc, VALUE *argv, VALUE klass)
40
+ {
41
+ VALUE queryString;
42
+ VALUE obj;
43
+
44
+ rb_scan_args(argc, argv, "1", &queryString);
45
+
46
+ struct QueryObject *q = malloc(sizeof(struct QueryObject));
47
+ q->queryString = CString2CFString(StringValuePtr(queryString));
48
+ q->query = MDQueryCreate(kCFAllocatorDefault, q->queryString, NULL, NULL);
49
+ obj = Data_Wrap_Struct(klass, 0, cMDQueryNative_free, q);
50
+
51
+ return obj;
52
+ }
53
+
54
+ static VALUE cMDQueryNative_set_search_scopes(int argc, VALUE *argv, VALUE self)
55
+ {
56
+ VALUE scopes;
57
+ CFStringRef *itemsList;
58
+ CFArrayRef scopesList;
59
+ int i;
60
+
61
+ rb_scan_args(argc, argv, "1", &scopes);
62
+ itemsList = (CFStringRef *)malloc(sizeof(CFStringRef) * (RARRAY(scopes)->len));
63
+
64
+ for(i = 0; i < RARRAY(scopes)->len; i ++) {
65
+ itemsList[i] = (CFStringRef)CString2CFString(StringValuePtr(RARRAY(scopes)->ptr[i]));
66
+ }
67
+
68
+ scopesList = CFArrayCreate(kCFAllocatorDefault,
69
+ (const void**)itemsList,
70
+ RARRAY(scopes)->len,
71
+ NULL);
72
+ MDQuerySetSearchScope(getQuery(self), scopesList, 0);
73
+
74
+ CFRelease(scopesList);
75
+ free(itemsList);
76
+
77
+ return self;
78
+ }
79
+
80
+ static VALUE cMDQueryNative_execute(int argc, VALUE *argv, VALUE self)
81
+ {
82
+ MDQueryRef query = getQuery(self);
83
+ MDItemRef item;
84
+ VALUE result = rb_ary_new();
85
+ VALUE rItem;
86
+ int resultCount, i;
87
+
88
+ MDQueryExecute(query, kMDQuerySynchronous);
89
+ MDQueryStop(query);
90
+ resultCount = MDQueryGetResultCount(query);
91
+ for(i = 0; i < resultCount; i ++) {
92
+ item = (MDItemRef)MDQueryGetResultAtIndex(query, i);
93
+ if(item != NULL) {
94
+ CFRetain(item);
95
+ rItem = createInstanceFromMDItem(item);
96
+ rb_ary_push(result, rItem);
97
+ }
98
+ }
99
+
100
+ return result;
101
+ }
102
+
103
+ void Init_md_query_native(void){
104
+ VALUE rb_mSpotlight;
105
+ VALUE rb_cMDQueryNative;
106
+
107
+ rb_mSpotlight = rb_define_module("Spotlight");
108
+ rb_cMDQueryNative = rb_define_class_under(rb_mSpotlight, "MDQueryNative", rb_cObject);
109
+ rb_define_singleton_method(rb_cMDQueryNative, "new", cMDQueryNative_new, -1);
110
+ rb_define_method(rb_cMDQueryNative, "set_search_scopes", cMDQueryNative_set_search_scopes, -1);
111
+ rb_define_method(rb_cMDQueryNative, "execute", cMDQueryNative_execute, -1);
112
+ }
@@ -0,0 +1,17 @@
1
+ module Spotlight
2
+ class Query
3
+ attr_reader :query_string
4
+ attr_accessor :scopes
5
+
6
+ def initialize(query_string)
7
+ @query_string = query_string
8
+ @scopes = []
9
+ end
10
+
11
+ def execute
12
+ @md_query = MDQueryNative.new(query_string)
13
+ @md_query.set_search_scopes(@scopes)
14
+ @md_query.execute
15
+ end
16
+ end
17
+ end
data/lib/spotlight.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'md_query_native'
2
+ require 'md_item_native'
3
+ require 'spotlight/query'
4
+
5
+ module Spotlight
6
+ Item = MDItemNative
7
+ end
@@ -0,0 +1,20 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Spotlight::MDItemNative do
4
+ before do
5
+ @query = Spotlight::MDItemNative.new(__FILE__)
6
+ end
7
+
8
+ it "should instanciate" do
9
+ @query.should be_an_instance_of(Spotlight::MDItemNative)
10
+ end
11
+
12
+ it "should get attribute by name" do
13
+ @query.get('kMDItemKind').should eql('Ruby Source File')
14
+ @query.get(:kMDItemKind).should eql('Ruby Source File')
15
+ end
16
+
17
+ it "should get nil if attribute is not found" do
18
+ @query.get('kMDXXXXXX').should be_nil
19
+ end
20
+ end
@@ -0,0 +1,16 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Spotlight::MDQueryNative do
4
+ before do
5
+ @query = Spotlight::MDQueryNative.new('kMDItemDisplayName = "*_spec.rb"cdw')
6
+ end
7
+
8
+ it "should instanciate" do
9
+ @query.should be_an_instance_of(Spotlight::MDQueryNative)
10
+ end
11
+
12
+ it "should execute" do
13
+ @query.set_search_scopes([File.expand_path(File.dirname(__FILE__))]);
14
+ @query.execute.first.should be_an_instance_of(Spotlight::MDItemNative)
15
+ end
16
+ end
@@ -0,0 +1,9 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'spotlight'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+
7
+ Spec::Runner.configure do |config|
8
+
9
+ end
@@ -0,0 +1,28 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Spotlight::Query do
4
+ before do
5
+ @query = Spotlight::Query.new('kMDItemDisplayName = "spotlight_query_spec.rb"')
6
+ end
7
+
8
+ it "should have query string" do
9
+ @query.query_string.should eql('kMDItemDisplayName = "spotlight_query_spec.rb"')
10
+ end
11
+
12
+ it "should execute query" do
13
+ @query.scopes << File.expand_path(File.dirname(__FILE__))
14
+ result = @query.execute
15
+ result.size.should eql(1)
16
+ result.first.should be_an_instance_of(Spotlight::MDItemNative)
17
+ result.first.get(:kMDItemPath).should eql(File.expand_path(File.dirname(__FILE__) + '/spotlight_query_spec.rb'))
18
+
19
+ @query.scopes = ['/tmp/xxx/yyy']
20
+ result = @query.execute
21
+ result.should be_empty
22
+ end
23
+
24
+ it "should execute query with empty scope" do
25
+ result = @query.execute
26
+ result.should_not be_empty
27
+ end
28
+ end
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: spotlight
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - youpy
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-02-16 00:00:00 +09:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.2.9
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: rake-compiler
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ description: Library to use Spotlight from Ruby
36
+ email: youpy@buycheapviagraonlinenow.com
37
+ executables: []
38
+
39
+ extensions:
40
+ - ext/md_item_native/extconf.rb
41
+ - ext/md_query_native/extconf.rb
42
+ extra_rdoc_files:
43
+ - LICENSE
44
+ - README.rdoc
45
+ files:
46
+ - ext/md_item_native/md_item_native.c
47
+ - ext/md_item_native/md_item_native.h
48
+ - ext/md_query_native/md_query_native.c
49
+ - lib/spotlight.rb
50
+ - lib/spotlight/query.rb
51
+ - LICENSE
52
+ - README.rdoc
53
+ has_rdoc: true
54
+ homepage: http://github.com/youpy/spotlight
55
+ licenses: []
56
+
57
+ post_install_message:
58
+ rdoc_options:
59
+ - --charset=UTF-8
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: "0"
67
+ version:
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: "0"
73
+ version:
74
+ requirements: []
75
+
76
+ rubyforge_project:
77
+ rubygems_version: 1.3.5
78
+ signing_key:
79
+ specification_version: 3
80
+ summary: Spotlight for Ruby
81
+ test_files:
82
+ - spec/md_item_native_spec.rb
83
+ - spec/md_query_native_spec.rb
84
+ - spec/spec_helper.rb
85
+ - spec/spotlight_query_spec.rb