Private
Public Access
1
0
Files
Kordophone/server/kordophone/Bridge/Operations/MBIMFetchAttachmentOperation.m

136 lines
5.4 KiB
Mathematica
Raw Normal View History

2018-11-21 01:38:43 -07:00
//
// MBIMFetchAttachmentOperation.m
// kordophoned
//
// Created by James Magahern on 11/20/18.
// Copyright © 2018 James Magahern. All rights reserved.
//
#import "MBIMFetchAttachmentOperation.h"
#import "MBIMDataResponse.h"
#import "MBIMImageUtils.h"
2018-11-21 01:38:43 -07:00
#import "IMCore_ClassDump.h"
#import "IMSharedUtilities_ClassDump.h"
#import <CoreGraphics/CoreGraphics.h>
2018-11-21 01:38:43 -07:00
@implementation MBIMFetchAttachmentOperation
+ (void)load { [super load]; }
+ (NSString *)endpointName
{
return @"attachment";
}
- (void)main
{
NSObject<HTTPResponse> *response = nil;
do {
BOOL preview = [[self valueForQueryItemWithName:@"preview"] boolValue];
NSString *guid = [self valueForQueryItemWithName:@"guid"];
2018-11-21 01:38:43 -07:00
if (!guid) {
2019-01-22 23:31:36 -08:00
MBIMLogInfo(@"No query item provided");
2018-11-21 01:38:43 -07:00
response = [[HTTPErrorResponse alloc] initWithErrorCode:500];
break;
}
IMFileTransfer *transfer = [[IMFileTransferCenter sharedInstance] transferForGUID:guid];
if (!transfer) {
2019-01-22 23:31:36 -08:00
MBIMLogInfo(@"No transfer found for guid: %@", guid);
2018-11-21 01:38:43 -07:00
response = [[HTTPErrorResponse alloc] initWithErrorCode:404];
break;
}
if (![transfer existsAtLocalPath]) {
2019-01-22 23:31:36 -08:00
MBIMLogInfo(@"We don't have the file for this yet (still downloading to server?)");
2018-11-21 01:38:43 -07:00
response = [[HTTPErrorResponse alloc] initWithErrorCode:404];
break;
}
NSData *responseData = nil;
NSURL *localURL = [transfer localURL];
NSString *extension = [[localURL pathExtension] lowercaseString];
if (preview) {
IMPreviewConstraints constraints = IMPreviewConstraintsZero();
// Fetch preview constraints from transfer
NSDictionary *previewConstraintsDict = [[transfer attributionInfo] objectForKey:@"pgenszc"];
if (previewConstraintsDict) {
constraints = IMPreviewConstraintsFromDictionary(previewConstraintsDict);
} else {
// Or, make a guess.
constraints.maxPxWidth = 500.0;
constraints.scale = 1.0;
}
NSURL *previewURL = IMAttachmentPreviewFileURL(localURL, extension, YES);
if (!previewURL) {
// I'm not sure why this sometimes returns nil...
MBIMLogInfo(@"Unable to generate attachment preview cache URL for %@, making one up.", localURL);
NSURL *temporaryAttachmentCache = [[[NSFileManager defaultManager] temporaryDirectory] URLByAppendingPathComponent:@"kordophone_attachment_cache"];
temporaryAttachmentCache = [temporaryAttachmentCache URLByAppendingPathComponent:guid];
[[NSFileManager defaultManager] createDirectoryAtURL:temporaryAttachmentCache withIntermediateDirectories:YES attributes:nil error:nil];
previewURL = [temporaryAttachmentCache URLByAppendingPathComponent:[localURL lastPathComponent]];
}
if (![[NSFileManager defaultManager] fileExistsAtPath:[previewURL path]]) {
MBIMLogInfo(@"Generating preview image for guid: %@ at %@", guid, [previewURL path]);
// Generate preview using preview generator manager
NSError *error = nil;
IMPreviewGeneratorManager *generator = [IMPreviewGeneratorManager sharedInstance];
CGImageRef previewImage = [generator newPreviewFromSourceURL:localURL withPreviewConstraints:constraints error:&error];
if (error) {
MBIMLogInfo(@"Unable to generate preview for attachment guid: %@", guid);
response = [[HTTPErrorResponse alloc] initWithErrorCode:500];
break;
}
// Convert to JPEG.
responseData = MBIMCGImageJPEGRepresentation(previewImage);
// Persist JPEG preview to disk
if (previewURL) {
[responseData writeToURL:previewURL atomically:YES];
}
} else {
// File exists
MBIMLogInfo(@"Using cached preview image for guid: %@ at %@", guid, [previewURL path]);
responseData = [NSData dataWithContentsOfURL:previewURL];
}
} else {
responseData = [NSData dataWithContentsOfURL:localURL];
}
2018-11-21 01:38:43 -07:00
if (!responseData) {
MBIMLogInfo(@"Wasn't able to load data for guid: %@", guid);
2018-11-21 01:38:43 -07:00
response = [[HTTPErrorResponse alloc] initWithErrorCode:404];
break;
}
NSString *mimeType = [transfer mimeType];
if ([mimeType isEqualToString:@"image/heic"]) {
// TODO: We should convert this to JPEG here. I don't want clients to have to deal with HEIC.
MBIMLogInfo(@"WARNING: Returning HEIC data for attachment %@", guid);
}
// It's unusual, but if this is nil, try to guess the MIME type based on the filename
if (!mimeType) {
// XXX: REALLY hacky
mimeType = [NSString stringWithFormat:@"image/%@", extension];
}
MBIMDataResponse *dataResponse = [[MBIMDataResponse alloc] initWithData:responseData contentType:mimeType];
dataResponse.httpHeaders[@"Cache-Control"] = @"public, immutable, max-age=31536000";
response = dataResponse;
2018-11-21 01:38:43 -07:00
} while (0);
self.serverCompletionBlock(response);
}
@end