Cute and funny game
This commit is contained in:
parent
e23deb75e3
commit
cbd2fe866c
@ -7,6 +7,10 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
802B076229515EE20019C2B1 /* BooruClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 802B076129515EE20019C2B1 /* BooruClient.m */; };
|
||||
802B07682952C38C0019C2B1 /* BooruXMLParserDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 802B07672952C38C0019C2B1 /* BooruXMLParserDelegate.m */; };
|
||||
802B076C2952CDBB0019C2B1 /* BooruImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 802B076B2952CDBB0019C2B1 /* BooruImage.m */; };
|
||||
802B076F2952D07D0019C2B1 /* ClickableImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 802B076E2952D07D0019C2B1 /* ClickableImageView.m */; };
|
||||
BC6610FD294C62B900277180 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BC6610FC294C62B900277180 /* Cocoa.framework */; };
|
||||
BC661107294C62B900277180 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = BC661105294C62B900277180 /* InfoPlist.strings */; };
|
||||
BC661109294C62B900277180 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = BC661108294C62B900277180 /* main.m */; };
|
||||
@ -30,7 +34,15 @@
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
BC6610F9294C62B900277180 /* Cunny Corrector.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Cunny Corrector.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
802B076029515EE20019C2B1 /* BooruClient.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BooruClient.h; sourceTree = "<group>"; };
|
||||
802B076129515EE20019C2B1 /* BooruClient.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BooruClient.m; sourceTree = "<group>"; };
|
||||
802B07662952C38C0019C2B1 /* BooruXMLParserDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BooruXMLParserDelegate.h; sourceTree = "<group>"; };
|
||||
802B07672952C38C0019C2B1 /* BooruXMLParserDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BooruXMLParserDelegate.m; sourceTree = "<group>"; };
|
||||
802B076A2952CDBB0019C2B1 /* BooruImage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BooruImage.h; sourceTree = "<group>"; };
|
||||
802B076B2952CDBB0019C2B1 /* BooruImage.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BooruImage.m; sourceTree = "<group>"; };
|
||||
802B076D2952D07D0019C2B1 /* ClickableImageView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ClickableImageView.h; sourceTree = "<group>"; };
|
||||
802B076E2952D07D0019C2B1 /* ClickableImageView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ClickableImageView.m; sourceTree = "<group>"; };
|
||||
BC6610F9294C62B900277180 /* Cunny Collector.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Cunny Collector.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
BC6610FC294C62B900277180 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
|
||||
BC6610FF294C62B900277180 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
|
||||
BC661100294C62B900277180 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
|
||||
@ -72,6 +84,28 @@
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
802B07692952CD640019C2B1 /* libbooru */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
802B076029515EE20019C2B1 /* BooruClient.h */,
|
||||
802B076129515EE20019C2B1 /* BooruClient.m */,
|
||||
802B07662952C38C0019C2B1 /* BooruXMLParserDelegate.h */,
|
||||
802B07672952C38C0019C2B1 /* BooruXMLParserDelegate.m */,
|
||||
802B076A2952CDBB0019C2B1 /* BooruImage.h */,
|
||||
802B076B2952CDBB0019C2B1 /* BooruImage.m */,
|
||||
);
|
||||
path = libbooru;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
802B07732952F4D40019C2B1 /* ui */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
802B076D2952D07D0019C2B1 /* ClickableImageView.h */,
|
||||
802B076E2952D07D0019C2B1 /* ClickableImageView.m */,
|
||||
);
|
||||
path = ui;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BC6610F0294C62B900277180 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -85,7 +119,7 @@
|
||||
BC6610FA294C62B900277180 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BC6610F9294C62B900277180 /* Cunny Corrector.app */,
|
||||
BC6610F9294C62B900277180 /* Cunny Collector.app */,
|
||||
BC661119294C62BA00277180 /* cunnyfinderTests.octest */,
|
||||
);
|
||||
name = Products;
|
||||
@ -114,6 +148,8 @@
|
||||
BC661102294C62B900277180 /* cunnyfinder */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
802B07732952F4D40019C2B1 /* ui */,
|
||||
802B07692952CD640019C2B1 /* libbooru */,
|
||||
BC66110E294C62B900277180 /* AppDelegate.h */,
|
||||
BC66110F294C62B900277180 /* AppDelegate.m */,
|
||||
BC661111294C62BA00277180 /* MainMenu.xib */,
|
||||
@ -170,7 +206,7 @@
|
||||
);
|
||||
name = cunnyfinder;
|
||||
productName = cunnyfinder;
|
||||
productReference = BC6610F9294C62B900277180 /* Cunny Corrector.app */;
|
||||
productReference = BC6610F9294C62B900277180 /* Cunny Collector.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
BC661118294C62BA00277180 /* cunnyfinderTests */ = {
|
||||
@ -206,6 +242,7 @@
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
English,
|
||||
en,
|
||||
);
|
||||
mainGroup = BC6610F0294C62B900277180;
|
||||
@ -263,6 +300,10 @@
|
||||
files = (
|
||||
BC661109294C62B900277180 /* main.m in Sources */,
|
||||
BC661110294C62B900277180 /* AppDelegate.m in Sources */,
|
||||
802B076C2952CDBB0019C2B1 /* BooruImage.m in Sources */,
|
||||
802B076F2952D07D0019C2B1 /* ClickableImageView.m in Sources */,
|
||||
802B076229515EE20019C2B1 /* BooruClient.m in Sources */,
|
||||
802B07682952C38C0019C2B1 /* BooruXMLParserDelegate.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -386,7 +427,8 @@
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "cunnyfinder/cunnyfinder-Prefix.pch";
|
||||
INFOPLIST_FILE = "cunnyfinder/cunnyfinder-Info.plist";
|
||||
PRODUCT_NAME = "Cunny Corrector";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = jp.femboyfinancial.CunnyCollector;
|
||||
PRODUCT_NAME = "Cunny Collector";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Debug;
|
||||
@ -398,7 +440,8 @@
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = "cunnyfinder/cunnyfinder-Prefix.pch";
|
||||
INFOPLIST_FILE = "cunnyfinder/cunnyfinder-Info.plist";
|
||||
PRODUCT_NAME = "Cunny Corrector";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = jp.femboyfinancial.CunnyCollector;
|
||||
PRODUCT_NAME = "Cunny Collector";
|
||||
WRAPPER_EXTENSION = app;
|
||||
};
|
||||
name = Release;
|
||||
@ -452,6 +495,7 @@
|
||||
BC66112C294C62BA00277180 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
BC66112D294C62BA00277180 /* Build configuration list for PBXNativeTarget "cunnyfinderTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
@ -460,6 +504,7 @@
|
||||
BC66112F294C62BA00277180 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
|
@ -8,10 +8,12 @@
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface AppDelegate : NSObject <NSApplicationDelegate>
|
||||
@interface AppDelegate : NSObject<NSApplicationDelegate>
|
||||
|
||||
@property (assign) IBOutlet NSWindow *window;
|
||||
|
||||
-(IBAction)actionUohhh:(id)sender;
|
||||
-(NSRect)randomPositionWithWidth:(int)width height:(int)height;
|
||||
-(void)addWaifu:(id)btn;
|
||||
|
||||
@end
|
||||
|
@ -7,12 +7,48 @@
|
||||
//
|
||||
|
||||
#import "AppDelegate.h"
|
||||
#import "libbooru/BooruClient.h"
|
||||
#import "ui/ClickableImageView.h"
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
|
||||
BooruClient* booru;
|
||||
|
||||
-(void)applicationDidFinishLaunching:(NSNotification *)aNotification
|
||||
{
|
||||
// Insert code here to initialize your application
|
||||
booru = [[BooruClient alloc] init:@[@"hatsune_miku", @"kuroki_tomoko", @"monika_(doki_doki_literature_club)", @"megumin"]];
|
||||
}
|
||||
|
||||
-(NSRect)randomPositionWithWidth:(int)width height:(int)height
|
||||
{
|
||||
float x = arc4random_uniform(self.window.frame.size.width - width);
|
||||
float y = arc4random_uniform(self.window.frame.size.height - height);
|
||||
NSRect rect = NSMakeRect(x, y, width, height);
|
||||
return rect;
|
||||
}
|
||||
|
||||
-(void)addWaifu:(id)btn
|
||||
{
|
||||
// find the image
|
||||
BooruImage* img = [booru search];
|
||||
|
||||
// download and show image
|
||||
NSRect frame = [self randomPositionWithWidth:[img previewWidth] height:[img previewHeight]];
|
||||
ClickableImageView* imgView = [[ClickableImageView alloc] initWithFrame:frame imageUrl:[img fileUrl]];
|
||||
NSURL* displayUrl;
|
||||
if ([img hasSample])
|
||||
{
|
||||
displayUrl = [img sampleUrl];
|
||||
}
|
||||
else
|
||||
{
|
||||
displayUrl = [img fileUrl];
|
||||
}
|
||||
[booru downloadAndDisplayImage:displayUrl inView:imgView];
|
||||
[self.window.contentView addSubview:imgView positioned:NSWindowBelow relativeTo:btn];
|
||||
|
||||
// cleanup
|
||||
[booru reset];
|
||||
}
|
||||
|
||||
-(IBAction)actionUohhh:(id)sender
|
||||
@ -25,12 +61,9 @@
|
||||
[alert setAlertStyle:NSInformationalAlertStyle];
|
||||
[alert runModal];
|
||||
*/
|
||||
float x = arc4random_uniform(self.window.frame.size.width - 48);
|
||||
float y = arc4random_uniform(self.window.frame.size.height - 48);
|
||||
bool brat = arc4random_uniform(20) == 0;
|
||||
|
||||
NSRect rect = NSMakeRect(x, y, 48, 48);
|
||||
NSTextField *label = [[NSTextField alloc] initWithFrame:rect];
|
||||
NSTextField *label = [[NSTextField alloc] initWithFrame:[self randomPositionWithWidth:48 height:48]];
|
||||
[label setEditable:false];
|
||||
[label setBezeled:false];
|
||||
[label setFont:[NSFont fontWithName:@"Apple Color Emoji" size:32]];
|
||||
@ -38,6 +71,7 @@
|
||||
[label setAlignment:NSCenterTextAlignment];
|
||||
if (brat) {
|
||||
[label setStringValue:@"💢"];
|
||||
[self addWaifu:sender];
|
||||
} else {
|
||||
[label setStringValue:@"😭"];
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>jp.femboyfinancial.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
|
@ -1,15 +1,17 @@
|
||||
{\rtf1\ansi\ansicpg1252\cocoartf1138\cocoasubrtf510
|
||||
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
|
||||
{\rtf1\ansi\ansicpg1252\cocoartf2580
|
||||
\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica-Bold;\f1\fswiss\fcharset0 Helvetica;}
|
||||
{\colortbl;\red255\green255\blue255;}
|
||||
{\*\expandedcolortbl;;}
|
||||
\vieww9600\viewh8400\viewkind0
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
|
||||
|
||||
\f0\b\fs24 \cf0 Programming:
|
||||
\b0 \
|
||||
\f1\b0 \
|
||||
James Shiffer\
|
||||
\
|
||||
|
||||
\b Special Thanks:
|
||||
\b0 \
|
||||
\f0\b Special Thanks:
|
||||
\f1\b0 \
|
||||
abmayo\
|
||||
dorontabi}
|
||||
dorontabi\
|
||||
Gelbooru.com}
|
@ -42,7 +42,7 @@
|
||||
<array class="NSMutableArray" key="NSMenuItems">
|
||||
<object class="NSMenuItem" id="694149608">
|
||||
<reference key="NSMenu" ref="649796088"/>
|
||||
<string key="NSTitle">Cunny Corrector</string>
|
||||
<string key="NSTitle">Cunny Collector</string>
|
||||
<string key="NSKeyEquiv"/>
|
||||
<int key="NSKeyEquivModMask">1048576</int>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
@ -56,11 +56,11 @@
|
||||
</object>
|
||||
<string key="NSAction">submenuAction:</string>
|
||||
<object class="NSMenu" key="NSSubmenu" id="110575045">
|
||||
<string key="NSTitle">Cunny Corrector</string>
|
||||
<string key="NSTitle">Cunny Collector</string>
|
||||
<array class="NSMutableArray" key="NSMenuItems">
|
||||
<object class="NSMenuItem" id="238522557">
|
||||
<reference key="NSMenu" ref="110575045"/>
|
||||
<string key="NSTitle">About Cunny Corrector</string>
|
||||
<string key="NSTitle">About Cunny Collector</string>
|
||||
<string key="NSKeyEquiv"/>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
<reference key="NSOnImage" ref="35465992"/>
|
||||
@ -125,7 +125,7 @@
|
||||
</object>
|
||||
<object class="NSMenuItem" id="755159360">
|
||||
<reference key="NSMenu" ref="110575045"/>
|
||||
<string key="NSTitle">Hide Cunny</string>
|
||||
<string key="NSTitle">Hide Cunny Collector</string>
|
||||
<string key="NSKeyEquiv">h</string>
|
||||
<int key="NSKeyEquivModMask">1048576</int>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
@ -163,7 +163,7 @@
|
||||
</object>
|
||||
<object class="NSMenuItem" id="632727374">
|
||||
<reference key="NSMenu" ref="110575045"/>
|
||||
<string key="NSTitle">Quit Cunny Corrector</string>
|
||||
<string key="NSTitle">Quit Cunny Collector</string>
|
||||
<string key="NSKeyEquiv">q</string>
|
||||
<int key="NSKeyEquivModMask">1048576</int>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
@ -366,7 +366,7 @@
|
||||
<array class="NSMutableArray" key="NSMenuItems">
|
||||
<object class="NSMenuItem" id="105068016">
|
||||
<reference key="NSMenu" ref="992780483"/>
|
||||
<string key="NSTitle">cunnyfinder Help</string>
|
||||
<string key="NSTitle">Cunny Collector Help</string>
|
||||
<string key="NSKeyEquiv">?</string>
|
||||
<int key="NSKeyEquivModMask">1048576</int>
|
||||
<int key="NSMnemonicLoc">2147483647</int>
|
||||
@ -385,7 +385,7 @@
|
||||
<int key="NSWindowBacking">2</int>
|
||||
<string key="NSWindowRect">{{335, 390}, {480, 360}}</string>
|
||||
<int key="NSWTFlags">1954021376</int>
|
||||
<string key="NSWindowTitle">Cunny Corrector</string>
|
||||
<string key="NSWindowTitle">Cunny Collector</string>
|
||||
<string key="NSWindowClass">NSWindow</string>
|
||||
<nil key="NSViewClass"/>
|
||||
<nil key="NSUserInterfaceItemIdentifier"/>
|
||||
|
29
cunnyfinder/libbooru/BooruClient.h
Normal file
29
cunnyfinder/libbooru/BooruClient.h
Normal file
@ -0,0 +1,29 @@
|
||||
//
|
||||
// BooruClient.h
|
||||
// cunnyfinder
|
||||
//
|
||||
// Created by James Shiffer on 12/19/22.
|
||||
// Copyright © 2022 FemboyFinancial. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "BooruImage.h"
|
||||
#import "BooruXMLParserDelegate.h"
|
||||
|
||||
@interface BooruClient : NSObject
|
||||
|
||||
@property NSString* urlFormat;
|
||||
@property NSString* tags;
|
||||
@property NSMutableArray* waifus;
|
||||
@property NSDictionary<NSString*, NSString*>* metadata;
|
||||
@property NSImageView* imageView;
|
||||
|
||||
-(id)init:(NSArray *)waifus;
|
||||
-(void)reset;
|
||||
-(BooruImage *)search;
|
||||
-(void)downloadAndDisplayImage:(NSURL *)url inView:(NSImageView *)imageView;
|
||||
-(void)downloadImage:(NSURL *)url;
|
||||
-(void)displayImage:(NSImage *)image;
|
||||
+(NSString *)urlEncode:(NSString *)str;
|
||||
|
||||
@end
|
81
cunnyfinder/libbooru/BooruClient.m
Normal file
81
cunnyfinder/libbooru/BooruClient.m
Normal file
@ -0,0 +1,81 @@
|
||||
//
|
||||
// BooruClient.m
|
||||
// cunnyfinder
|
||||
//
|
||||
// Created by James Shiffer on 12/19/22.
|
||||
// Copyright © 2022 FemboyFinancial. All rights reserved.
|
||||
//
|
||||
|
||||
#import "BooruClient.h"
|
||||
|
||||
@implementation BooruClient
|
||||
|
||||
-(id)init:(NSArray *)waifus
|
||||
{
|
||||
self.urlFormat = @"https://gelbooru.com/index.php?page=dapi&s=post&q=index&limit=1&tags=%@%%20%@";
|
||||
self.tags = @"score%3A%3E%3D10%20sort%3Arandom%201girl%20solo";
|
||||
self.waifus = [[NSMutableArray alloc] initWithArray:waifus];
|
||||
self.metadata = nil;
|
||||
return self;
|
||||
}
|
||||
|
||||
+(NSString *)urlEncode:(NSString*)str
|
||||
{
|
||||
CFStringRef urlString = CFURLCreateStringByAddingPercentEscapes(
|
||||
NULL,
|
||||
(CFStringRef)str,
|
||||
NULL,
|
||||
(CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
|
||||
kCFStringEncodingUTF8
|
||||
);
|
||||
return (NSString *)CFBridgingRelease(urlString);
|
||||
}
|
||||
|
||||
|
||||
-(BooruImage *)search
|
||||
{
|
||||
NSString* randomWaifu = self.waifus[arc4random_uniform(self.waifus.count)];
|
||||
NSLog(@"searching for pics of %@", randomWaifu);
|
||||
NSString* urlStr = [[NSString alloc] initWithFormat:self.urlFormat, self.tags, [BooruClient urlEncode:randomWaifu]];
|
||||
NSURL* url = [NSURL URLWithString:urlStr];
|
||||
NSXMLParser* xml = [[NSXMLParser alloc] initWithContentsOfURL:url];
|
||||
BooruXMLParserDelegate* parser = [[BooruXMLParserDelegate alloc] init];
|
||||
[xml setDelegate:parser];
|
||||
[xml setShouldProcessNamespaces:NO];
|
||||
[xml setShouldReportNamespacePrefixes:NO];
|
||||
[xml setShouldResolveExternalEntities:NO];
|
||||
[xml parse];
|
||||
if ([xml parserError])
|
||||
{
|
||||
NSLog(@"parsing error: %@", [xml parserError]);
|
||||
}
|
||||
NSLog(@"found image id: %@", parser.data[@"id"]);
|
||||
return [[BooruImage alloc] init:parser.data];
|
||||
}
|
||||
|
||||
-(void)downloadAndDisplayImage:(NSURL *)url inView:(NSImageView *)imageView
|
||||
{
|
||||
self.imageView = imageView;
|
||||
NSOperationQueue* queue = [NSOperationQueue new];
|
||||
NSInvocationOperation* operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadImage:) object:url];
|
||||
[queue addOperation:operation];
|
||||
}
|
||||
|
||||
-(void)downloadImage:(NSURL *)url
|
||||
{
|
||||
NSData* imageData = [[NSData alloc] initWithContentsOfURL:url];
|
||||
NSImage* image = [[NSImage alloc] initWithData:imageData];
|
||||
[self performSelectorOnMainThread:@selector(displayImage:) withObject:image waitUntilDone:YES];
|
||||
}
|
||||
|
||||
-(void)displayImage:(NSImage *)image
|
||||
{
|
||||
self.imageView.image = image;
|
||||
}
|
||||
|
||||
-(void)reset
|
||||
{
|
||||
self.metadata = nil;
|
||||
}
|
||||
|
||||
@end
|
27
cunnyfinder/libbooru/BooruImage.h
Normal file
27
cunnyfinder/libbooru/BooruImage.h
Normal file
@ -0,0 +1,27 @@
|
||||
//
|
||||
// BooruImage.h
|
||||
// cunnyfinder
|
||||
//
|
||||
// Created by James Shiffer on 12/20/22.
|
||||
// Copyright © 2022 FemboyFinancial. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface BooruImage : NSObject
|
||||
|
||||
@property NSDictionary<NSString*, NSString*>* metadata;
|
||||
|
||||
-(id)init:(NSDictionary<NSString*, NSString*> *)metadata;
|
||||
-(int)width;
|
||||
-(int)height;
|
||||
-(int)previewWidth;
|
||||
-(int)previewHeight;
|
||||
-(int)sampleWidth;
|
||||
-(int)sampleHeight;
|
||||
-(bool)hasSample;
|
||||
-(NSURL *)fileUrl;
|
||||
-(NSURL *)previewUrl;
|
||||
-(NSURL *)sampleUrl;
|
||||
|
||||
@end
|
109
cunnyfinder/libbooru/BooruImage.m
Normal file
109
cunnyfinder/libbooru/BooruImage.m
Normal file
@ -0,0 +1,109 @@
|
||||
//
|
||||
// BooruImage.m
|
||||
// cunnyfinder
|
||||
//
|
||||
// Created by James Shiffer on 12/20/22.
|
||||
// Copyright © 2022 FemboyFinancial. All rights reserved.
|
||||
//
|
||||
|
||||
#import "BooruImage.h"
|
||||
|
||||
@implementation BooruImage
|
||||
|
||||
-(id)init:(NSDictionary<NSString*, NSString*> *)metadata
|
||||
{
|
||||
self.metadata = [[NSDictionary alloc] initWithDictionary:metadata];
|
||||
return self;
|
||||
}
|
||||
|
||||
-(int)width
|
||||
{
|
||||
if (!self.metadata)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return [self.metadata[@"width"] integerValue];
|
||||
}
|
||||
|
||||
-(int)height
|
||||
{
|
||||
if (!self.metadata)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return [self.metadata[@"height"] integerValue];
|
||||
}
|
||||
|
||||
-(int)previewWidth
|
||||
{
|
||||
if (!self.metadata)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return [self.metadata[@"preview_width"] integerValue];
|
||||
}
|
||||
|
||||
-(int)previewHeight
|
||||
{
|
||||
if (!self.metadata)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return [self.metadata[@"preview_height"] integerValue];
|
||||
}
|
||||
|
||||
-(int)sampleWidth
|
||||
{
|
||||
if (!self.metadata || ![self hasSample])
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return [self.metadata[@"sample_width"] integerValue];
|
||||
}
|
||||
|
||||
-(int)sampleHeight
|
||||
{
|
||||
if (!self.metadata || ![self hasSample])
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return [self.metadata[@"sample_height"] integerValue];
|
||||
}
|
||||
|
||||
-(NSURL *)fileUrl
|
||||
{
|
||||
if (!self.metadata)
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
return [NSURL URLWithString:self.metadata[@"file_url"]];
|
||||
}
|
||||
|
||||
-(NSURL *)previewUrl
|
||||
{
|
||||
if (!self.metadata)
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
return [NSURL URLWithString:self.metadata[@"preview_url"]];
|
||||
}
|
||||
|
||||
-(NSURL *)sampleUrl
|
||||
{
|
||||
if (!self.metadata || ![self hasSample])
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
return [NSURL URLWithString:self.metadata[@"sample_url"]];
|
||||
}
|
||||
|
||||
-(bool)hasSample
|
||||
{
|
||||
if (!self.metadata)
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
return [self.metadata[@"sample"] boolValue];
|
||||
}
|
||||
|
||||
@end
|
30
cunnyfinder/libbooru/BooruXMLParserDelegate.h
Normal file
30
cunnyfinder/libbooru/BooruXMLParserDelegate.h
Normal file
@ -0,0 +1,30 @@
|
||||
//
|
||||
// BooruXMLParserDelegate.h
|
||||
// cunnyfinder
|
||||
//
|
||||
// Created by James Shiffer on 12/20/22.
|
||||
// Copyright © 2022 FemboyFinancial. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface BooruXMLParserDelegate : NSObject<NSXMLParserDelegate>
|
||||
|
||||
@property NSMutableDictionary<NSString *, NSString *>* data;
|
||||
|
||||
-(id)init;
|
||||
-(void)parser:(NSXMLParser *)parser
|
||||
didStartElement:(NSString *)elementName
|
||||
namespaceURI:(NSString *)namespaceURI
|
||||
qualifiedName:(NSString *)qName
|
||||
attributes:(NSDictionary<NSString *, NSString *> *)attributeDict;
|
||||
|
||||
-(void)parser:(NSXMLParser *)parser
|
||||
foundCharacters:(NSString *)string;
|
||||
|
||||
-(void)parser:(NSXMLParser *)parser
|
||||
didEndElement:(NSString *)elementName
|
||||
namespaceURI:(NSString *)namespaceURI
|
||||
qualifiedName:(NSString *)qName;
|
||||
|
||||
@end
|
46
cunnyfinder/libbooru/BooruXMLParserDelegate.m
Normal file
46
cunnyfinder/libbooru/BooruXMLParserDelegate.m
Normal file
@ -0,0 +1,46 @@
|
||||
//
|
||||
// BooruXMLParserDelegate.m
|
||||
// cunnyfinder
|
||||
//
|
||||
// Created by James Shiffer on 12/20/22.
|
||||
// Copyright © 2022 FemboyFinancial. All rights reserved.
|
||||
//
|
||||
|
||||
#import "BooruXMLParserDelegate.h"
|
||||
|
||||
@implementation BooruXMLParserDelegate
|
||||
|
||||
NSMutableString* value;
|
||||
|
||||
-(id)init
|
||||
{
|
||||
self.data = [[NSMutableDictionary alloc] init];
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)parser:(NSXMLParser *)parser
|
||||
didStartElement:(NSString *)elementName
|
||||
namespaceURI:(NSString *)namespaceURI
|
||||
qualifiedName:(NSString *)qName
|
||||
attributes:(NSDictionary<NSString *,NSString *> *)attributeDict
|
||||
{
|
||||
value = [NSMutableString string];
|
||||
}
|
||||
|
||||
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
|
||||
{
|
||||
[value appendString:string];
|
||||
}
|
||||
|
||||
-(void)parser:(NSXMLParser *)parser
|
||||
didEndElement:(NSString *)elementName
|
||||
namespaceURI:(NSString *)namespaceURI
|
||||
qualifiedName:(NSString *)qName
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
[self.data setObject:value forKey:elementName];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
21
cunnyfinder/ui/ClickableImageView.h
Normal file
21
cunnyfinder/ui/ClickableImageView.h
Normal file
@ -0,0 +1,21 @@
|
||||
//
|
||||
// ClickableImageView.h
|
||||
// cunnyfinder
|
||||
//
|
||||
// Created by James Shiffer on 12/20/22.
|
||||
// Copyright © 2022 FemboyFinancial. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface ClickableImageView : NSImageView
|
||||
|
||||
@property NSURL* fileUrl;
|
||||
|
||||
-(id)initWithFrame:(NSRect)frame imageUrl:(NSURL *)fileUrl;
|
||||
-(void)mouseDown:(NSEvent *)event;
|
||||
-(void)downloadImage:(NSString *)filePath;
|
||||
-(void)downloadAndSaveImage:(NSString *)filePath;
|
||||
-(void)showWarning:(id)sender;
|
||||
|
||||
@end
|
68
cunnyfinder/ui/ClickableImageView.m
Normal file
68
cunnyfinder/ui/ClickableImageView.m
Normal file
@ -0,0 +1,68 @@
|
||||
//
|
||||
// ClickableImageView.m
|
||||
// cunnyfinder
|
||||
//
|
||||
// Created by James Shiffer on 12/20/22.
|
||||
// Copyright © 2022 FemboyFinancial. All rights reserved.
|
||||
//
|
||||
|
||||
#import "ClickableImageView.h"
|
||||
|
||||
@implementation ClickableImageView
|
||||
|
||||
-(id)initWithFrame:(NSRect)frame imageUrl:(NSURL *)fileUrl
|
||||
{
|
||||
self = [super initWithFrame:frame];
|
||||
self.fileUrl = fileUrl;
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)drawRect:(NSRect)dirtyRect
|
||||
{
|
||||
[super drawRect:dirtyRect];
|
||||
// Drawing code here.
|
||||
}
|
||||
|
||||
-(void)downloadImage:(NSString *)filePath
|
||||
{
|
||||
NSOperationQueue* queue = [NSOperationQueue new];
|
||||
NSInvocationOperation* operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadAndSaveImage:) object:filePath];
|
||||
[queue addOperation:operation];
|
||||
}
|
||||
|
||||
-(void)downloadAndSaveImage:(NSString *)filePath
|
||||
{
|
||||
NSData* imageData = [[NSData alloc] initWithContentsOfURL:self.fileUrl];
|
||||
NSFileManager* fs = [[NSFileManager alloc] init];
|
||||
BOOL success = [fs createFileAtPath:filePath contents:imageData attributes:nil];
|
||||
if (!success)
|
||||
{
|
||||
[self performSelectorOnMainThread:@selector(showWarning:) withObject:nil waitUntilDone:YES];
|
||||
}
|
||||
}
|
||||
|
||||
-(void)showWarning:(id)sender
|
||||
{
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
[alert addButtonWithTitle:@"OK"];
|
||||
[alert setMessageText:@"Uohhh!"];
|
||||
[alert setIcon:[NSImage imageNamed:NSImageNameCaution]];
|
||||
[alert setInformativeText:@"Damn bratty file failed to save... correction is needed!"];
|
||||
[alert setAlertStyle:NSWarningAlertStyle];
|
||||
[alert beginSheetModalForWindow:self.window completionHandler:nil];
|
||||
}
|
||||
|
||||
-(void)mouseDown:(NSEvent *)event
|
||||
{
|
||||
NSSavePanel* panel = [NSSavePanel savePanel];
|
||||
panel.allowedFileTypes = @[[self.fileUrl pathExtension]];
|
||||
panel.nameFieldStringValue = [self.fileUrl lastPathComponent];
|
||||
[panel beginSheetModalForWindow:self.window completionHandler:^(NSInteger result) {
|
||||
if (result == NSFileHandlingPanelOKButton)
|
||||
{
|
||||
[self downloadImage:[panel filename]];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
Loading…
x
Reference in New Issue
Block a user