2020-02-22 15:38:54 +04:00

255 lines
9.1 KiB
Objective-C
Executable File

//
// Created by Tikhonenko Pavel on 29/11/2013.
// Copyright (c) 2013 Coub. All rights reserved.
//
#import "CBJSONCoubMapper.h"
#import "CBCoubNew.h"
#import "NSDictionary+CBExtensions.h"
#import "CBCoubVideoSource.h"
#import "CBCoubAudioSource.h"
#import "CBTagNew.h"
@implementation CBJSONCoubMapper
{
}
+ (CBCoubNew *)updateCoubFromCoub:(CBCoubNew *)newCoub coub:(CBCoubNew *)coub
{
coub.title = newCoub.title;
coub.liked = newCoub.liked;
coub.visibility = newCoub.visibility;
coub.recoubed = newCoub.recoubed;
coub.likeCount = newCoub.likeCount;
coub.recoubCount = newCoub.recoubCount;
coub.cotd = newCoub.cotd;
coub.flagged = newCoub.flagged;
coub.creationDate = coub.creationDate;
coub.creationDateAsString = coub.creationDateAsString;
// if(newCoub.isDone)
// coub.state = CBCoubDraftCompleted;
return coub;
}
+ (CBCoubNew *)updateCoubFromJSONObject:(NSDictionary *)attributes coub:(CBCoubNew *)coub
{
static NSDictionary *kCoubJSONKeys = nil;
if(!kCoubJSONKeys)
{
kCoubJSONKeys = @{
//@"permalink" : @"permalink",
@"title" : @"title",
@"visibility_type" : @"visibility",
//@"created_at" : @"creationDateAsString",
//@"external_download" : @"externalDownloadAsDictionary",
@"like" : @"liked",
@"recoub" : @"recoubed",
@"likes_count" : @"likeCount",
@"views_count" : @"viewCount",
@"recoubs_count" : @"recoubCount",
@"cotd" : @"cotd",
@"flag" : @"flagged",
};
}
if ([attributes[@"title"] isKindOfClass:[NSString class]])
{
NSString *title = attributes[@"title"];
coub.title = title;
}
NSDictionary *recoubInfo = nil;
if(attributes[@"permalink"])
coub.permalink = attributes[@"permalink"];
if(attributes[@"id"])
coub.coubID = [attributes[@"id"] stringValue];
coub.originalPermalink = attributes[@"permalink"];
coub.originalCreationDateAsString = attributes[@"created_at"];
if (coub.author == nil)
{
coub.author = [CBCoubAuthorVO coubAuthorWithAttributes:attributes[@"user"]];
//coub.authorCD = [CBUserNewuserWithAttributes:attributes[@"user"]];
}
if (coub.author.name.length == 0)
{
NSDictionary *channel = attributes[@"channel"];
if ([channel respondsToSelector:@selector(objectForKey:)])
coub.author.name = channel[@"title"];
}
if(attributes[@"is_done"])
coub.isDone = [attributes[@"is_done"] boolValue];
NSDictionary *fileVersions = attributes[@"file_versions"];
NSString *remoteVideoLocation = attributes[@"explicitVideoLocation"];
if (remoteVideoLocation)
{
remoteVideoLocation = [remoteVideoLocation stringByReplacingOccurrencesOfString:@"muted_mp4_med_" withString:@"mp4_med_"];
remoteVideoLocation = [remoteVideoLocation stringByReplacingOccurrencesOfString:@"_muted_med" withString:@"_med"];
coub.remoteVideoLocation = remoteVideoLocation;
}
else
{
if (fileVersions)
remoteVideoLocation = fileVersions[@"iphone"][@"url"];
if(!remoteVideoLocation)
remoteVideoLocation = attributes[@"file"];
if(!remoteVideoLocation || [remoteVideoLocation isEqual:[NSNull null]])
remoteVideoLocation = fileVersions[@"html5"][@"video"][@"med"][@"url"];
if (remoteVideoLocation)
{
if ([remoteVideoLocation rangeOfString:@"muted_mp4"].location != NSNotFound)
{
remoteVideoLocation = [remoteVideoLocation stringByReplacingOccurrencesOfString:@"muted_mp4_med_" withString:@"mp4_med_"];
remoteVideoLocation = [remoteVideoLocation stringByReplacingOccurrencesOfString:@"_muted_med" withString:@"_med"];
coub.remoteVideoLocation = remoteVideoLocation;
}
else
{
NSRange r1 = [remoteVideoLocation rangeOfString:@"iphone_"];
NSRange r2 = [remoteVideoLocation rangeOfString:@"_iphone"];
if (r1.location == NSNotFound)
{
r1 = [remoteVideoLocation rangeOfString:@"gifv_"];
r2 = [remoteVideoLocation rangeOfString:@"_gifv"];
}
if (r1.location != NSNotFound)
{
NSInteger loc = r1.length+r1.location;
NSString *someVideoMetadataString = [remoteVideoLocation substringWithRange:NSMakeRange(loc, r2.location - loc)];
remoteVideoLocation = fileVersions[@"web"][@"template"];
NSRange r3 = [remoteVideoLocation rangeOfString:@"%{"];
remoteVideoLocation = [remoteVideoLocation substringToIndex:r3.location];
remoteVideoLocation = [NSString stringWithFormat:@"%@mp4_med_size_%@_med.mp4", remoteVideoLocation, someVideoMetadataString];
coub.remoteVideoLocation = remoteVideoLocation;
}
else if ([remoteVideoLocation rangeOfString:@"mp4_med_size_"].location != NSNotFound)
{
coub.remoteVideoLocation = remoteVideoLocation;
}
}
}
}
NSString *remoteAudioLocation = [attributes[@"audio_versions"] coubURIFromVersionTemplateWithPreferredSubstitutions:@[@"low", @"mid", @"high"]];
if(!remoteAudioLocation)
remoteAudioLocation = attributes[@"audio_file_url"];
if(!remoteAudioLocation || [remoteAudioLocation isEqual:[NSNull null]])
remoteAudioLocation = fileVersions[@"mobile"][@"mp3"];
if(remoteAudioLocation)
coub.remoteAudioLocation = remoteAudioLocation;
NSDictionary *chunks = attributes[@"audio_versions"][@"chunks"];
if(chunks)
{
NSString *audioTemplate = chunks[@"template"];
audioTemplate = [audioTemplate stringByReplacingOccurrencesOfString:@"%{version}" withString:@"low"];
audioTemplate = [audioTemplate stringByReplacingOccurrencesOfString:@"%{chunk}" withString:@"%i"];
coub.remoteAudioLocationPattern = audioTemplate;
}
// big, med, small, ios_large
//KALog(@"ff=%@", [attributes[@"first_frame_versions"][@"versions"] componentsJoinedByString: @", "]);
NSString *largePictureLocation = [attributes[@"first_frame_versions"] coubURIFromVersionTemplateWithPreferredSubstitutions:@[@"med", @"big", @"ios_large"]];
if(largePictureLocation)
coub.largePicture = largePictureLocation;
// micro, tiny, age_restricted, ios_large, ios_mosaic, big, med, small
NSString *mediumPictureLocation = [attributes[@"image_versions"] coubURIFromVersionTemplateWithPreferredSubstitutions:@[@"ios_mosaic", @"small", @"med"]];
if(!mediumPictureLocation)
mediumPictureLocation = attributes[@"picture"]; // short JSON
if(mediumPictureLocation)
coub.mediumPicture = mediumPictureLocation;
// Determine the type of audio based on the values of "has_sound" and "audio_file_url"
if(coub.remoteAudioLocation && ([coub.remoteAudioLocation isKindOfClass:[NSString class]] && [coub.remoteAudioLocation length] < 8))
coub.remoteAudioLocation = nil;
if(attributes[@"visibility_type"])
{
coub.audioType = coub.remoteAudioLocationPattern ? CBCoubAudioTypeExternal : ([attributes[@"has_sound"] boolValue] ? CBCoubAudioTypeInternal : CBCoubAudioTypeNone);
}
// else a short JSON doesn't have any information on sound
NSDictionary *mediaBlock = attributes[@"media_blocks"];
BOOL isCoubAudioSourceAvailable = mediaBlock[@"audio_track"] != nil;
BOOL isCoubVideoSourceAvailable = mediaBlock[@"external_video"] != nil;
if(isCoubVideoSourceAvailable)
coub.videoSource = [CBCoubVideoSource sourceFromData:mediaBlock[@"external_video"]];
if(isCoubAudioSourceAvailable)
coub.audioSource = [CBCoubAudioSource sourceFromData:mediaBlock[@"audio_track"]];
if(coub.audioSource || coub.videoSource)
coub.isCoubSourcesAvailable = YES;
NSDictionary *externalDownloadInfo = attributes[@"external_download"];
if([externalDownloadInfo isKindOfClass:[NSDictionary class]])
{
coub.externalDownloadType = externalDownloadInfo[@"type"];
coub.externalDownloadSource = externalDownloadInfo[@"url"];
}else
{
// Coub API may return a boolean "false" as "external_download" value
coub.externalDownloadType = nil;
coub.externalDownloadSource = nil;
}
NSArray *tags = attributes[@"tags"];
if(tags)
{
NSMutableArray *mutableArray = [NSMutableArray arrayWithCapacity:tags.count];
[tags enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop)
{
[mutableArray addObject:[CBTagNew tagWithAttributes:obj]];
}];
coub.tags = [NSArray arrayWithArray:mutableArray];
}
if(recoubInfo)
{
coub.recouber = [CBCoubAuthorVO coubAuthorWithAttributes:recoubInfo[@"user"]];
coub.liked = [recoubInfo[@"like"] boolValue];
coub.recoubed = [recoubInfo[@"recoub"] boolValue];
coub.flagged = [recoubInfo[@"flagged"] boolValue];
}
if(!coub.coubID)
[NSException raise:NSInternalInconsistencyException format:@"No coub id found in %@", attributes];
if(!coub.permalink)
[NSException raise:NSInternalInconsistencyException format:@"No coub permalink found in %@", attributes];
NSArray *size = attributes[@"dimensions"][@"small"];
//coub.naturalVideoSize = CGSizeMake([size[0] floatValue], [size[1] floatValue]);
return coub;
}
+ (CBCoubNew *)coubFromJSONObject:(NSDictionary *)jsonObj
{
return [self updateCoubFromJSONObject:jsonObj coub:[CBCoubNew new]];
}
@end