mirror of
https://github.com/nextcloud/desktop.git
synced 2024-12-17 11:21:51 +03:00
2fddf05515
The client (in this case mirall) tells the Finder plugin where to get the icons. This enables installation in different locations and in branded clients.
236 lines
6.2 KiB
Objective-C
236 lines
6.2 KiB
Objective-C
/**
|
|
* Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
|
|
*
|
|
* This library is free software; you can redistribute it and/or modify it under
|
|
* the terms of the GNU Lesser General Public License as published by the Free
|
|
* Software Foundation; either version 2.1 of the License, or (at your option)
|
|
* any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
|
* details.
|
|
*/
|
|
|
|
#import "ContentManager.h"
|
|
#import "IconCache.h"
|
|
#import "RequestManager.h"
|
|
|
|
#define READ_TAG 2422
|
|
|
|
static RequestManager* sharedInstance = nil;
|
|
|
|
@implementation RequestManager
|
|
|
|
- (id)init
|
|
{
|
|
if ((self = [super init]))
|
|
{
|
|
_socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
|
|
|
|
_isRunning = NO;
|
|
_isConnected = NO;
|
|
|
|
_registeredPathes = [[NSMutableDictionary alloc] init];
|
|
|
|
[self start];
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
- (void)dealloc
|
|
{
|
|
[_socket setDelegate:nil delegateQueue:NULL];
|
|
[_socket disconnect];
|
|
[_socket release];
|
|
|
|
sharedInstance = nil;
|
|
|
|
[super dealloc];
|
|
}
|
|
|
|
+ (RequestManager*)sharedInstance
|
|
{
|
|
@synchronized(self)
|
|
{
|
|
if (sharedInstance == nil)
|
|
{
|
|
sharedInstance = [[self alloc] init];
|
|
}
|
|
}
|
|
|
|
return sharedInstance;
|
|
}
|
|
|
|
|
|
- (void)askOnSocket:(NSString*)path query:(NSString*)verb
|
|
{
|
|
NSString *query = [NSString stringWithFormat:@"%@:%@\n", verb,path];
|
|
// NSLog(@"Query: %@", query);
|
|
|
|
NSData* data = [query dataUsingEncoding:NSUTF8StringEncoding];
|
|
[_socket writeData:data withTimeout:5 tag:4711];
|
|
|
|
NSData* stop = [@"\n" dataUsingEncoding:NSUTF8StringEncoding];
|
|
[_socket readDataToData:stop withTimeout:-1 tag:READ_TAG];
|
|
}
|
|
|
|
|
|
- (BOOL)isRegisteredPath:(NSString*)path
|
|
{
|
|
// check if the file in question is underneath a registered directory
|
|
NSArray *regPathes = [_registeredPathes allKeys];
|
|
BOOL registered = NO;
|
|
|
|
for( NSString *regPath in regPathes ) {
|
|
if( [path hasPrefix:regPath]) {
|
|
// the path was registered
|
|
registered = YES;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return registered;
|
|
}
|
|
|
|
- (NSNumber*)askForIcon:(NSString*)path isDirectory:(BOOL)isDir
|
|
{
|
|
NSString *verb = @"RETRIEVE_FILE_STATUS";
|
|
NSNumber *res = [NSNumber numberWithInt:0];
|
|
|
|
if( [self isRegisteredPath:path] ) {
|
|
if( _isConnected ) {
|
|
if(isDir) {
|
|
verb = @"RETRIEVE_FOLDER_STATUS";
|
|
}
|
|
|
|
[self askOnSocket:path query:verb];
|
|
|
|
NSNumber *res_minus_one = [NSNumber numberWithInt:0];
|
|
|
|
return res_minus_one;
|
|
} else {
|
|
[_requestQueue addObject:path];
|
|
[self start]; // try again to connect
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
|
|
- (void)socket:(GCDAsyncSocket*)socket didReadData:(NSData*)data withTag:(long)tag
|
|
{
|
|
NSArray *chunks;
|
|
NSString *answer = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
|
if (answer != nil && [answer length] > 0) {
|
|
// cut a trailing newline
|
|
answer = [answer substringToIndex:[answer length] - 1];
|
|
chunks = [answer componentsSeparatedByString: @":"];
|
|
}
|
|
NSLog(@"READ from socket (%ld): <%@>", tag, answer);
|
|
ContentManager *contentman = [ContentManager sharedInstance];
|
|
|
|
if( [chunks count] > 0 && tag == READ_TAG ) {
|
|
if( [[chunks objectAtIndex:0] isEqualToString:@"STATUS"] ) {
|
|
[contentman setResultForPath:[chunks objectAtIndex:2] result:[chunks objectAtIndex:1]];
|
|
} else if( [[chunks objectAtIndex:0] isEqualToString:@"UPDATE_VIEW"] ) {
|
|
NSString *path = [chunks objectAtIndex:1];
|
|
[contentman reFetchFileNameCacheForPath:path];
|
|
} else if( [[chunks objectAtIndex:0 ] isEqualToString:@"REGISTER_PATH"] ) {
|
|
NSNumber *one = [NSNumber numberWithInt:1];
|
|
NSString *path = [chunks objectAtIndex:1];
|
|
[_registeredPathes setObject:one forKey:path];
|
|
|
|
[contentman repaintAllWindows];
|
|
} else if( [[chunks objectAtIndex:0 ] isEqualToString:@"UNREGISTER_PATH"] ) {
|
|
NSNumber *one = [NSNumber numberWithInt:1];
|
|
NSString *path = [chunks objectAtIndex:1];
|
|
[_registeredPathes removeObjectForKey:path];
|
|
|
|
[contentman repaintAllWindows];
|
|
} else if( [[chunks objectAtIndex:0 ] isEqualToString:@"ICON_PATH"] ) {
|
|
NSString *path = [chunks objectAtIndex:1];
|
|
[[ContentManager sharedInstance] loadIconResourcePath:path];
|
|
} else {
|
|
NSLog(@"Unknown command %@", [chunks objectAtIndex:0]);
|
|
}
|
|
} else {
|
|
NSLog(@"Received unknown tag %ld", tag);
|
|
}
|
|
// Read on and on
|
|
NSData* stop = [@"\n" dataUsingEncoding:NSUTF8StringEncoding];
|
|
[_socket readDataToData:stop withTimeout:-1 tag:READ_TAG];
|
|
|
|
}
|
|
|
|
- (NSTimeInterval)socket:(GCDAsyncSocket*)socket shouldTimeoutReadWithTag:(long)tag elapsed:(NSTimeInterval)elapsed bytesDone:(NSUInteger)length
|
|
{
|
|
// Called if a read operation has reached its timeout without completing.
|
|
return 0.0;
|
|
}
|
|
|
|
- (void)socket:(GCDAsyncSocket*)socket didConnectToHost:(NSString*)host port:(UInt16)port
|
|
{
|
|
NSLog( @"Connected to host successfully!");
|
|
_isConnected = YES;
|
|
_isRunning = NO;
|
|
|
|
if( [_requestQueue count] > 0 ) {
|
|
NSLog( @"We have to empty the queue");
|
|
for( NSString *path in _requestQueue ) {
|
|
[self askOnSocket:path];
|
|
}
|
|
}
|
|
|
|
ContentManager *contentman = [ContentManager sharedInstance];
|
|
[contentman clearFileNameCacheForPath:nil];
|
|
[contentman repaintAllWindows];
|
|
|
|
// Read for the UPDATE_VIEW requests
|
|
NSData* stop = [@"\n" dataUsingEncoding:NSUTF8StringEncoding];
|
|
[_socket readDataToData:stop withTimeout:-1 tag:READ_TAG];
|
|
|
|
}
|
|
|
|
- (void)socketDidDisconnect:(GCDAsyncSocket*)socket withError:(NSError*)err
|
|
{
|
|
NSLog(@"Socket DISconnected!");
|
|
|
|
_isConnected = NO;
|
|
_isRunning = NO;
|
|
if( err ) {
|
|
NSLog(@"ERROR: %@", [err localizedDescription]);
|
|
}
|
|
|
|
// clear the registered pathes.
|
|
[_registeredPathes release];
|
|
_registeredPathes = [[NSMutableDictionary alloc] init];
|
|
|
|
// clear the caches in conent manager
|
|
ContentManager *contentman = [ContentManager sharedInstance];
|
|
[contentman clearFileNameCacheForPath:nil];
|
|
[contentman repaintAllWindows];
|
|
|
|
[NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(start) userInfo:nil repeats:NO];
|
|
|
|
}
|
|
|
|
|
|
- (void)start
|
|
{
|
|
if (!_isRunning)
|
|
{
|
|
NSLog(@"Connect Socket!");
|
|
NSError *err = nil;
|
|
if (![_socket connectToHost:@"localhost" onPort:34001 withTimeout:5 error:&err]) // Asynchronous!
|
|
{
|
|
// If there was an error, it's likely something like "already connected" or "no delegate set"
|
|
NSLog(@"I goofed: %@", err);
|
|
}
|
|
|
|
_isRunning = YES;
|
|
}
|
|
}
|
|
|
|
@end
|