content_type 2.0.2 → 2.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.
- data/ext/content_type.c +82 -53
- data/spec/content_type_spec.rb +9 -1
- metadata +2 -2
data/ext/content_type.c
CHANGED
@@ -15,6 +15,8 @@ VALUE file_content_type_wrap(VALUE self, VALUE path);
|
|
15
15
|
VALUE file_content_type(VALUE self);
|
16
16
|
VALUE file_singleton_content_type(VALUE self, VALUE path);
|
17
17
|
|
18
|
+
VALUE string_content_type(VALUE self);
|
19
|
+
|
18
20
|
bool content_type_file_ext(VALUE self, char *ext);
|
19
21
|
|
20
22
|
// http://www.webdeveloper.com/forum/showthread.php?t=162526
|
@@ -43,40 +45,42 @@ void magic_fail(const char *error);
|
|
43
45
|
void
|
44
46
|
Init_content_type()
|
45
47
|
{
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
48
|
+
// class definition
|
49
|
+
content_type = rb_define_class("ContentType", rb_cObject);
|
50
|
+
|
51
|
+
// instance methods
|
52
|
+
rb_define_method(content_type, "initialize", content_type_initialize, 1);
|
53
|
+
rb_define_method(content_type, "content_type", content_type_content_type, 0);
|
54
|
+
|
55
|
+
// instance attributes
|
56
|
+
rb_define_attr(content_type, "filepath", 1, 0);
|
57
|
+
rb_define_attr(content_type, "processed", 1, 0);
|
58
|
+
|
59
|
+
// hax on File
|
60
|
+
rb_define_method(rb_cFile, "content_type", file_content_type, 0);
|
61
|
+
rb_define_singleton_method(rb_cFile,
|
62
|
+
"content_type", file_singleton_content_type, 1);
|
63
|
+
|
64
|
+
// hax on String
|
65
|
+
rb_define_method(rb_cString, "content_type", string_content_type, 0);
|
62
66
|
}
|
63
67
|
|
64
68
|
VALUE
|
65
69
|
content_type_initialize(VALUE self, VALUE path)
|
66
70
|
{
|
67
|
-
|
71
|
+
struct stat st;
|
68
72
|
|
69
|
-
|
73
|
+
SafeStringValue(path);
|
70
74
|
|
71
|
-
|
72
|
-
|
73
|
-
|
75
|
+
if ((stat(RSTRING_PTR(path), &st)) != 0)
|
76
|
+
rb_raise(rb_const_get(rb_cObject, rb_intern("ArgumentError")),
|
77
|
+
"invalid file");
|
74
78
|
|
75
|
-
|
76
|
-
|
77
|
-
|
79
|
+
rb_iv_set(self, "@content_type", rb_str_new("", 0));
|
80
|
+
rb_iv_set(self, "@filepath", path);
|
81
|
+
rb_iv_set(self, "@processed", Qfalse);
|
78
82
|
|
79
|
-
|
83
|
+
return self;
|
80
84
|
}
|
81
85
|
|
82
86
|
bool
|
@@ -108,9 +112,9 @@ content_type_file_ext(VALUE self, char *ext)
|
|
108
112
|
VALUE
|
109
113
|
content_type_content_type(VALUE self)
|
110
114
|
{
|
111
|
-
|
112
|
-
|
113
|
-
|
115
|
+
VALUE ct;
|
116
|
+
struct magic_set *mh;
|
117
|
+
const char *mime;
|
114
118
|
char ext[MAX_EXT_LEN]; // TODO dynamicly sized
|
115
119
|
int i;
|
116
120
|
|
@@ -122,57 +126,82 @@ content_type_content_type(VALUE self)
|
|
122
126
|
return rb_iv_get(self, "@content_type");
|
123
127
|
}
|
124
128
|
|
125
|
-
|
126
|
-
|
129
|
+
if (rb_iv_get(self, "@processed"))
|
130
|
+
return rb_iv_get(self, "@content_type");
|
127
131
|
|
128
|
-
|
129
|
-
|
132
|
+
if (!(mh = magic_open(MAGIC_OPTIONS)))
|
133
|
+
magic_fail("open");
|
130
134
|
|
131
|
-
|
132
|
-
|
135
|
+
if ((magic_load(mh, NULL)) != 0)
|
136
|
+
magic_fail("load");
|
133
137
|
|
134
|
-
|
135
|
-
|
138
|
+
if (!(mime = magic_file(mh, RSTRING_PTR(rb_iv_get(self, "@filepath")))))
|
139
|
+
magic_fail("file");
|
136
140
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
+
ct = rb_str_new(mime, strlen(mime));
|
142
|
+
rb_iv_set(self, "@content_type", ct);
|
143
|
+
rb_iv_set(self, "@processed", Qtrue);
|
144
|
+
magic_close(mh);
|
141
145
|
|
142
|
-
|
146
|
+
return ct;
|
143
147
|
}
|
144
148
|
|
145
149
|
VALUE
|
146
150
|
file_content_type_wrap(VALUE self, VALUE path)
|
147
151
|
{
|
148
|
-
|
152
|
+
VALUE ct, mime, args[1];
|
149
153
|
|
150
|
-
|
151
|
-
|
152
|
-
|
154
|
+
SafeStringValue(path);
|
155
|
+
args[0] = path;
|
156
|
+
ct = rb_class_new_instance(1, args, content_type);
|
153
157
|
|
154
|
-
|
158
|
+
return rb_funcall(ct, rb_intern("content_type"), 0);
|
155
159
|
}
|
156
160
|
|
157
161
|
VALUE
|
158
162
|
file_content_type(VALUE self)
|
159
163
|
{
|
160
|
-
|
164
|
+
return file_content_type_wrap(self, rb_funcall(self, rb_intern("path"), 0));
|
161
165
|
}
|
162
166
|
|
163
167
|
VALUE
|
164
168
|
file_singleton_content_type(VALUE self, VALUE path)
|
165
169
|
{
|
166
|
-
|
170
|
+
return file_content_type_wrap(self, path);
|
171
|
+
}
|
172
|
+
|
173
|
+
VALUE
|
174
|
+
string_content_type(VALUE self)
|
175
|
+
{
|
176
|
+
struct magic_set *mh;
|
177
|
+
const char *mime;
|
178
|
+
VALUE str;
|
179
|
+
VALUE ct;
|
180
|
+
|
181
|
+
str = rb_funcall(self, rb_intern("to_s"), 0);
|
182
|
+
|
183
|
+
if (!(mh = magic_open(MAGIC_OPTIONS)))
|
184
|
+
magic_fail("open");
|
185
|
+
|
186
|
+
if ((magic_load(mh, NULL)) != 0)
|
187
|
+
magic_fail("load");
|
188
|
+
|
189
|
+
if (!(mime = magic_buffer(mh, RSTRING_PTR(str), RSTRING_LEN(str))))
|
190
|
+
magic_fail("buffer");
|
191
|
+
|
192
|
+
ct = rb_str_new(mime, strlen(mime));
|
193
|
+
magic_close(mh);
|
194
|
+
|
195
|
+
return ct;
|
167
196
|
}
|
168
197
|
|
169
198
|
void
|
170
199
|
magic_fail(const char *error)
|
171
200
|
{
|
172
|
-
|
173
|
-
|
201
|
+
const char *format = "magic_%s() error";
|
202
|
+
char *error_message;
|
174
203
|
|
175
|
-
|
176
|
-
|
177
|
-
|
204
|
+
error_message = malloc(sizeof(char *) * (strlen(format) + strlen(error)));
|
205
|
+
sprintf((char *)error_message, format, error);
|
206
|
+
rb_raise(rb_const_get(rb_cObject, rb_intern("RuntimeError")), error_message);
|
178
207
|
}
|
data/spec/content_type_spec.rb
CHANGED
@@ -37,7 +37,8 @@ describe ContentType do
|
|
37
37
|
context 'file ext overrides' do
|
38
38
|
it 'should detect docx files' do
|
39
39
|
ct = ContentType.new(@dcx)
|
40
|
-
ct.content_type.should ==
|
40
|
+
ct.content_type.should ==
|
41
|
+
'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
|
41
42
|
end
|
42
43
|
|
43
44
|
it 'should handle dot files' do
|
@@ -100,4 +101,11 @@ describe ContentType do
|
|
100
101
|
File.unlink(t.path)
|
101
102
|
end
|
102
103
|
end
|
104
|
+
|
105
|
+
context 'on strings' do
|
106
|
+
it 'should have String#content_type' do
|
107
|
+
str = File.read(@img)
|
108
|
+
str.content_type.should == 'image/jpeg'
|
109
|
+
end
|
110
|
+
end
|
103
111
|
end
|