Today's Menu  Portugal
journal and plan nutrition
Z5GoogleDriveController.m
Go to the documentation of this file.
1 //
2 // Z5GoogleDriveController.m
3 // TodaysMenu
4 //
5 // Created by Don Zeek on 4/16/18.
6 // Copyright © 2018 net.dzeek.y2015.ios.portfolio. All rights reserved.
7 //
8 
9 #import "Z5DataController.h"
10 #import "GTMHTTPFetcher.h"
11 #import "GTLDriveFile.h"
12 #import "GTMSessionFetcherService.h"
13 
29 @implementation Z5GoogleDriveController {
30  NSMutableArray *localDriveListeners;
31  NSMutableDictionary *requestLine;
32  NSString *journalRootId;
33 }
34 
35 - (id) init
36 {
37  // Initialize the service object.
38  self.service = [[GTLRDriveService alloc] init];
39 
40  localDriveListeners = [[NSMutableArray alloc] initWithCapacity:10];
41 
42  requestLine = [[NSMutableDictionary alloc] init];
43 
44  return self;
45 }
46 
47 
48 - (void) addDriveListener: (id<Z5GoogleDriveListener>)ear
49 {
50  [self connectToLogin];
51  [localDriveListeners addObject:ear];
52 }
53 - (void) removeDriveListener: (id<Z5GoogleDriveListener>)ear
54 {
55  [localDriveListeners removeObject:ear];
56 }
57 - (void) connectToLogin
58 {
59  Z5GoogleLoginController *loginControl = [[[Z5DataController sharedInstance] remoteDataController] loginController];
60  [loginControl addLoginListener:self];
61 }
62 
63 #pragma mark - Z5GoogleLoginListener
64 - (void) signedIn: (GIDGoogleUser *)user
65 {
66  NSLog(@"GoogleDriveController.signedIn: %@ - %@", user.profile.name, user.authentication.fetcherAuthorizer);
67  self.service.authorizer = user.authentication.fetcherAuthorizer;
68 }
69 - (void) signedOut:(GIDGoogleUser *)user
70 {
71  self.service.authorizer = nil;
72 }
73 
74 
75 - (NSString *)signedInUsername {
76  // Get the email address of the signed-in user.
77  // id<GTMFetcherAuthorizationProtocol> auth = self.service.authorizer;
78 
79  NSString *ret;
81  if (nil==user) {
82  ret = nil;
83  } else {
84  ret = [[user profile] name];
85  }
86  return ret;
87 }
88 
101 id<V7GoogDriveAPIProtocol> mDriveAPIDelegate;
102 
103 //- (instancetype) initWithDelegate:(id <V7GoogDriveAPIProtocol>)delegate
104 //{
105 // self = [super init];
106 // if (self) {
107 // mDriveAPIDelegate = delegate;
108 // }
109 // return self;
110 //}
111 
112 -(void) listRootFor:(id<V7GoogDriveAPIProtocol>)reqstor
113 {
114  GTLRServiceTicket *rootListTicket = [self listRoot];
115 
116  NSDictionary<NSString *,id> *extraTicketProps = [rootListTicket ticketProperties];
117  NSString *rootFetchKey = [extraTicketProps objectForKey:@"query-stage"];
118  NSLog(@"Z5GoogleDriveController.viewDidLoad: rootFetechKey: %@", rootFetchKey); //"chase-root"
119  [requestLine setObject:reqstor forKey:rootFetchKey];
120 }
121 
122 // List up to 10 files in Drive
123 - (GTLRServiceTicket *)listRoot {
124 
126  remoteDataController] driveController];
127  GTLRDriveQuery_FilesList *query = [GTLRDriveQuery_FilesList query];
128  query.fields = @"nextPageToken, files(id, name)";
129  query.pageSize = 100;
130  query.q = @"name = 'NutritionJournal'";
131 
132  NSMutableDictionary<NSString *,id> *extraTicketProps = [[NSMutableDictionary alloc] init];
133  [extraTicketProps setObject:@"chase-root" forKey:@"query-stage"];
134  [query.executionParameters setTicketProperties:extraTicketProps];
135 
136  NSLog(@"Z5GoogleDriveController.listRoot: authorizer: %@", driveController.service.authorizer);
137 
138  GTLRServiceTicket *queryTicket = [driveController.service executeQuery:query
139  delegate:self
140  didFinishSelector:@selector(displayResultWithTicket:finishedWithObject:error:)];
141 
142  return queryTicket;
143 }
144 
145 - (void) listJournalRootFor:(id<V7GoogDriveAPIProtocol>)reqstor
146 {
147  GTLRServiceTicket *rootListTicket = [self listJournalRoot:journalRootId];
148 
149  NSDictionary<NSString *,id> *extraTicketProps = [rootListTicket ticketProperties];
150  NSString *journalRootFetchKey = [extraTicketProps objectForKey:@"query-stage"];
151  NSLog(@"Z5GoogleDriveController.viewDidLoad: rootFetechKey: %@", journalRootFetchKey); //"chase-journal-root"
152  [requestLine setObject:reqstor forKey:journalRootFetchKey];
153 }
154 - (GTLRServiceTicket *)listJournalRoot:(NSString *)journalRootId {
155 
156  NSLog(@"Z5GoogleDriveController.listJournalRoot");
157  Z5GoogleDriveController *driveController = [[[Z5DataController sharedInstance] remoteDataController] driveController];
158 
159  GTLRDriveQuery_FilesList *query = [GTLRDriveQuery_FilesList query];
160  query.fields = @" nextPageToken, files(id, name, mimeType)";
161  query.pageSize = 100;
162  query.q = [NSString stringWithFormat:@"'%@' in parents and mimeType = 'application/vnd.google-apps.folder'",
163  journalRootId];
164 
165  NSMutableDictionary<NSString *,id> *extraTicketProps = [[NSMutableDictionary alloc] init];
166  [extraTicketProps setObject:@"chase-journal-root" forKey:@"query-stage"];
167  [query.executionParameters setTicketProperties:extraTicketProps];
168 
169  NSLog(@"Z5GoogleDriveController.listJournalRoot: authorizer: %@", driveController.service.authorizer);
170 
171  GTLRServiceTicket *queryTicket = [driveController.service
172  executeQuery:query
173  delegate:self
174  didFinishSelector:@selector(displayResultWithTicket:finishedWithObject:error:)];
175 
176  return queryTicket;
177 }
181 - (NSArray *)listJournalItemRoot:(NSArray<GTLRDrive_File *> *)itemFiles
182 {
183  NSLog(@"Z5GoogleDriveController.listJournalItemRoot: input file count: %lu", (unsigned long)[itemFiles count]);
184 
185  NSMutableArray * ret = [[NSMutableArray alloc] init];
186  for (GTLRDrive_File *file in itemFiles) {
187  NSLog(@"Z5GoogleDriveController.listJournalItemRoot: mimeType %@", file.mimeType);
188 
189  [ret addObject:[file name]];
190 
191  if ([file.mimeType isEqualToString:@"application/vnd.google-apps.folder"]) {
192  [self listJournaItemPartRoot:file.identifier];
193  } else {
194 
195  }
196  }
197  return ret;
198 }
199 - (void) listJournaItemPartRoot:(NSString *)journalItemPartRootId for:(id<V7GoogDriveAPIProtocol>) requestor
200 {
201  GTLRServiceTicket *rootListTicket = [self listJournaItemPartRoot:journalItemPartRootId];
202 
203  NSDictionary<NSString *,id> *extraTicketProps = [rootListTicket ticketProperties];
204  NSString *journalItemPartRootFetchKey = [extraTicketProps objectForKey:@"query-stage"];
205  NSLog(@"Z5GoogleDriveController.listJournaItemPartRootFor: journalItemPartRootFetchKey: %@", journalItemPartRootFetchKey); //"chase-journal-root"
206  [requestLine setObject:requestor forKey:journalItemPartRootFetchKey];
207 }
208 - (GTLRServiceTicket *)listJournaItemPartRoot:(NSString *)journalItemPartRootId {
209 
210  NSLog(@"Z5GoogleDriveController.listJournaItemPartRoot");
211  Z5GoogleDriveController *driveController = [[[Z5DataController sharedInstance] remoteDataController] driveController];
212 
213  GTLRDriveQuery_FilesList *query = [GTLRDriveQuery_FilesList query];
214  query.fields = @"nextPageToken, files(id, name)";
215  query.pageSize = 100;
216  query.q = [NSString stringWithFormat:@"'%@' in parents", journalItemPartRootId];
217 
218  NSMutableDictionary<NSString *,id> *extraTicketProps = [[NSMutableDictionary alloc] init];
219  [extraTicketProps setObject:@"chase-journal-item-part-root" forKey:@"query-stage"];
220  [query.executionParameters setTicketProperties:extraTicketProps];
221 
222  // NSLog(@"V7GoogDriveAPIController.listJournaItemPartRoot: authorizer: %@", driveController.service.authorizer);
223 
224  GTLRServiceTicket *queryTicket = [driveController.service executeQuery:query
225  delegate:self
226  didFinishSelector:@selector(displayResultWithTicket:finishedWithObject:error:)];
227 
228  return queryTicket;
229 }
230 
231 // Process the response and display output
232 - (void)displayResultWithTicket:(GTLRServiceTicket *)ticket
233  finishedWithObject:(GTLRDrive_FileList *)result
234  error:(NSError *)error {
235 
236  NSDictionary<NSString *,id> *extraTicketProps = [ticket ticketProperties];
237  NSString *queryFetchKey = [extraTicketProps objectForKey:@"query-stage"];
238 
239  // NSLog(@"V7GoogDriveAPIController.displayResultWithTicket: queryFetchKey: %@", queryFetchKey);
240  NSLog(@"Z5GoogleDriveController.displayResultWithTicket: key: %@ count: %lu",
241  queryFetchKey, [result.files count]);
242  if (error == nil) {
243  if ([queryFetchKey isEqualToString:@"chase-root"]) {
244  // TODO: journalRootId: error trap multiple access
245  for (GTLRDrive_File *file in result.files) {
246  journalRootId = file.identifier;
247  }
248  id<V7GoogDriveAPIProtocol> reqstor = [requestLine objectForKey:queryFetchKey];
249  [self listJournalRootFor:reqstor];
250  } else if ([queryFetchKey isEqualToString:@"chase-journal-root"]) {
251  id<V7GoogDriveAPIProtocol> reqstor = [requestLine objectForKey:queryFetchKey];
252  NSLog(@"Z5GoogleDriveController.displayResultWithTicket: JournalRoot");
253  // this is the original, only, use of .resultStage
254  // mDriveAPIDelegate = [requestLine objectForKey:queryFetchKey];
255  // [mDriveAPIDelegate resultStage:qJournalRoot returnedFiles:result.files];
256  NSMutableArray *filesToRequestor = [[NSMutableArray alloc] init];
257  for (GTLRDrive_File *file in result.files) {
258  NSLog(@"V7GoogDriveViewController.resultStage: mime %@ name: %@ identifier: %@", file.mimeType, file.name, file.identifier);
259  NSDictionary *fileInfo = [[NSDictionary alloc] initWithObjectsAndKeys:file.name, @"filename", file.identifier, @"fileidentifier", nil];
260  [filesToRequestor addObject:fileInfo];
261  // [focusFoodDriveArray addObject:file];
262 
263 
264  if ([file.mimeType isEqualToString:@"application/vnd.google-apps.folder"]) {
265  NSLog(@"V7GoogDriveViewController.resultStage: Folder in Journal-Root, request parts");
266  // [driveControl listJournaItemPartRoot:file.identifier];
267  [self listJournaItemPartRoot:file.identifier for:reqstor];
268  } else {
269  ;
270  }
271  [reqstor resultStage:qJournalRoot returnedFiles:filesToRequestor];
272  }
273  } else if ([queryFetchKey isEqualToString:@"chase-journal-item-root"]) {
274  NSLog(@"Z5GoogleDriveController.displayResultWithTicket: JournalItemRoot: #files: %ld", [result.files count]);
275  /* TODO: save result 'journalItemRoot' */
276  NSString *journalItemRoot = [result.files lastObject].identifier;
277  NSLog(@"Z5GoogleDriveController.displayResultWithTicket: journalItemRoot: %@", journalItemRoot);
278 
279  mDriveAPIDelegate = [requestLine objectForKey:queryFetchKey];
280  [mDriveAPIDelegate resultStage:kOblateSpheroid returnedFiles:result.files];
281  } else if ([queryFetchKey isEqualToString:@"chase-journal-item-part-root"]) {
282  NSLog(@"Z5GoogleDriveController.displayResultWithTicket: JournalItemPartRoot");
283  [mDriveAPIDelegate resultStage:qJournalPartRoot returnedFiles:result.files];
284  }
285  [self logFilesList:result.files];
286  [mDriveAPIDelegate ticketCompleted:ticket];
287 
288  } else {
289  NSMutableString *errMessage = [[NSMutableString alloc] init];
290  [errMessage appendFormat:@"Error getting presentation data: %@\n", error.localizedDescription];
291  // [self showAlert:@"Error" message:message];
292  NSLog(@"Z5GoogleDriveController.displayResultWithTicket:: Error: %@", error.localizedDescription);
293  }
294  // END -- Log files list
295 }
296 
297 
298 
299 - (void) placeRecipe
300 {
301  [self createFolder:@"Baked Halibut" inFolder:nil];
302 }
303 - (void) createFolder:(NSString *) newFolderName inFolder:(NSObject *) parent
304 {
305  [self createFolder:@"Baked Halibut" inFolder:nil];
306  Z5GoogleLoginController *loginControl = [[[Z5DataController sharedInstance] remoteDataController] loginController];
307  NSLog(@"Z5GoogleDriveController.createFolder: user: %@ new folder name: %@", [loginControl username], newFolderName);
308  if (nil!=[loginControl username]) {
309  // this branch executes, however Error: Code=401 "Login Required"
310  GTLRDrive_File *metadata = [GTLRDrive_File object];
311  metadata.name = newFolderName;
312  metadata.mimeType = @"application/vnd.google-apps.folder";
313  GTLRDriveQuery_FilesCreate *query =
314  [GTLRDriveQuery_FilesCreate queryWithObject:metadata
315  uploadParameters:nil];
316  query.fields = @"id";
317  [_service executeQuery:query completionHandler:^(GTLRServiceTicket *ticket,
318  GTLRDrive_File *file,
319  NSError *error) {
320  if (error == nil) {
321  NSLog(@"Z5GoogleDriveController.createFolder: File ID %@", file.identifier);
322  } else {
323  NSLog(@"Z5GoogleDriveController.createFolder: An error occurred: %@", error);
324  }
325  }];
326  } else {
327  NSLog(@"Z5GoogleDriveController.createFolder: not logged in");
328  }
329 }
330 
331 - (void) uploadFile
332 {
333  [self createFolder:@"Baked Halibut" inFolder:nil];
334  NSData *fileData = [[NSFileManager defaultManager] contentsAtPath:@"files/photo.jpg"];
335  NSString *folderId = @"0BwwA4oUTeiV1UVNwOHItT0xfa2M";
336 
337  GTLRDrive_File *metadata = [GTLRDrive_File object];
338  metadata.name = @"photo.jpg";
339  metadata.parents = [NSArray arrayWithObject:folderId];
340 
341  GTLRUploadParameters *uploadParameters = [GTLRUploadParameters uploadParametersWithData:fileData MIMEType:@"image/jpeg"];
342  uploadParameters.shouldUploadWithSingleRequest = TRUE;
343  GTLRDriveQuery_FilesCreate *query = [GTLRDriveQuery_FilesCreate queryWithObject:metadata
344  uploadParameters:uploadParameters];
345  query.fields = @"id";
346  [_service executeQuery:query completionHandler:^(GTLRServiceTicket *ticket,
347  GTLRDrive_File *file,
348  NSError *error) {
349  if (error == nil) {
350  NSLog(@"Z5GoogleDriveController.uploadFile: File ID %@", file.identifier);
351  } else {
352  NSLog(@"Z5GoogleDriveController.uploadFile: An error occurred: %@", error);
353  }
354  }];
355 }
356 
357 - (void) downloadFile: (GTLDriveFile *)file withDelegate:(id<Z5RemoteDataFetchProtocol>) delegate
358 {
359  // GTLServiceDrive *drive = ...;
360  // GTLDriveFile *file = ...;
361  __block NSString *driveFileTitle = [file title];
362  __block NSString *driveFileId = [file identifier];
363  GTMSessionFetcher *fetcher = [_service.fetcherService fetcherWithURLString:file.downloadUrl];
364 
365  [fetcher beginFetchWithCompletionHandler:^(NSData *data, NSError *error) {
366  if (error == nil) {
367  // NSLog(@"RemoteData.downloadFile: Retrieved file content");
368  // NSString *contents = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
369  // NSLog(@"RemoteData.downloadFile: contents: %@", contents);
370 
371  [delegate showDataFetch:data fromFile:driveFileTitle withGoogleId:driveFileId];
372 
373  } else {
374  NSLog(@"RemoteDate.downloadFile: An error occurred: %@", error);
375  }
376  }];
377 }
378 
379 
380 - (void) logFilesList:(NSArray<GTLRDrive_File *> *)fileArr
381 {
382  // Log files list
383  NSMutableString *output = [[NSMutableString alloc] init];
384  if (fileArr.count > 0) {
385  [output appendString:@"Files:\n"];
386  int count = 1;
387  for (GTLRDrive_File *file in fileArr) {
388  [output appendFormat:@"%@ (%@)\n", file.name, file.identifier];
389  count++;
390  }
391  } else {
392  [output appendString:@"No files found."];
393  }
394  NSLog(@"V7GoogleDriveViewController.logFilesList: %@", output);
395  // END = Log files list
396 }
397 @end
void logFilesList:(NSArray< GTLRDrive_File *> *fileArr)
GIDProfileData * profile
Definition: GIDGoogleUser.h:24
void addLoginListener:(id< Z5GoogleLoginListener > ear)
void listJournaItemPartRoot:for:(NSString *journalItemPartRootId, [for] id< V7GoogDriveAPIProtocol > requestor)
instancetype sharedInstance()
id< GTMFetcherAuthorizationProtocol > fetcherAuthorizer()
NSMutableDictionary * requestLine
NSString * journalRootId
void listJournalRootFor:(id< V7GoogDriveAPIProtocol > reqstor)
id< V7GoogDriveAPIProtocol > mDriveAPIDelegate
void createFolder:inFolder:(NSString *newFolderName, [inFolder] NSObject *parent)
GTLRServiceTicket * listJournaItemPartRoot:(NSString *journalItemPartRootId)
Singleton interface to both core and remote data sources.
GIDGoogleUser * currentUser
Definition: GIDSignIn.h:100
NSString * name
GIDSignIn * sharedInstance()
GIDAuthentication * authentication
Definition: GIDGoogleUser.h:27
GTLRServiceTicket * listJournalRoot:(NSString *journalRootId)