/
UploadThread.m
244 lines (203 loc) · 7.09 KB
/
UploadThread.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
//
// UploadThread.m
// PhotoUpload
// arch-tag: 53F4E420-9196-11D8-9294-000A957659CC
//
// Created by Dustin Sallings on Wed Sep 25 2002.
// Copyright (c) 2002 __MyCompanyName__. All rights reserved.
//
#import <CoreServices/CoreServices.h>
#import "UploadThread.h"
#import "PUImage.h"
#import "SizeScaler.h"
#import "cJSON.h"
#import "NSData-Base64Extensions.h"
#import "NSData+MD5.h"
@implementation UploadThread
-(void)setBatch:(Batch *)to
{
id tmp=to;
_batch=to;
[_batch retain];
if(tmp != nil) {
[tmp release];
}
}
static NSString *formatDate(NSDate *d) {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd"];
NSString *rv = [dateFormatter stringFromDate:d];
[dateFormatter release];
return rv;
}
static NSString *formatDateTime(NSDate *d) {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm"];
NSString *rv = [dateFormatter stringFromDate:d];
[dateFormatter release];
return rv;
}
static void addAttachment(cJSON *a, const char *name,
const char *mimeType, NSData *data) {
cJSON *doc = cJSON_CreateObject();
assert(doc);
cJSON_AddStringToObject(doc, "content_type", mimeType);
cJSON_AddStringToObject(doc, "data", [[data encodeBase64WithNewlines:NO] UTF8String]);
cJSON_AddItemToObject(a, name, doc);
}
static void addScaledImage(cJSON *a, const char *name, const char *mimeType,
NSBitmapImageFileType repType,
NSSize size, NSImage *image) {
NSArray *reps = [image representations];
NSEnumerator *e=[reps objectEnumerator];
id object=nil;
while(object = [e nextObject]) {
if([object isKindOfClass:[NSBitmapImageRep class]]) {
NSImage *tempImage = [[NSImage alloc] init];
[tempImage addRepresentation:object];
NSImage *auxImage = [[NSImage alloc] initWithSize: size];
[auxImage lockFocus];
[tempImage drawInRect:NSMakeRect(0,0,size.width, size.height)
fromRect:NSZeroRect
operation:NSCompositeSourceOver
fraction:1.0];
[auxImage unlockFocus];
[tempImage release];
NSBitmapImageRep* scaledImageRep = [[NSBitmapImageRep alloc]
initWithData: [auxImage TIFFRepresentation]];
NSMutableDictionary *props = [[NSMutableDictionary alloc] init];
[props setObject:[NSNumber numberWithFloat: 0.2]
forKey:NSImageCompressionFactor];
NSData *d = [scaledImageRep representationUsingType:repType
properties:props];
NSLog(@"Storing %d bytes scaled to %dx%d",
[d length], (int)size.width, (int)size.height);
addAttachment(a, name, mimeType, d);
[props release];
[auxImage release];
[scaledImageRep release];
break;
}
}
}
-(void)run: (id)object
{
// Create the autorelease pool.
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSSize tnSize;
tnSize.width = 220;
tnSize.height = 146;
NSSize eightBySix;
eightBySix.width = 800;
eightBySix.height = 600;
// Retain the parameters
params=object;
[params retain];
// URL for uploading
NSURL *url=[[NSURL alloc] initWithString: [_batch url]];
NSEnumerator *en=[[_batch files] objectEnumerator];
id f=nil;
while( (f = [en nextObject]) && (! [params finished])) {
// Create an inner autorelease pool to deal with the garbage the
// upload produces
NSAutoreleasePool *ipool = [[NSAutoreleasePool alloc] init];
cJSON *doc = cJSON_CreateObject();
assert(doc);
NSLog(@"Uploading %@.", f);
// Get the file data
NSData *origData = [[NSData alloc] initWithContentsOfFile:[f filename]];
cJSON_AddStringToObject(doc, "_id", [[origData md5] UTF8String]);
cJSON_AddStringToObject(doc, "type", "photo");
cJSON_AddStringToObject(doc, "addedby", [[_batch username] UTF8String]);
cJSON_AddStringToObject(doc, "cat", [[_batch category] UTF8String]);
cJSON_AddStringToObject(doc, "descr", [[_batch description] UTF8String]);
cJSON_AddStringToObject(doc, "taken", [formatDate([_batch taken]) UTF8String]);
cJSON_AddStringToObject(doc, "ts", [formatDateTime([NSDate date]) UTF8String]);
cJSON_AddNumberToObject(doc, "size", [origData length]);
NSString *extension = [[[f filename] pathExtension] lowercaseString];
if ([extension isEqual: @"jpeg"]) {
extension = @"jpg";
}
cJSON_AddStringToObject(doc, "extension", [extension UTF8String]);
NSImage *origImage = [[NSImage alloc] initWithData: origData];
NSSize origSize = [origImage size];
cJSON_AddNumberToObject(doc, "width", origSize.width);
cJSON_AddNumberToObject(doc, "height", origSize.height);
SizeScaler *ss = [[SizeScaler alloc] initWithSize:origSize];
NSSize thisTnSize = [ss scaleTo: tnSize];
cJSON_AddNumberToObject(doc, "tnwidth", thisTnSize.width);
cJSON_AddNumberToObject(doc, "tnheight", thisTnSize.height);
cJSON *keywords = cJSON_CreateArray();
NSArray *keywordArray = [[_batch keywords] componentsSeparatedByCharactersInSet: [NSCharacterSet whitespaceCharacterSet]];
NSEnumerator *e=[keywordArray objectEnumerator];
id object=nil;
while(object = [e nextObject]) {
cJSON_AddItemToArray(keywords, cJSON_CreateString([object UTF8String]));
}
cJSON_AddItemToObject(doc, "keywords", keywords);
cJSON *attachments = cJSON_CreateObject();
const char *mimeType = "image/jpeg";
NSBitmapImageFileType repType = NSJPEGFileType;
if ([extension isEqualToString:@"png"]) {
mimeType = "image/png";
repType = NSPNGFileType;
}
addAttachment(attachments,
[[NSString stringWithFormat:@"original.%@", extension] UTF8String],
mimeType, origData);
addScaledImage(attachments,
[[NSString stringWithFormat:@"800x600.%@", extension] UTF8String],
mimeType, repType,
[ss scaleTo:eightBySix], origImage);
addScaledImage(attachments,
[[NSString stringWithFormat:@"thumb.%@", extension] UTF8String],
mimeType, repType,
thisTnSize, origImage);
cJSON_AddItemToObject(doc, "_attachments", attachments);
char *str = cJSON_Print(doc);
NSData *postBody = [[NSData alloc] initWithBytesNoCopy:str length:strlen(str)
freeWhenDone:YES];
NSMutableURLRequest* urlRequest = [[NSMutableURLRequest alloc]
initWithURL:url];
[urlRequest setHTTPMethod:@"POST"];
[urlRequest setHTTPBody: postBody];
[urlRequest addValue:@"application/json" forHTTPHeaderField:@"Content-type"];
NSURLResponse *response;
NSError *error;
NSData *responseData = [NSURLConnection sendSynchronousRequest:urlRequest
returningResponse:&response
error:&error];
NSString *s = [[NSString alloc] initWithData:responseData
encoding:NSUTF8StringEncoding];
NSLog(@"Response: %@", s);
[s release];
if (error) {
NSLog(@"There was an error");
}
[urlRequest release];
[postBody release];
[ss release];
[origData release];
[origImage release];
[params uploadedFile];
cJSON_Delete(doc);
[ipool release];
}
NSLog(@"Finished, thread will join.\n");
[params uploadComplete];
[url release];
[pool release];
}
-(void)dealloc
{
if(_batch!=nil) {
[_batch release];
_batch=nil;
}
if(params!=nil) {
[params release];
params=nil;
}
[super dealloc];
}
@end