├── .gitignore
├── ImageHosting.xcodeproj
├── project.pbxproj
└── project.xcworkspace
│ └── contents.xcworkspacedata
├── ImageHosting
├── Addition
│ ├── NSColor+IHAddition.h
│ ├── NSColor+IHAddition.m
│ ├── NSString+IHAddition.h
│ ├── NSString+IHAddition.m
│ ├── NSString+IHURL.h
│ └── NSString+IHURL.m
├── Application
│ ├── AppDelegate.h
│ ├── AppDelegate.m
│ └── IHCommon.h
├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── icon128.png
│ │ ├── icon128@2x.png
│ │ ├── icon16.png
│ │ ├── icon16@2x.png
│ │ ├── icon256.png
│ │ ├── icon256@2x.png
│ │ ├── icon32.png
│ │ ├── icon32@2x.png
│ │ ├── icon512.png
│ │ └── icon512@2x.png
│ ├── Contents.json
│ ├── about.imageset
│ │ ├── Contents.json
│ │ ├── icon128.png
│ │ └── icon128@2x.png
│ ├── fail.imageset
│ │ ├── Contents.json
│ │ └── fail.png
│ ├── failure.imageset
│ │ ├── Contents.json
│ │ ├── Failure.png
│ │ ├── Failure@2x.png
│ │ └── Failure@3x.png
│ ├── line.imageset
│ │ ├── Contents.json
│ │ └── line.png
│ ├── logo.imageset
│ │ ├── Contents.json
│ │ ├── logo.png
│ │ ├── logo@2x.png
│ │ └── logo@3x.png
│ ├── success.imageset
│ │ ├── Contents.json
│ │ └── success.png
│ └── successful.imageset
│ │ ├── Contents.json
│ │ ├── success.png
│ │ ├── success@2x.png
│ │ └── success@3x.png
├── Base.lproj
│ └── Main.storyboard
├── Controller
│ ├── View
│ │ ├── IHPreferencesAccountsViewController.h
│ │ ├── IHPreferencesAccountsViewController.m
│ │ ├── IHPreferencesAccountsViewController.xib
│ │ ├── IHPreferencesFeedbackViewController.h
│ │ ├── IHPreferencesFeedbackViewController.m
│ │ ├── IHPreferencesFeedbackViewController.xib
│ │ ├── IHPreferencesGeneralViewController.h
│ │ ├── IHPreferencesGeneralViewController.m
│ │ ├── IHPreferencesGeneralViewController.xib
│ │ ├── IHViewController.h
│ │ └── IHViewController.m
│ └── Window
│ │ ├── IHAboutWindowController.h
│ │ ├── IHAboutWindowController.m
│ │ ├── IHAboutWindowController.xib
│ │ ├── IHPreferencesWindowController.h
│ │ ├── IHPreferencesWindowController.m
│ │ ├── IHPreferencesWindowController.xib
│ │ ├── IHUploadWindowController.h
│ │ ├── IHUploadWindowController.m
│ │ ├── IHUploadWindowController.xib
│ │ ├── IHWindowController.h
│ │ └── IHWindowController.m
├── External
│ ├── AFNetworking
│ │ ├── AFHTTPSessionManager.h
│ │ ├── AFHTTPSessionManager.m
│ │ ├── AFNetworkReachabilityManager.h
│ │ ├── AFNetworkReachabilityManager.m
│ │ ├── AFNetworking.h
│ │ ├── AFSecurityPolicy.h
│ │ ├── AFSecurityPolicy.m
│ │ ├── AFURLRequestSerialization.h
│ │ ├── AFURLRequestSerialization.m
│ │ ├── AFURLResponseSerialization.h
│ │ ├── AFURLResponseSerialization.m
│ │ ├── AFURLSessionManager.h
│ │ └── AFURLSessionManager.m
│ ├── AGAsyncTestHelper
│ │ └── AGAsyncTestHelper.h
│ ├── BRLinkLabel
│ │ ├── BRLinkLabel.h
│ │ └── BRLinkLabel.m
│ ├── HappyDNS
│ │ ├── Common
│ │ │ ├── QNDnsManager.h
│ │ │ ├── QNDnsManager.m
│ │ │ ├── QNDomain.h
│ │ │ ├── QNDomain.m
│ │ │ ├── QNLruCache.h
│ │ │ ├── QNLruCache.m
│ │ │ ├── QNNetworkInfo.h
│ │ │ ├── QNNetworkInfo.m
│ │ │ ├── QNRecord.h
│ │ │ ├── QNRecord.m
│ │ │ └── QNResolverDelegate.h
│ │ ├── HappyDNS.h
│ │ ├── Http
│ │ │ ├── QNDnspodEnterprise.h
│ │ │ ├── QNDnspodEnterprise.m
│ │ │ ├── QNDnspodFree.h
│ │ │ └── QNDnspodFree.m
│ │ ├── Local
│ │ │ ├── QNHijackingDetectWrapper.h
│ │ │ ├── QNHijackingDetectWrapper.m
│ │ │ ├── QNHosts.h
│ │ │ ├── QNHosts.m
│ │ │ ├── QNResolvUtil.h
│ │ │ ├── QNResolvUtil.m
│ │ │ ├── QNResolver.h
│ │ │ ├── QNResolver.m
│ │ │ ├── QNTxtResolver.h
│ │ │ └── QNTxtResolver.m
│ │ └── Util
│ │ │ ├── QNDes.h
│ │ │ ├── QNDes.m
│ │ │ ├── QNGetAddrInfo.h
│ │ │ ├── QNGetAddrInfo.m
│ │ │ ├── QNHex.h
│ │ │ ├── QNHex.m
│ │ │ ├── QNIP.h
│ │ │ └── QNIP.m
│ ├── JSONKit
│ │ ├── JSONKit.h
│ │ └── JSONKit.m
│ ├── QiniuSDK
│ │ ├── Common
│ │ │ ├── QNALAssetFile.h
│ │ │ ├── QNALAssetFile.m
│ │ │ ├── QNAsyncRun.h
│ │ │ ├── QNAsyncRun.m
│ │ │ ├── QNCrc32.h
│ │ │ ├── QNCrc32.m
│ │ │ ├── QNEtag.h
│ │ │ ├── QNEtag.m
│ │ │ ├── QNFile.h
│ │ │ ├── QNFile.m
│ │ │ ├── QNFileDelegate.h
│ │ │ ├── QNPHAssetFile.h
│ │ │ ├── QNPHAssetFile.m
│ │ │ ├── QNPHAssetResource.h
│ │ │ ├── QNPHAssetResource.m
│ │ │ ├── QNSystem.h
│ │ │ ├── QNSystem.m
│ │ │ ├── QNUrlSafeBase64.h
│ │ │ ├── QNUrlSafeBase64.m
│ │ │ ├── QNVersion.h
│ │ │ ├── QN_GTM_Base64.h
│ │ │ └── QN_GTM_Base64.m
│ │ ├── Http
│ │ │ ├── QNHttpDelegate.h
│ │ │ ├── QNResponseInfo.h
│ │ │ ├── QNResponseInfo.m
│ │ │ ├── QNSessionManager.h
│ │ │ ├── QNSessionManager.m
│ │ │ ├── QNUserAgent.h
│ │ │ └── QNUserAgent.m
│ │ ├── QiniuSDK.h
│ │ ├── Recorder
│ │ │ ├── QNFileRecorder.h
│ │ │ ├── QNFileRecorder.m
│ │ │ └── QNRecorderDelegate.h
│ │ └── Storage
│ │ │ ├── QNConfiguration.h
│ │ │ ├── QNConfiguration.m
│ │ │ ├── QNFormUpload.h
│ │ │ ├── QNFormUpload.m
│ │ │ ├── QNResumeUpload.h
│ │ │ ├── QNResumeUpload.m
│ │ │ ├── QNUpToken.h
│ │ │ ├── QNUpToken.m
│ │ │ ├── QNUploadManager.h
│ │ │ ├── QNUploadManager.m
│ │ │ ├── QNUploadOption+Private.h
│ │ │ ├── QNUploadOption.h
│ │ │ └── QNUploadOption.m
│ └── UIKit+AFNetworking
│ │ ├── AFAutoPurgingImageCache.h
│ │ ├── AFAutoPurgingImageCache.m
│ │ ├── AFImageDownloader.h
│ │ ├── AFImageDownloader.m
│ │ ├── AFNetworkActivityIndicatorManager.h
│ │ ├── AFNetworkActivityIndicatorManager.m
│ │ ├── UIActivityIndicatorView+AFNetworking.h
│ │ ├── UIActivityIndicatorView+AFNetworking.m
│ │ ├── UIButton+AFNetworking.h
│ │ ├── UIButton+AFNetworking.m
│ │ ├── UIImage+AFNetworking.h
│ │ ├── UIImageView+AFNetworking.h
│ │ ├── UIImageView+AFNetworking.m
│ │ ├── UIKit+AFNetworking.h
│ │ ├── UIProgressView+AFNetworking.h
│ │ ├── UIProgressView+AFNetworking.m
│ │ ├── UIRefreshControl+AFNetworking.h
│ │ ├── UIRefreshControl+AFNetworking.m
│ │ ├── UIWebView+AFNetworking.h
│ │ └── UIWebView+AFNetworking.m
├── ImageHosting-Prefix.pch
├── ImageHosting.entitlements
├── Info.plist
├── Model
│ ├── IHAccount.h
│ ├── IHAccount.m
│ ├── IHCache.h
│ ├── IHCache.m
│ ├── IHGeneral.h
│ ├── IHGeneral.m
│ └── const.h
├── Util
│ ├── IHAccountManager.h
│ ├── IHAccountManager.m
│ ├── IHGeneralManager.h
│ ├── IHGeneralManager.m
│ ├── IHPreferencesManager.h
│ ├── IHPreferencesManager.m
│ ├── IHQiniuTokenManager.h
│ ├── IHQiniuTokenManager.m
│ ├── IHQiniuUploadManager.h
│ └── IHQiniuUploadManager.m
├── View
│ ├── IHProgressIndicator.h
│ ├── IHProgressIndicator.m
│ ├── IHTableView.h
│ ├── IHTableView.m
│ ├── IHUploadFileCell.h
│ ├── IHUploadFileCell.m
│ └── IHUploadFileCell.xib
└── main.m
├── ImageHostingHelper
├── AppDelegate.h
├── AppDelegate.m
├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── Base.lproj
│ └── Main.storyboard
├── ImageHostingHelper.entitlements
├── Info.plist
├── ViewController.h
├── ViewController.m
└── main.m
├── ImageHostingHelperTests
├── ImageHostingHelperTests.m
└── Info.plist
├── ImageHostingHelperUITests
├── ImageHostingHelperUITests.m
└── Info.plist
├── ImageHostingTests
├── ImageHostingTests.m
└── Info.plist
├── ImageHostingUITests
├── ImageHostingUITests.m
└── Info.plist
├── LICENSE
├── README.md
├── SRC
├── archive
│ └── Applications
└── image
│ ├── background.tif
│ ├── icon.png
│ ├── upload.png
│ ├── upload_1.png
│ ├── upload_2.png
│ └── upload_3.png
└── uncrustify.cfg
/.gitignore:
--------------------------------------------------------------------------------
1 | tignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
2 |
3 | ## Build generated
4 | build/
5 | DerivedData/
6 |
7 | ## Various settings
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | !default.perspectivev3
16 | xcuserdata/
17 |
18 | ## Other
19 | *.moved-aside
20 | *.xcuserstate
21 | *.DS_Store
22 |
23 | ## Obj-C/Swift specific
24 | *.hmap
25 | *.ipa
26 | *.dSYM.zip
27 | *.dSYM
28 |
29 | # CocoaPods
30 | #
31 | # We recommend against adding the Pods directory to your .gitignore. However
32 | # you should judge for yourself, the pros and cons are mentioned at:
33 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
34 | #
35 | # Pods/
36 |
37 | # Carthage
38 | #
39 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
40 | # Carthage/Checkouts
41 |
42 | Carthage/Build
43 |
44 | # fastlane
45 | #
46 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
47 | # screenshots whenever they are needed.
48 | # For more information about the recommended setup visit:
49 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
50 |
51 | fastlane/report.xml
52 | fastlane/screenshots
53 |
54 | #Code Injection
55 | #
56 | # After new code Injection tools there's a generated folder /iOSInjectionProject
57 | # https://github.com/johnno1962/injectionforxcode
58 |
59 | iOSInjectionProject/
60 |
61 |
--------------------------------------------------------------------------------
/ImageHosting.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ImageHosting/Addition/NSColor+IHAddition.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSColor+IHAddition.h
3 | // ImageHosting
4 | //
5 | // Created by chars on 16/9/2.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSColor (IHAddition)
12 |
13 | + (NSColor *)ih_colorWithRGBString:(NSString *)string;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/ImageHosting/Addition/NSColor+IHAddition.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSColor+IHAddition.m
3 | // ImageHosting
4 | //
5 | // Created by chars on 16/9/2.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import "NSColor+IHAddition.h"
10 |
11 | @implementation NSColor (IHAddition)
12 |
13 | + (NSColor *)ih_colorWithRGBString:(NSString *)string
14 | {
15 | return [[self class] ih_colorWithRGBString:string alpha:1.0f];
16 | }
17 |
18 | + (NSColor *)ih_colorWithRGBString:(NSString *)string alpha:(CGFloat)alpha
19 | {
20 | if (!string || [string length] < 6) {
21 | return nil;
22 | }
23 |
24 | const char *cStr = [string cStringUsingEncoding:NSASCIIStringEncoding];
25 | long hex;
26 | if ([string length] <= 6) {
27 | hex = strtol(cStr, NULL, 16);
28 | } else {
29 | hex = strtol(cStr + 1, NULL, 16);
30 | }
31 | return [self ih_colorWithRGBHex:(NSUInteger)hex alpha:alpha];
32 | }
33 |
34 | + (NSColor *)ih_colorWithRGBHex:(NSUInteger)hex
35 | {
36 | return [self ih_colorWithRGBHex:hex alpha:1.0f];
37 | }
38 |
39 | + (NSColor *)ih_colorWithRGBHex:(NSUInteger)hex alpha:(CGFloat)alpha
40 | {
41 | unsigned char red = (hex >> 16) & 0xFF;
42 | unsigned char green = (hex >> 8) & 0xFF;
43 | unsigned char blue = hex & 0xFF;
44 |
45 | return [NSColor colorWithRed:(CGFloat)red / 255.0f
46 | green:(CGFloat)green / 255.0f
47 | blue:(CGFloat)blue / 255.0f
48 | alpha:alpha];
49 | }
50 |
51 | @end
52 |
--------------------------------------------------------------------------------
/ImageHosting/Addition/NSString+IHAddition.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+IHAddition.h
3 | // ImageHosting
4 | //
5 | // Created by dengw on 16/8/20.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSString (IHAddition)
12 |
13 | /** 加密 */
14 | - (NSString *)ih_encode;
15 |
16 | /** 解密 */
17 | - (NSString *)ih_decode;
18 |
19 | /** 是否有效字符串 */
20 | - (BOOL)ih_isValid;
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/ImageHosting/Addition/NSString+IHAddition.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+IHAddition.m
3 | // ImageHosting
4 | //
5 | // Created by dengw on 16/8/20.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import "NSString+IHAddition.h"
10 | #import "QN_GTM_Base64.h"
11 |
12 | @implementation NSString (IHAddition)
13 |
14 | - (NSString *)ih_encode
15 | {
16 | NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];
17 | return [QN_GTM_Base64 stringByEncodingData:data];
18 | }
19 |
20 | - (NSString *)ih_decode
21 | {
22 | NSData *data = [QN_GTM_Base64 decodeString:self];
23 | return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
24 | }
25 |
26 | - (BOOL)ih_isValid
27 | {
28 | if (self.length > 0) {
29 | return YES;
30 | }
31 | return NO;
32 | }
33 |
34 | @end
35 |
--------------------------------------------------------------------------------
/ImageHosting/Addition/NSString+IHURL.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+IHURL.h
3 | // ImageHosting
4 | //
5 | // Created by chars on 16/9/2.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSString (IHURL)
12 |
13 | /**
14 | * URLEncode
15 | */
16 | - (NSString *)URLEncodedString;
17 |
18 | /**
19 | * URLDecode
20 | */
21 | -(NSString *)URLDecodedString;
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/ImageHosting/Addition/NSString+IHURL.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+IHURL.m
3 | // ImageHosting
4 | //
5 | // Created by chars on 16/9/2.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import "NSString+IHURL.h"
10 |
11 | @implementation NSString (IHURL)
12 |
13 | /**
14 | * URLEncode
15 | */
16 | - (NSString *)URLEncodedString
17 | {
18 | // CharactersToBeEscaped = @":/?&=;+!@#$()~',*";
19 | // CharactersToLeaveUnescaped = @"[].";
20 |
21 | NSString *unencodedString = self;
22 | NSString *encodedString = (NSString *)
23 | CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)unencodedString, NULL, (CFStringRef)@"!*'();:@&=+$,/?%#[]", kCFStringEncodingUTF8));
24 | return encodedString;
25 | }
26 |
27 | /**
28 | * URLDecode
29 | */
30 | - (NSString *)URLDecodedString
31 | {
32 | //NSString *decodedString = [encodedString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding ];
33 |
34 | NSString *encodedString = self;
35 | NSString *decodedString = (__bridge_transfer NSString *)CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL, (__bridge CFStringRef)encodedString, CFSTR(""), CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));
36 | return decodedString;
37 | }
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/ImageHosting/Application/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // ImageHosting
4 | //
5 | // Created by chars on 16/8/16.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : NSObject
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/ImageHosting/Application/IHCommon.h:
--------------------------------------------------------------------------------
1 | //
2 | // IHCommon.h
3 | // ImageHosting
4 | //
5 | // Created by chars on 16/9/7.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #ifndef IHCommon_h
10 | #define IHCommon_h
11 |
12 | //自定义日志输出
13 | #ifdef DEBUG
14 | //调试状态
15 | #define IHLog(...) NSLog(@"%s line:%d\n %@ \n\n", __func__, __LINE__, [NSString stringWithFormat:__VA_ARGS__])
16 | #else
17 | //发布状态
18 | #define IHLog(...)
19 | #endif
20 |
21 |
22 | #endif /* IHCommon_h */
23 |
--------------------------------------------------------------------------------
/ImageHosting/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "16x16",
5 | "idiom" : "mac",
6 | "filename" : "icon16.png",
7 | "scale" : "1x"
8 | },
9 | {
10 | "size" : "16x16",
11 | "idiom" : "mac",
12 | "filename" : "icon16@2x.png",
13 | "scale" : "2x"
14 | },
15 | {
16 | "size" : "32x32",
17 | "idiom" : "mac",
18 | "filename" : "icon32.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "32x32",
23 | "idiom" : "mac",
24 | "filename" : "icon32@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "128x128",
29 | "idiom" : "mac",
30 | "filename" : "icon128.png",
31 | "scale" : "1x"
32 | },
33 | {
34 | "size" : "128x128",
35 | "idiom" : "mac",
36 | "filename" : "icon128@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "256x256",
41 | "idiom" : "mac",
42 | "filename" : "icon256.png",
43 | "scale" : "1x"
44 | },
45 | {
46 | "size" : "256x256",
47 | "idiom" : "mac",
48 | "filename" : "icon256@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "512x512",
53 | "idiom" : "mac",
54 | "filename" : "icon512.png",
55 | "scale" : "1x"
56 | },
57 | {
58 | "size" : "512x512",
59 | "idiom" : "mac",
60 | "filename" : "icon512@2x.png",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
--------------------------------------------------------------------------------
/ImageHosting/Assets.xcassets/AppIcon.appiconset/icon128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charsdavy/ImageHosting/048e49b60b0f5212d8ae110d51cd83c387d982c4/ImageHosting/Assets.xcassets/AppIcon.appiconset/icon128.png
--------------------------------------------------------------------------------
/ImageHosting/Assets.xcassets/AppIcon.appiconset/icon128@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charsdavy/ImageHosting/048e49b60b0f5212d8ae110d51cd83c387d982c4/ImageHosting/Assets.xcassets/AppIcon.appiconset/icon128@2x.png
--------------------------------------------------------------------------------
/ImageHosting/Assets.xcassets/AppIcon.appiconset/icon16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charsdavy/ImageHosting/048e49b60b0f5212d8ae110d51cd83c387d982c4/ImageHosting/Assets.xcassets/AppIcon.appiconset/icon16.png
--------------------------------------------------------------------------------
/ImageHosting/Assets.xcassets/AppIcon.appiconset/icon16@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charsdavy/ImageHosting/048e49b60b0f5212d8ae110d51cd83c387d982c4/ImageHosting/Assets.xcassets/AppIcon.appiconset/icon16@2x.png
--------------------------------------------------------------------------------
/ImageHosting/Assets.xcassets/AppIcon.appiconset/icon256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charsdavy/ImageHosting/048e49b60b0f5212d8ae110d51cd83c387d982c4/ImageHosting/Assets.xcassets/AppIcon.appiconset/icon256.png
--------------------------------------------------------------------------------
/ImageHosting/Assets.xcassets/AppIcon.appiconset/icon256@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charsdavy/ImageHosting/048e49b60b0f5212d8ae110d51cd83c387d982c4/ImageHosting/Assets.xcassets/AppIcon.appiconset/icon256@2x.png
--------------------------------------------------------------------------------
/ImageHosting/Assets.xcassets/AppIcon.appiconset/icon32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charsdavy/ImageHosting/048e49b60b0f5212d8ae110d51cd83c387d982c4/ImageHosting/Assets.xcassets/AppIcon.appiconset/icon32.png
--------------------------------------------------------------------------------
/ImageHosting/Assets.xcassets/AppIcon.appiconset/icon32@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charsdavy/ImageHosting/048e49b60b0f5212d8ae110d51cd83c387d982c4/ImageHosting/Assets.xcassets/AppIcon.appiconset/icon32@2x.png
--------------------------------------------------------------------------------
/ImageHosting/Assets.xcassets/AppIcon.appiconset/icon512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charsdavy/ImageHosting/048e49b60b0f5212d8ae110d51cd83c387d982c4/ImageHosting/Assets.xcassets/AppIcon.appiconset/icon512.png
--------------------------------------------------------------------------------
/ImageHosting/Assets.xcassets/AppIcon.appiconset/icon512@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charsdavy/ImageHosting/048e49b60b0f5212d8ae110d51cd83c387d982c4/ImageHosting/Assets.xcassets/AppIcon.appiconset/icon512@2x.png
--------------------------------------------------------------------------------
/ImageHosting/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/ImageHosting/Assets.xcassets/about.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "icon128.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "icon128@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/ImageHosting/Assets.xcassets/about.imageset/icon128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charsdavy/ImageHosting/048e49b60b0f5212d8ae110d51cd83c387d982c4/ImageHosting/Assets.xcassets/about.imageset/icon128.png
--------------------------------------------------------------------------------
/ImageHosting/Assets.xcassets/about.imageset/icon128@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charsdavy/ImageHosting/048e49b60b0f5212d8ae110d51cd83c387d982c4/ImageHosting/Assets.xcassets/about.imageset/icon128@2x.png
--------------------------------------------------------------------------------
/ImageHosting/Assets.xcassets/fail.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "fail.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ImageHosting/Assets.xcassets/fail.imageset/fail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charsdavy/ImageHosting/048e49b60b0f5212d8ae110d51cd83c387d982c4/ImageHosting/Assets.xcassets/fail.imageset/fail.png
--------------------------------------------------------------------------------
/ImageHosting/Assets.xcassets/failure.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "Failure.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "Failure@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "Failure@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ImageHosting/Assets.xcassets/failure.imageset/Failure.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charsdavy/ImageHosting/048e49b60b0f5212d8ae110d51cd83c387d982c4/ImageHosting/Assets.xcassets/failure.imageset/Failure.png
--------------------------------------------------------------------------------
/ImageHosting/Assets.xcassets/failure.imageset/Failure@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charsdavy/ImageHosting/048e49b60b0f5212d8ae110d51cd83c387d982c4/ImageHosting/Assets.xcassets/failure.imageset/Failure@2x.png
--------------------------------------------------------------------------------
/ImageHosting/Assets.xcassets/failure.imageset/Failure@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charsdavy/ImageHosting/048e49b60b0f5212d8ae110d51cd83c387d982c4/ImageHosting/Assets.xcassets/failure.imageset/Failure@3x.png
--------------------------------------------------------------------------------
/ImageHosting/Assets.xcassets/line.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "line.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ImageHosting/Assets.xcassets/line.imageset/line.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charsdavy/ImageHosting/048e49b60b0f5212d8ae110d51cd83c387d982c4/ImageHosting/Assets.xcassets/line.imageset/line.png
--------------------------------------------------------------------------------
/ImageHosting/Assets.xcassets/logo.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "logo.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "logo@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "logo@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ImageHosting/Assets.xcassets/logo.imageset/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charsdavy/ImageHosting/048e49b60b0f5212d8ae110d51cd83c387d982c4/ImageHosting/Assets.xcassets/logo.imageset/logo.png
--------------------------------------------------------------------------------
/ImageHosting/Assets.xcassets/logo.imageset/logo@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charsdavy/ImageHosting/048e49b60b0f5212d8ae110d51cd83c387d982c4/ImageHosting/Assets.xcassets/logo.imageset/logo@2x.png
--------------------------------------------------------------------------------
/ImageHosting/Assets.xcassets/logo.imageset/logo@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charsdavy/ImageHosting/048e49b60b0f5212d8ae110d51cd83c387d982c4/ImageHosting/Assets.xcassets/logo.imageset/logo@3x.png
--------------------------------------------------------------------------------
/ImageHosting/Assets.xcassets/success.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "success.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/ImageHosting/Assets.xcassets/success.imageset/success.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charsdavy/ImageHosting/048e49b60b0f5212d8ae110d51cd83c387d982c4/ImageHosting/Assets.xcassets/success.imageset/success.png
--------------------------------------------------------------------------------
/ImageHosting/Assets.xcassets/successful.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "success.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "success@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "success@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/ImageHosting/Assets.xcassets/successful.imageset/success.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charsdavy/ImageHosting/048e49b60b0f5212d8ae110d51cd83c387d982c4/ImageHosting/Assets.xcassets/successful.imageset/success.png
--------------------------------------------------------------------------------
/ImageHosting/Assets.xcassets/successful.imageset/success@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charsdavy/ImageHosting/048e49b60b0f5212d8ae110d51cd83c387d982c4/ImageHosting/Assets.xcassets/successful.imageset/success@2x.png
--------------------------------------------------------------------------------
/ImageHosting/Assets.xcassets/successful.imageset/success@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charsdavy/ImageHosting/048e49b60b0f5212d8ae110d51cd83c387d982c4/ImageHosting/Assets.xcassets/successful.imageset/success@3x.png
--------------------------------------------------------------------------------
/ImageHosting/Controller/View/IHPreferencesAccountsViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // IHPreferencesAccountsViewController.h
3 | // ImageHosting
4 | //
5 | // Created by chars on 16/8/19.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import "IHViewController.h"
10 |
11 | @interface IHPreferencesAccountsViewController : IHViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/ImageHosting/Controller/View/IHPreferencesAccountsViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // IHPreferencesAccountsViewController.m
3 | // ImageHosting
4 | //
5 | // Created by chars on 16/8/19.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import "IHPreferencesAccountsViewController.h"
10 | #import "IHAccountManager.h"
11 | #import "IHAccount.h"
12 | #import "const.h"
13 |
14 | @interface IHPreferencesAccountsViewController ()
15 |
16 | @property (weak) IBOutlet NSTextField *akTextField;
17 | @property (weak) IBOutlet NSSecureTextField *skTextField;
18 | @property (weak) IBOutlet NSTextField *bucketNameTextField;
19 | @property (weak) IBOutlet NSButton *east;
20 | @property (weak) IBOutlet NSButton *north;
21 | @property (copy) NSString *region;
22 |
23 | @end
24 |
25 | @implementation IHPreferencesAccountsViewController
26 |
27 | - (void)viewDidLoad
28 | {
29 | [super viewDidLoad];
30 | // Do view setup here.
31 | _region = REGION_EAST_CHINA;
32 | [self fillCurrentAccount];
33 | }
34 |
35 | - (void)fillCurrentAccount
36 | {
37 | IHAccount *currentAccount = [[IHAccountManager sharedManager] currentAccount];
38 | if (currentAccount) {
39 | _akTextField.stringValue = currentAccount.ak;
40 | _skTextField.stringValue = currentAccount.sk;
41 | _bucketNameTextField.stringValue = currentAccount.bucketName;
42 | if ([currentAccount.region isEqualToString:REGION_EAST_CHINA]) {
43 | _east.state = 1;
44 | _north.state = 0;
45 | } else if ([currentAccount.region isEqualToString:REGION_NORTH_CHINA]) {
46 | _east.state = 0;
47 | _north.state = 1;
48 | }
49 | } else {
50 | _east.state = 1;
51 | _north.state = 0;
52 | }
53 | }
54 |
55 | - (IBAction)clickedSubmit:(id)sender
56 | {
57 | IHAccount *account = [[IHAccount alloc] init];
58 | account.accountType = IHAccountTypeQiniu;
59 | account.ak = _akTextField.stringValue;
60 | account.sk = _skTextField.stringValue;
61 | account.bucketName = _bucketNameTextField.stringValue;
62 | account.region = self.region;
63 |
64 | BOOL success = [[IHAccountManager sharedManager] archive:account key:ACCOUNTS_KEY];
65 | if (success) {
66 | NSString *title = @"Configure Success";
67 | NSString *msg = @"Config Account Info Success ! Please continue another operation ";
68 | [self showAlertTitle:title message:msg style:IHAlertStyleInformational];
69 | } else {
70 | NSString *title = @"Configure Failed";
71 | NSString *msg = @"Config Account Info Failed ! Please again ";
72 | [self showAlertTitle:title message:msg style:IHAlertStyleWarning];
73 | [self clearAccountViewContent];
74 | }
75 | }
76 |
77 | - (IBAction)clickedRegion:(NSButton *)sender {
78 | if (sender.tag == 1) {
79 | self.region = REGION_EAST_CHINA;
80 | } else if (sender.tag == 0) {
81 | self.region = REGION_NORTH_CHINA;
82 | }
83 | }
84 |
85 | - (void)showAlertTitle:(NSString *)title message:(NSString *)message style:(IHAlertStyle)style
86 | {
87 | NSAlertStyle alertStyle = NSInformationalAlertStyle;
88 | if (style == IHAlertStyleWarning) {
89 | alertStyle = NSWarningAlertStyle;
90 | } else if (style == IHAlertStyleCritical) {
91 | alertStyle = NSCriticalAlertStyle;
92 | } else if (style == IHAlertStyleInformational) {
93 | alertStyle = NSInformationalAlertStyle;
94 | } else {
95 | alertStyle = NSInformationalAlertStyle;
96 | }
97 |
98 | NSAlert *alert = [NSAlert alertWithMessageText:title defaultButton:@"Okay" alternateButton:nil otherButton:nil informativeTextWithFormat:@"%@", message];
99 | alert.alertStyle = alertStyle;
100 | [alert beginSheetModalForWindow:self.preferencesWindow completionHandler:nil];
101 | }
102 |
103 | - (void)clearAccountViewContent
104 | {
105 | _akTextField.stringValue = @"";
106 | _skTextField.stringValue = @"";
107 | _bucketNameTextField.stringValue = @"";
108 | _east.state = 1;
109 | _north.state = 0;
110 | }
111 |
112 | @end
113 |
--------------------------------------------------------------------------------
/ImageHosting/Controller/View/IHPreferencesFeedbackViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // IHPreferencesFeedbackViewController.h
3 | // ImageHosting
4 | //
5 | // Created by chars on 16/8/22.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import "IHViewController.h"
10 |
11 | @interface IHPreferencesFeedbackViewController : IHViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/ImageHosting/Controller/View/IHPreferencesFeedbackViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // IHPreferencesFeedbackViewController.m
3 | // ImageHosting
4 | //
5 | // Created by chars on 16/8/22.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import "IHPreferencesFeedbackViewController.h"
10 | #import "BRLinkLabel.h"
11 |
12 | #define FONT_FEED_BACK 14.0f
13 |
14 | @interface IHPreferencesFeedbackViewController ()
15 |
16 | @end
17 |
18 | @implementation IHPreferencesFeedbackViewController
19 |
20 | - (void)viewDidLoad
21 | {
22 | [super viewDidLoad];
23 | // Do view setup here.
24 |
25 | [self emailLabel];
26 | [self githubLabel];
27 | [self weiboLabel];
28 | [self tiwtterLabel];
29 | }
30 |
31 | - (void)emailLabel
32 | {
33 | NSString *title = @"chars.davy@gmail.com";
34 | CGSize size = [title sizeWithAttributes:@{ NSFontAttributeName: [NSFont systemFontOfSize:FONT_FEED_BACK] }];
35 | NSRect frame = NSMakeRect(144, 220, size.width, 20);
36 | NSString *email = @"mailto:chars.davy@gmail.com";;
37 | email = [email stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
38 | BRLinkLabel *linkLabel = [self linkLabel:title link:email frame:frame];
39 | linkLabel.accessibilitySelected = YES;
40 | [self.view addSubview:linkLabel];
41 | }
42 |
43 | - (void)githubLabel
44 | {
45 | NSString *title = @"@charsdavy";
46 | CGSize size = [title sizeWithAttributes:@{ NSFontAttributeName: [NSFont systemFontOfSize:FONT_FEED_BACK] }];
47 | NSRect frame = NSMakeRect(144, 167, size.width, 20);
48 | NSString *link = @"https://github.com/charsdavy";
49 | BRLinkLabel *linkLabel = [self linkLabel:title link:link frame:frame];
50 | [self.view addSubview:linkLabel];
51 | }
52 |
53 | - (void)weiboLabel
54 | {
55 | NSString *title = @"@Chars-D";
56 | CGSize size = [title sizeWithAttributes:@{ NSFontAttributeName: [NSFont systemFontOfSize:FONT_FEED_BACK] }];
57 | NSRect frame = NSMakeRect(144, 115, size.width, 20);
58 | NSString *link = @"http://weibo.com/u/3875245858";
59 | BRLinkLabel *linkLabel = [self linkLabel:title link:link frame:frame];
60 | [self.view addSubview:linkLabel];
61 | }
62 |
63 | - (void)tiwtterLabel
64 | {
65 | NSString *title = @"@charsdavy";
66 | CGSize size = [title sizeWithAttributes:@{ NSFontAttributeName: [NSFont systemFontOfSize:FONT_FEED_BACK] }];
67 | NSRect frame = NSMakeRect(144, 65, size.width, 20);
68 | NSString *link = @"https://twitter.com/charsdavy";
69 | BRLinkLabel *linkLabel = [self linkLabel:title link:link frame:frame];
70 | [self.view addSubview:linkLabel];
71 | }
72 |
73 | - (BRLinkLabel *)linkLabel:(NSString *)title link:(NSString *)link frame:(CGRect)frame
74 | {
75 | NSAttributedString *attString = [[NSAttributedString alloc] initWithString:title attributes:@{ NSLinkAttributeName:link, NSForegroundColorAttributeName: [NSColor colorWithRed:16 / 255.0 green:64 / 255.0 blue:251 / 255.0 alpha:1.0f] }];
76 | BRLinkLabel *linkLabel = [[BRLinkLabel alloc] initWithFrame:frame attibutedString:attString];
77 | linkLabel.showBackground = NO;
78 | return linkLabel;
79 | }
80 |
81 | @end
82 |
--------------------------------------------------------------------------------
/ImageHosting/Controller/View/IHPreferencesFeedbackViewController.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/ImageHosting/Controller/View/IHPreferencesGeneralViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // IHPreferencesGeneralViewController.h
3 | // ImageHosting
4 | //
5 | // Created by chars on 16/8/19.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import "IHViewController.h"
10 |
11 | @interface IHPreferencesGeneralViewController : IHViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/ImageHosting/Controller/View/IHPreferencesGeneralViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // IHPreferencesGeneralViewController.m
3 | // ImageHosting
4 | //
5 | // Created by chars on 16/8/19.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import "IHPreferencesGeneralViewController.h"
10 | #import "IHGeneralManager.h"
11 | #import "IHGeneral.h"
12 | #import "const.h"
13 |
14 | @interface IHPreferencesGeneralViewController ()
15 |
16 | @property (weak) IBOutlet NSButton *launch;
17 | @property (weak) IBOutlet NSButton *systemNotification;
18 |
19 | @end
20 |
21 | @implementation IHPreferencesGeneralViewController
22 |
23 | - (void)viewDidLoad {
24 | [super viewDidLoad];
25 | // Do view setup here.
26 |
27 | [self initSubViews];
28 | }
29 |
30 | - (void)initSubViews
31 | {
32 | IHGeneral *general = [[IHGeneral alloc] init];
33 | general = [[IHGeneralManager sharedManager] unarchiveForKey:SYSTEM_NOTIFICATION_KEY];
34 |
35 | if ([general.launchStartUp isEqualToString:@"YES"]) {
36 | _launch.state = 1;
37 | [[IHGeneralManager sharedManager] startupAppWhenLogin:YES];
38 | } else {
39 | _launch.state = 0;
40 | [[IHGeneralManager sharedManager] startupAppWhenLogin:NO];
41 | }
42 |
43 | if ([general.userNotification isEqualToString:@"YES"]) {
44 | _systemNotification.state = 1;
45 | } else {
46 | _systemNotification.state = 0;
47 | }
48 | }
49 |
50 | - (IBAction)launchStartUp:(NSButton *)sender {
51 | IHLog(@"state:%zi", sender.state);
52 | NSString *launch = sender.state ? @"YES" : @"NO";
53 |
54 | if (sender.state) {
55 | [[IHGeneralManager sharedManager] startupAppWhenLogin:YES];
56 | } else {
57 | [[IHGeneralManager sharedManager] startupAppWhenLogin:NO];
58 | }
59 |
60 | IHGeneral *general = [[IHGeneral alloc] init];
61 | general = [[IHGeneralManager sharedManager] unarchiveForKey:SYSTEM_NOTIFICATION_KEY];
62 | general.launchStartUp = launch;
63 |
64 | [[IHGeneralManager sharedManager] archive:general key:SYSTEM_NOTIFICATION_KEY];
65 | }
66 |
67 | - (IBAction)systemNotification:(NSButton *)sender {
68 | IHLog(@"state:%zi", sender.state);
69 | NSString *noti = sender.state ? @"YES" : @"NO";
70 | IHGeneral *general = [[IHGeneral alloc] init];
71 | general = [[IHGeneralManager sharedManager] unarchiveForKey:SYSTEM_NOTIFICATION_KEY];
72 | general.userNotification = noti;
73 |
74 | [[IHGeneralManager sharedManager] archive:general key:SYSTEM_NOTIFICATION_KEY];
75 | }
76 |
77 | @end
78 |
--------------------------------------------------------------------------------
/ImageHosting/Controller/View/IHViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // IHViewController.h
3 | // ImageHosting
4 | //
5 | // Created by chars on 16/8/19.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface IHViewController : NSViewController
12 |
13 | @property (nullable, strong) NSWindow *preferencesWindow;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/ImageHosting/Controller/View/IHViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // IHViewController.m
3 | // ImageHosting
4 | //
5 | // Created by chars on 16/8/19.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import "IHViewController.h"
10 |
11 | @interface IHViewController ()
12 |
13 | @end
14 |
15 | @implementation IHViewController
16 |
17 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
18 | {
19 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
20 | if (self) {
21 | // Initialization code here.
22 | }
23 |
24 | return self;
25 | }
26 |
27 | - (void)viewDidLoad {
28 | [super viewDidLoad];
29 | // Do view setup here.
30 | }
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/ImageHosting/Controller/Window/IHAboutWindowController.h:
--------------------------------------------------------------------------------
1 | //
2 | // IHAboutWindowController.h
3 | // ImageHosting
4 | //
5 | // Created by dengw on 16/8/28.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import "IHWindowController.h"
10 |
11 | @interface IHAboutWindowController : IHWindowController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/ImageHosting/Controller/Window/IHAboutWindowController.m:
--------------------------------------------------------------------------------
1 | //
2 | // IHAboutWindowController.m
3 | // ImageHosting
4 | //
5 | // Created by dengw on 16/8/28.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import "IHAboutWindowController.h"
10 |
11 | #define VERSION @"1.1.3"
12 | #define BUILD @"10"
13 |
14 | @interface IHAboutWindowController ()
15 |
16 | @property (weak) IBOutlet NSTextField *versionTextField;
17 | @property (weak) IBOutlet NSTextField *copyrightTextField;
18 |
19 | @end
20 |
21 | @implementation IHAboutWindowController
22 |
23 | - (instancetype)init
24 | {
25 | self = [super initWithWindowNibName:@"IHAboutWindowController"];
26 | if (self) {
27 | }
28 | return self;
29 | }
30 |
31 | - (void)windowDidLoad
32 | {
33 | [super windowDidLoad];
34 |
35 | // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
36 |
37 | self.versionTextField.stringValue = [self version];
38 | }
39 |
40 | - (NSString *)version
41 | {
42 | NSString *version = [NSString stringWithFormat:@"Version %@ (%@)", VERSION, BUILD];
43 | return version;
44 | }
45 |
46 | #pragma mark - Showing the Preferences Window
47 |
48 | - (void)showWithCompletionHandler:(IHWindowControllerCompletionHandler)handler
49 | {
50 | self.completionHandler = handler;
51 | [self showWindow:self];
52 | }
53 |
54 | @end
55 |
--------------------------------------------------------------------------------
/ImageHosting/Controller/Window/IHPreferencesWindowController.h:
--------------------------------------------------------------------------------
1 | //
2 | // IHPreferencesWindowController.h
3 | // ImageHosting
4 | //
5 | // Created by chars on 16/8/19.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import "IHWindowController.h"
10 |
11 | @interface IHPreferencesWindowController : IHWindowController
12 |
13 | - (IBAction)showPreferencesFor:(id)sender;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/ImageHosting/Controller/Window/IHPreferencesWindowController.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/ImageHosting/Controller/Window/IHUploadWindowController.h:
--------------------------------------------------------------------------------
1 | //
2 | // IHUploadWindowController.h
3 | // ImageHosting
4 | //
5 | // Created by chars on 16/8/19.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import "IHWindowController.h"
10 |
11 | @interface IHUploadWindowController : IHWindowController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/ImageHosting/Controller/Window/IHWindowController.h:
--------------------------------------------------------------------------------
1 | //
2 | // IHWindowController.h
3 | // ImageHosting
4 | //
5 | // Created by chars on 16/8/16.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | typedef void(^IHWindowControllerCompletionHandler)(void);
12 |
13 | @interface IHWindowController : NSWindowController
14 |
15 | @property (nonatomic, copy) IHWindowControllerCompletionHandler completionHandler;
16 |
17 | - (void)showWithCompletionHandler:(IHWindowControllerCompletionHandler)handler;
18 |
19 | @end
20 |
21 |
--------------------------------------------------------------------------------
/ImageHosting/Controller/Window/IHWindowController.m:
--------------------------------------------------------------------------------
1 | //
2 | // IHWindowController.m
3 | // ImageHosting
4 | //
5 | // Created by chars on 16/8/16.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import "IHWindowController.h"
10 |
11 | @interface IHWindowController ()
12 |
13 | @end
14 |
15 | @implementation IHWindowController
16 |
17 | - (void)showWithCompletionHandler:(IHWindowControllerCompletionHandler)handler {
18 | }
19 |
20 | - (void)windowWillClose:(NSNotification *)notification {
21 | self.completionHandler ? self.completionHandler() : nil;
22 | }
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/ImageHosting/External/AFNetworking/AFNetworking.h:
--------------------------------------------------------------------------------
1 | // AFNetworking.h
2 | //
3 | // Copyright (c) 2013 AFNetworking (http://afnetworking.com/)
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #import
24 | #import
25 | #import
26 |
27 | #ifndef _AFNETWORKING_
28 | #define _AFNETWORKING_
29 |
30 | #import "AFURLRequestSerialization.h"
31 | #import "AFURLResponseSerialization.h"
32 | #import "AFSecurityPolicy.h"
33 |
34 | #if !TARGET_OS_WATCH
35 | #import "AFNetworkReachabilityManager.h"
36 | #endif
37 |
38 | #import "AFURLSessionManager.h"
39 | #import "AFHTTPSessionManager.h"
40 |
41 | #endif /* _AFNETWORKING_ */
42 |
--------------------------------------------------------------------------------
/ImageHosting/External/BRLinkLabel/BRLinkLabel.h:
--------------------------------------------------------------------------------
1 | //
2 | // BRLinkLabel.h
3 | // BRLinkLabel
4 | //
5 | // Created by Yang on 16/2/29.
6 | // Copyright © 2016年 sgyang. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | IB_DESIGNABLE
12 |
13 | @interface BRLinkLabel : NSView
14 |
15 | @property (nonatomic, copy) NSAttributedString *displayString;
16 |
17 | //方便直接设置attibute
18 | @property (nonatomic, copy) IBInspectable NSString *textString;
19 | @property (nonatomic, copy) IBInspectable NSString *linkString;
20 | @property (nonatomic, retain) IBInspectable NSColor *textColor;
21 |
22 | //背景相关
23 | @property (nonatomic) BOOL IBInspectable showBackground;
24 | @property (nonatomic, retain) IBInspectable NSColor *backgroundColor;
25 |
26 | - (instancetype)initWithFrame:(NSRect)frameRect attibutedString:(NSAttributedString *)displayString;
27 | //也可以用- (instancetype)initWithFrame:(NSRect)frameRect来创建
28 |
29 | @end
--------------------------------------------------------------------------------
/ImageHosting/External/HappyDNS/Common/QNDnsManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNDnsManager.h
3 | // HappyDNS
4 | //
5 | // Created by bailong on 15/6/23.
6 | // Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class QNNetworkInfo;
12 | @class QNDomain;
13 |
14 | /**
15 | * 上传进度回调函数
16 | *
17 | * @param key 上传时指定的存储key
18 | * @param percent 进度百分比
19 | */
20 | typedef NSArray * (^QNGetAddrInfoCallback)(NSString *host);
21 |
22 | @protocol QNIpSorter
23 | - (NSArray *)sort:(NSArray *)ips;
24 | @end
25 |
26 | @interface QNDnsManager : NSObject
27 | - (NSArray *)query:(NSString *)domain;
28 | - (NSArray *)queryWithDomain:(QNDomain *)domain;
29 | - (void)onNetworkChange:(QNNetworkInfo *)netInfo;
30 | - (instancetype)init:(NSArray *)resolvers networkInfo:(QNNetworkInfo *)netInfo;
31 | - (instancetype)init:(NSArray *)resolvers networkInfo:(QNNetworkInfo *)netInfo sorter:(id)sorter;
32 | - (instancetype)putHosts:(NSString *)domain ip:(NSString *)ip;
33 | - (instancetype)putHosts:(NSString *)domain ip:(NSString *)ip provider:(int)provider;
34 | + (void)setGetAddrInfoBlock:(QNGetAddrInfoCallback)block;
35 | @end
36 |
37 | @interface QNDnsManager (NSURL)
38 | - (NSURL *)queryAndReplaceWithIP:(NSURL *)url;
39 | @end
--------------------------------------------------------------------------------
/ImageHosting/External/HappyDNS/Common/QNDomain.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNDomain.h
3 | // HappyDNS
4 | //
5 | // Created by bailong on 15/6/23.
6 | // Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface QNDomain : NSObject
12 | @property (nonatomic, strong, readonly) NSString *domain;
13 |
14 | // 用来判断劫持
15 | @property (nonatomic, readonly) BOOL hasCname;
16 | // 用来判断劫持
17 | @property (nonatomic, readonly) int maxTtl;
18 |
19 | @property (nonatomic, readonly) BOOL hostsFirst;
20 |
21 | - (instancetype)init:(NSString *)domain;
22 |
23 | - (instancetype)init:(NSString *)domain hostsFirst:(BOOL)hostsFirst hasCname:(BOOL)hasCname;
24 |
25 | - (instancetype)init:(NSString *)domain hostsFirst:(BOOL)hostsFirst hasCname:(BOOL)hasCname maxTtl:(int)maxTtl;
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/ImageHosting/External/HappyDNS/Common/QNDomain.m:
--------------------------------------------------------------------------------
1 | //
2 | // QNDomain.m
3 | // HappyDNS
4 | //
5 | // Created by bailong on 15/6/23.
6 | // Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
7 | //
8 |
9 | #import "QNDomain.h"
10 |
11 | @implementation QNDomain
12 | - (instancetype)init:(NSString *)domain {
13 | return [self init:domain hostsFirst:NO hasCname:NO maxTtl:0];
14 | }
15 |
16 | - (instancetype)init:(NSString *)domain hostsFirst:(BOOL)hostsFirst hasCname:(BOOL)hasCname {
17 | return [self init:domain hostsFirst:hostsFirst hasCname:hasCname maxTtl:0];
18 | }
19 |
20 | - (instancetype)init:(NSString *)domain hostsFirst:(BOOL)hostsFirst hasCname:(BOOL)hasCname maxTtl:(int)maxTtl {
21 | if (self = [super init]) {
22 | _domain = domain;
23 | _hasCname = hasCname;
24 | _maxTtl = maxTtl;
25 | _hostsFirst = hostsFirst;
26 | }
27 | return self;
28 | }
29 |
30 | @end
31 |
--------------------------------------------------------------------------------
/ImageHosting/External/HappyDNS/Common/QNLruCache.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNLruCache.h
3 | // HappyDNS
4 | //
5 | // Created by bailong on 16/7/5.
6 | // Copyright © 2016年 Qiniu Cloud Storage. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface QNLruCache : NSObject
12 |
13 | - (instancetype)init:(NSUInteger)limit;
14 |
15 | - (void)removeAllObjects;
16 |
17 | - (void)removeObjectForKey:(NSString *)key;
18 |
19 | - (id)objectForKey:(NSString *)key;
20 |
21 | - (void)setObject:(id)obj forKey:(NSString *)key;
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/ImageHosting/External/HappyDNS/Common/QNLruCache.m:
--------------------------------------------------------------------------------
1 | //
2 | // QNLruCache.m
3 | // HappyDNS
4 | //
5 | // Created by bailong on 16/7/5.
6 | // Copyright © 2016年 Qiniu Cloud Storage. All rights reserved.
7 | //
8 |
9 | #import "QNLruCache.h"
10 |
11 | @interface QNLruCache ()
12 |
13 | @property (nonatomic, readonly) NSUInteger limit;
14 |
15 | @property (nonatomic, readonly) NSMutableDictionary* cache;
16 |
17 | @property (nonatomic, readonly) NSMutableArray* list;
18 |
19 | @end
20 |
21 | @interface _QNElement : NSObject
22 | @property (nonatomic, readonly, strong) NSString* key;
23 | @property (nonatomic, strong) id obj;
24 | - (instancetype)initObject:(id)obj forKey:(NSString*)key;
25 | @end
26 |
27 | @implementation _QNElement
28 |
29 | - (instancetype)initObject:(id)obj forKey:(NSString*)key {
30 | if (self = [super init]) {
31 | _key = key;
32 | _obj = obj;
33 | }
34 | return self;
35 | }
36 |
37 | @end
38 |
39 | @implementation QNLruCache
40 |
41 | - (instancetype)init:(NSUInteger)limit {
42 | if (self = [super init]) {
43 | _limit = limit;
44 | _cache = [NSMutableDictionary new];
45 | _list = [NSMutableArray new];
46 | }
47 | return self;
48 | }
49 |
50 | - (void)removeAllObjects {
51 | [_cache removeAllObjects];
52 | [_list removeAllObjects];
53 | }
54 |
55 | - (void)removeObjectForKey:(NSString*)key {
56 | _QNElement* obj = [_cache objectForKey:key];
57 | if (obj == nil) {
58 | return;
59 | }
60 | [_cache removeObjectForKey:key];
61 | [_list removeObjectIdenticalTo:obj];
62 | }
63 |
64 | - (id)objectForKey:(NSString*)key {
65 | _QNElement* obj = [_cache objectForKey:key];
66 | if (obj != nil) {
67 | [_list removeObjectIdenticalTo:obj];
68 | [_list insertObject:obj atIndex:0];
69 | }
70 | return obj.obj;
71 | }
72 |
73 | - (void)setObject:(id)obj forKey:(NSString*)key {
74 | _QNElement* old = [_cache objectForKey:key];
75 | if (old) {
76 | old.obj = obj;
77 | [_list removeObjectIdenticalTo:old];
78 | [_list insertObject:old atIndex:0];
79 | return;
80 | } else if (_list.count == _limit) {
81 | old = [_list lastObject];
82 | [_list removeLastObject];
83 | [_cache removeObjectForKey:old.key];
84 | }
85 | _QNElement* newElement = [[_QNElement alloc] initObject:obj forKey:key];
86 | [_cache setObject:newElement forKey:key];
87 | [_list insertObject:newElement atIndex:0];
88 | }
89 |
90 | @end
91 |
--------------------------------------------------------------------------------
/ImageHosting/External/HappyDNS/Common/QNNetworkInfo.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNNetworkInfo.h
3 | // HappyDNS
4 | //
5 | // Created by bailong on 15/6/25.
6 | // Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | extern const int kQNNO_NETWORK;
12 | extern const int kQNWIFI;
13 | extern const int kQNMOBILE;
14 |
15 | extern const int kQNISP_GENERAL;
16 | extern const int kQNISP_CTC;
17 | extern const int kQNISP_DIANXIN;
18 | extern const int kQNISP_CNC;
19 | extern const int kQNISP_LIANTONG;
20 | extern const int kQNISP_CMCC;
21 | extern const int kQNISP_YIDONG;
22 | extern const int kQNISP_OTHER;
23 |
24 | @interface QNNetworkInfo : NSObject
25 |
26 | @property (nonatomic, readonly) int networkConnection;
27 | @property (nonatomic, readonly) int provider;
28 |
29 | - (instancetype)init:(int)connecton provider:(int)provider;
30 |
31 | - (BOOL)isEqual:(id)other;
32 | - (BOOL)isEqualToInfo:(QNNetworkInfo *)info;
33 |
34 | + (instancetype)noNet;
35 |
36 | + (instancetype)normal;
37 |
38 | + (BOOL)isNetworkChanged;
39 |
40 | + (NSString *)getIp;
41 |
42 | @end
43 |
--------------------------------------------------------------------------------
/ImageHosting/External/HappyDNS/Common/QNNetworkInfo.m:
--------------------------------------------------------------------------------
1 | //
2 | // QNNetworkInfo.m
3 | // HappyDNS
4 | //
5 | // Created by bailong on 15/6/25.
6 | // Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
7 | //
8 |
9 | #import
10 | #include
11 | #include
12 | #include
13 | #include
14 |
15 | #import "QNIP.h"
16 | #import "QNNetworkInfo.h"
17 |
18 | const int kQNNO_NETWORK = -1;
19 | const int kQNWIFI = 1;
20 | const int kQNMOBILE = 2;
21 |
22 | const int kQNISP_GENERAL = 0;
23 | const int kQNISP_CTC = 1;
24 | const int kQNISP_DIANXIN = kQNISP_CTC;
25 | const int kQNISP_CNC = 2;
26 | const int kQNISP_LIANTONG = kQNISP_CNC;
27 | const int kQNISP_CMCC = 3;
28 | const int kQNISP_YIDONG = kQNISP_CMCC;
29 | const int kQNISP_OTHER = 999;
30 |
31 | #define IPLength 64
32 |
33 | static char previousIp[IPLength] = {0};
34 | static NSString *lock = @"";
35 |
36 | @implementation QNNetworkInfo
37 |
38 | - (instancetype)init:(int)connecton provider:(int)provider {
39 | if (self = [super init]) {
40 | _networkConnection = connecton;
41 | _provider = provider;
42 | }
43 | return self;
44 | }
45 |
46 | + (instancetype)noNet {
47 | return [[QNNetworkInfo alloc] init:kQNNO_NETWORK provider:kQNISP_GENERAL];
48 | }
49 |
50 | + (instancetype)normal {
51 | return [[QNNetworkInfo alloc] init:kQNISP_GENERAL provider:kQNISP_GENERAL];
52 | }
53 |
54 | - (BOOL)isEqualToInfo:(QNNetworkInfo *)info {
55 | if (self == info)
56 | return YES;
57 | return self.provider == info.provider && self.networkConnection == info.networkConnection;
58 | }
59 |
60 | - (BOOL)isEqual:(id)other {
61 | if (other == self)
62 | return YES;
63 | if (!other || ![other isKindOfClass:[self class]])
64 | return NO;
65 | return [self isEqualToInfo:other];
66 | }
67 |
68 | + (BOOL)isNetworkChanged {
69 | @synchronized(lock) {
70 | char local[IPLength] = {0};
71 | int err = qn_localIp(local, sizeof(local));
72 | if (err != 0) {
73 | return YES;
74 | }
75 | if (memcmp(previousIp, local, sizeof(local)) != 0) {
76 | memcpy(previousIp, local, sizeof(local));
77 | return YES;
78 | }
79 | return NO;
80 | }
81 | }
82 |
83 | + (NSString *)getIp {
84 | return [QNIP local];
85 | }
86 | @end
87 |
--------------------------------------------------------------------------------
/ImageHosting/External/HappyDNS/Common/QNRecord.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNRecord.h
3 | // HappyDNS
4 | //
5 | // Created by bailong on 15/6/23.
6 | // Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | /**
12 | * A 记录
13 | */
14 | extern const int kQNTypeA;
15 |
16 | /**
17 | * AAAA 记录
18 | */
19 | extern const int kQNTypeAAAA;
20 |
21 | /**
22 | * Cname 记录
23 | */
24 | extern const int kQNTypeCname;
25 |
26 | /**
27 | * Txt 记录
28 | */
29 | extern const int kQNTypeTXT;
30 |
31 | @interface QNRecord : NSObject
32 | @property (nonatomic, strong, readonly) NSString *value;
33 | @property (nonatomic, readonly) int ttl;
34 | @property (nonatomic, readonly) int type;
35 | @property (nonatomic, readonly) long long timeStamp;
36 |
37 | - (instancetype)init:(NSString *)value
38 | ttl:(int)ttl
39 | type:(int)type;
40 |
41 | - (BOOL)expired:(long long)time;
42 | @end
43 |
--------------------------------------------------------------------------------
/ImageHosting/External/HappyDNS/Common/QNRecord.m:
--------------------------------------------------------------------------------
1 | //
2 | // QNRecord.m
3 | // HappyDNS
4 | //
5 | // Created by bailong on 15/6/23.
6 | // Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
7 | //
8 |
9 | #import "QNRecord.h"
10 |
11 | const int kQNTypeA = 1;
12 | const int kQNTypeAAAA = 28;
13 | const int kQNTypeCname = 5;
14 | const int kQNTypeTXT = 16;
15 |
16 | @implementation QNRecord
17 | - (instancetype)init:(NSString *)value
18 | ttl:(int)ttl
19 | type:(int)type {
20 | if (self = [super init]) {
21 | _value = value;
22 | _type = type;
23 | _ttl = ttl;
24 | _timeStamp = [[NSDate date] timeIntervalSince1970];
25 | }
26 | return self;
27 | }
28 |
29 | - (BOOL)expired:(long long)time {
30 | return time > _timeStamp + _ttl;
31 | }
32 |
33 | @end
34 |
--------------------------------------------------------------------------------
/ImageHosting/External/HappyDNS/Common/QNResolverDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNResolverDelegate.h
3 | // HappyDNS
4 | //
5 | // Created by bailong on 15/6/23.
6 | // Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | extern const int kQNDomainHijackingCode;
12 | extern const int kQNDomainNotOwnCode;
13 | extern const int kQNDomainSeverError;
14 |
15 | #define QN_DNS_DEFAULT_TIMEOUT 20 //seconds
16 |
17 | @class QNDomain;
18 | @class QNNetworkInfo;
19 | @protocol QNResolverDelegate
20 | - (NSArray *)query:(QNDomain *)domain networkInfo:(QNNetworkInfo *)netInfo error:(NSError **)error;
21 | @end
22 |
--------------------------------------------------------------------------------
/ImageHosting/External/HappyDNS/HappyDNS.h:
--------------------------------------------------------------------------------
1 | //
2 | // HappyDNS.h
3 | // HappyDNS
4 | //
5 | // Created by bailong on 15/6/24.
6 | // Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "QNDnsManager.h"
12 | #import "QNDnspodEnterprise.h"
13 | #import "QNDnspodFree.h"
14 | #import "QNDomain.h"
15 | #import "QNHijackingDetectWrapper.h"
16 | #import "QNIP.h"
17 | #import "QNNetworkInfo.h"
18 | #import "QNRecord.h"
19 | #import "QNResolver.h"
20 | #import "QNResolverDelegate.h"
21 |
22 | #import "QNGetAddrInfo.h"
--------------------------------------------------------------------------------
/ImageHosting/External/HappyDNS/Http/QNDnspodEnterprise.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNDnspodEnterprise.h
3 | // HappyDNS
4 | //
5 | // Created by bailong on 15/7/31.
6 | // Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
7 | //
8 |
9 | #import "QNResolverDelegate.h"
10 | #import
11 |
12 | extern const int kQN_ENCRYPT_FAILED;
13 | extern const int kQN_DECRYPT_FAILED;
14 |
15 | @interface QNDnspodEnterprise : NSObject
16 |
17 | - (instancetype)initWithId:(NSString *)userId
18 | key:(NSString *)key;
19 |
20 | - (instancetype)initWithId:(NSString *)userId
21 | key:(NSString *)key
22 | server:(NSString *)server;
23 |
24 | - (instancetype)initWithId:(NSString *)userId
25 | key:(NSString *)key
26 | server:(NSString *)server
27 | timeout:(NSUInteger)time;
28 |
29 | - (NSArray *)query:(QNDomain *)domain networkInfo:(QNNetworkInfo *)netInfo error:(NSError *__autoreleasing *)error;
30 | @end
31 |
--------------------------------------------------------------------------------
/ImageHosting/External/HappyDNS/Http/QNDnspodEnterprise.m:
--------------------------------------------------------------------------------
1 | //
2 | // QNDnspodFree.m
3 | // HappyDNS
4 | //
5 | // Created by bailong on 15/6/23.
6 | // Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
7 | //
8 |
9 | #import "QNDnspodEnterprise.h"
10 | #import
11 |
12 | #import "QNDes.h"
13 | #import "QNDomain.h"
14 | #import "QNHex.h"
15 | #import "QNIP.h"
16 | #import "QNRecord.h"
17 |
18 | const int kQN_ENCRYPT_FAILED = -10001;
19 | const int kQN_DECRYPT_FAILED = -10002;
20 |
21 | @interface QNDnspodEnterprise ()
22 | @property (readonly, strong) NSString *server;
23 | @property (nonatomic, strong) NSString *userId;
24 | @property (nonatomic, strong) QNDes *des;
25 | @property (nonatomic) NSUInteger timeout;
26 |
27 | @end
28 |
29 | @implementation QNDnspodEnterprise
30 |
31 | - (instancetype)initWithId:(NSString *)userId
32 | key:(NSString *)key {
33 | return [self initWithId:userId key:key server:@"119.29.29.29"];
34 | }
35 |
36 | - (instancetype)initWithId:(NSString *)userId
37 | key:(NSString *)key
38 | server:(NSString *)server {
39 | return [self initWithId:userId key:key server:@"119.29.29.29" timeout:QN_DNS_DEFAULT_TIMEOUT];
40 | }
41 |
42 | - (instancetype)initWithId:(NSString *)userId
43 | key:(NSString *)key
44 | server:(NSString *)server
45 | timeout:(NSUInteger)time {
46 | if (self = [super init]) {
47 | _server = server;
48 | _userId = userId;
49 | _des = [[QNDes alloc] init:[key dataUsingEncoding:NSUTF8StringEncoding]];
50 | _timeout = time;
51 | }
52 | return self;
53 | }
54 |
55 | - (NSString *)encrypt:(NSString *)domain {
56 | NSData *data = [_des encrypt:[domain dataUsingEncoding:NSUTF8StringEncoding]];
57 | if (data == nil) {
58 | return nil;
59 | }
60 | NSString *str = [QNHex encodeHexData:data];
61 | return str;
62 | }
63 |
64 | - (NSString *)decrypt:(NSData *)raw {
65 | NSData *enc = [QNHex decodeHexString:[[NSString alloc] initWithData:raw
66 | encoding:NSUTF8StringEncoding]];
67 | if (enc == nil) {
68 | return nil;
69 | }
70 | NSData *data = [_des decrpyt:enc];
71 | if (data == nil) {
72 | return nil;
73 | }
74 | return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
75 | }
76 |
77 | - (NSArray *)query:(QNDomain *)domain networkInfo:(QNNetworkInfo *)netInfo error:(NSError *__autoreleasing *)error {
78 | NSString *encrypt = [self encrypt:domain.domain];
79 | if (encrypt == nil) {
80 | if (error != nil) {
81 | *error = [[NSError alloc] initWithDomain:domain.domain code:kQN_ENCRYPT_FAILED userInfo:nil];
82 | }
83 | return nil;
84 | }
85 | NSString *url = [NSString stringWithFormat:@"http://%@/d?ttl=1&dn=%@&id=%@", [QNIP ipHost:_server], encrypt, _userId];
86 | NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:_timeout];
87 | NSHTTPURLResponse *response = nil;
88 | NSError *httpError = nil;
89 | NSData *data = [NSURLConnection sendSynchronousRequest:urlRequest
90 | returningResponse:&response
91 | error:&httpError];
92 |
93 | if (httpError != nil) {
94 | if (error != nil) {
95 | *error = httpError;
96 | }
97 | return nil;
98 | }
99 | if (response.statusCode != 200) {
100 | return nil;
101 | }
102 |
103 | NSString *raw = [self decrypt:data];
104 | if (raw == nil) {
105 | if (error != nil) {
106 | *error = [[NSError alloc] initWithDomain:domain.domain code:kQN_DECRYPT_FAILED userInfo:nil];
107 | }
108 | return nil;
109 | }
110 | NSArray *ip1 = [raw componentsSeparatedByString:@","];
111 | if (ip1.count != 2) {
112 | return nil;
113 | }
114 | NSString *ttlStr = [ip1 objectAtIndex:1];
115 | int ttl = [ttlStr intValue];
116 | if (ttl <= 0) {
117 | return nil;
118 | }
119 | NSString *ips = [ip1 objectAtIndex:0];
120 | NSArray *ipArray = [ips componentsSeparatedByString:@";"];
121 | NSMutableArray *ret = [[NSMutableArray alloc] initWithCapacity:ipArray.count];
122 | for (int i = 0; i < ipArray.count; i++) {
123 | QNRecord *record = [[QNRecord alloc] init:[ipArray objectAtIndex:i] ttl:ttl type:kQNTypeA];
124 | [ret addObject:record];
125 | }
126 | return ret;
127 | }
128 |
129 | @end
130 |
--------------------------------------------------------------------------------
/ImageHosting/External/HappyDNS/Http/QNDnspodFree.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNDnspodFree.h
3 | // HappyDNS
4 | //
5 | // Created by bailong on 15/6/23.
6 | // Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
7 | //
8 |
9 | #import "QNResolverDelegate.h"
10 | #import
11 |
12 | @interface QNDnspodFree : NSObject
13 | - (NSArray *)query:(QNDomain *)domain networkInfo:(QNNetworkInfo *)netInfo error:(NSError *__autoreleasing *)error;
14 |
15 | - (instancetype)init;
16 | - (instancetype)initWithServer:(NSString *)server;
17 | - (instancetype)initWithServer:(NSString *)server
18 | timeout:(NSUInteger)time;
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/ImageHosting/External/HappyDNS/Http/QNDnspodFree.m:
--------------------------------------------------------------------------------
1 | //
2 | // QNDnspodFree.m
3 | // HappyDNS
4 | //
5 | // Created by bailong on 15/6/23.
6 | // Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
7 | //
8 |
9 | #import "QNDnspodFree.h"
10 | #import "QNDomain.h"
11 | #import "QNIP.h"
12 | #import "QNRecord.h"
13 |
14 | @interface QNDnspodFree ()
15 | @property (readonly, nonatomic, strong) NSString *server;
16 | @property (readonly, nonatomic) NSUInteger timeout;
17 | @end
18 |
19 | @implementation QNDnspodFree
20 |
21 | - (instancetype)init {
22 | return [self initWithServer:@"119.29.29.29"];
23 | }
24 | - (instancetype)initWithServer:(NSString *)server {
25 | return [self initWithServer:@"119.29.29.29" timeout:QN_DNS_DEFAULT_TIMEOUT];
26 | }
27 |
28 | - (instancetype)initWithServer:(NSString *)server
29 | timeout:(NSUInteger)time {
30 | if (self = [super init]) {
31 | _server = server;
32 | _timeout = time;
33 | }
34 | return self;
35 | }
36 |
37 | - (NSArray *)query:(QNDomain *)domain networkInfo:(QNNetworkInfo *)netInfo error:(NSError *__autoreleasing *)error {
38 | NSString *url = [NSString stringWithFormat:@"http://%@/d?ttl=1&dn=%@", [QNIP ipHost:_server], domain.domain];
39 | NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:_timeout];
40 | NSHTTPURLResponse *response = nil;
41 | NSError *httpError = nil;
42 | NSData *data = [NSURLConnection sendSynchronousRequest:urlRequest
43 | returningResponse:&response
44 | error:&httpError];
45 |
46 | if (httpError != nil) {
47 | if (error != nil) {
48 | *error = httpError;
49 | }
50 | return nil;
51 | }
52 | if (response.statusCode != 200) {
53 | return nil;
54 | }
55 | NSString *raw = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
56 | NSArray *ip1 = [raw componentsSeparatedByString:@","];
57 | if (ip1.count != 2) {
58 | return nil;
59 | }
60 | NSString *ttlStr = [ip1 objectAtIndex:1];
61 | int ttl = [ttlStr intValue];
62 | if (ttl <= 0) {
63 | return nil;
64 | }
65 | NSString *ips = [ip1 objectAtIndex:0];
66 | NSArray *ipArray = [ips componentsSeparatedByString:@";"];
67 | NSMutableArray *ret = [[NSMutableArray alloc] initWithCapacity:ipArray.count];
68 | for (int i = 0; i < ipArray.count; i++) {
69 | QNRecord *record = [[QNRecord alloc] init:[ipArray objectAtIndex:i] ttl:ttl type:kQNTypeA];
70 | [ret addObject:record];
71 | }
72 | return ret;
73 | }
74 |
75 | @end
76 |
--------------------------------------------------------------------------------
/ImageHosting/External/HappyDNS/Local/QNHijackingDetectWrapper.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNHijackingDetectWrapper.h
3 | // HappyDNS
4 | //
5 | // Created by bailong on 15/7/16.
6 | // Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "QNResolverDelegate.h"
12 |
13 | @class QNResolver;
14 | @interface QNHijackingDetectWrapper : NSObject
15 | - (NSArray *)query:(QNDomain *)domain networkInfo:(QNNetworkInfo *)netInfo error:(NSError *__autoreleasing *)error;
16 | - (instancetype)initWithResolver:(QNResolver *)resolver;
17 | @end
18 |
--------------------------------------------------------------------------------
/ImageHosting/External/HappyDNS/Local/QNHijackingDetectWrapper.m:
--------------------------------------------------------------------------------
1 | //
2 | // QNHijackingDetectWrapper.m
3 | // HappyDNS
4 | //
5 | // Created by bailong on 15/7/16.
6 | // Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
7 | //
8 |
9 | #import "QNHijackingDetectWrapper.h"
10 | #import "QNDomain.h"
11 | #import "QNRecord.h"
12 | #import "QNResolver.h"
13 |
14 | @interface QNHijackingDetectWrapper ()
15 | @property (nonatomic, readonly) QNResolver *resolver;
16 | @end
17 |
18 | @implementation QNHijackingDetectWrapper
19 |
20 | - (NSArray *)query:(QNDomain *)domain networkInfo:(QNNetworkInfo *)netInfo error:(NSError *__autoreleasing *)error {
21 | NSArray *result = [_resolver query:domain networkInfo:netInfo error:error];
22 | if (((!domain.hasCname) && domain.maxTtl == 0) || result == nil || result.count == 0) {
23 | return result;
24 | }
25 | BOOL hasCname = NO;
26 | BOOL outOfTtl = NO;
27 | for (int i = 0; i < result.count; i++) {
28 | QNRecord *record = [result objectAtIndex:i];
29 | if (record.type == kQNTypeCname) {
30 | hasCname = YES;
31 | }
32 | if (domain.maxTtl > 0 && record.type == kQNTypeA && record.ttl > domain.maxTtl) {
33 | outOfTtl = YES;
34 | }
35 | }
36 | if ((domain.hasCname && !hasCname) || outOfTtl) {
37 | if (error != nil) {
38 | *error = [[NSError alloc] initWithDomain:domain.domain code:kQNDomainHijackingCode userInfo:nil];
39 | }
40 | return nil;
41 | }
42 | return result;
43 | }
44 | - (instancetype)initWithResolver:(QNResolver *)resolver {
45 | if (self = [super init]) {
46 | _resolver = resolver;
47 | }
48 | return self;
49 | }
50 |
51 | @end
52 |
--------------------------------------------------------------------------------
/ImageHosting/External/HappyDNS/Local/QNHosts.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNHosts.h
3 | // HappyDNS
4 | //
5 | // Created by bailong on 15/6/23.
6 | // Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
7 | //
8 |
9 | #import "QNResolverDelegate.h"
10 | #import
11 |
12 | @interface QNHosts : NSObject
13 |
14 | - (NSArray *)query:(QNDomain *)domain networkInfo:(QNNetworkInfo *)netInfo;
15 | - (void)put:(NSString *)domain ip:(NSString *)ip;
16 | - (void)put:(NSString *)domain ip:(NSString *)ip provider:(int)provider;
17 | - (instancetype)init;
18 | @end
19 |
--------------------------------------------------------------------------------
/ImageHosting/External/HappyDNS/Local/QNHosts.m:
--------------------------------------------------------------------------------
1 | //
2 | // QNHosts.m
3 | // HappyDNS
4 | //
5 | // Created by bailong on 15/6/23.
6 | // Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
7 | //
8 |
9 | #import "QNHosts.h"
10 | #import "QNDomain.h"
11 | //#import "QNIP.h"
12 | #import "QNNetworkInfo.h"
13 |
14 | @interface QNHosts ()
15 | @property (nonatomic) NSMutableDictionary *dict;
16 | @end
17 |
18 | @interface QNHostsValue : NSObject
19 | @property (nonatomic, copy, readonly) NSString *ip;
20 | @property (readonly) int provider;
21 | @end
22 |
23 | @implementation QNHostsValue
24 |
25 | - (instancetype)init:(NSString *)ip provider:(int)provider {
26 | if (self = [super init]) {
27 | _ip = ip;
28 | _provider = provider;
29 | }
30 | return self;
31 | }
32 |
33 | @end
34 |
35 | static NSArray *filter(NSArray *input, int provider) {
36 | NSMutableArray *normal = [[NSMutableArray alloc] initWithCapacity:input.count];
37 | NSMutableArray *special = [[NSMutableArray alloc] init];
38 | for (QNHostsValue *v in input) {
39 | NSString *ip = v.ip;
40 | if (v.provider == kQNISP_GENERAL) {
41 | [normal addObject:ip];
42 | }
43 | if (provider == v.provider && provider != kQNISP_GENERAL) {
44 | [special addObject:ip];
45 | }
46 | }
47 | if (special.count != 0) {
48 | return special;
49 | }
50 | return normal;
51 | }
52 |
53 | @implementation QNHosts
54 | - (NSArray *)query:(QNDomain *)domain networkInfo:(QNNetworkInfo *)netInfo {
55 | NSMutableArray *x;
56 | @synchronized(_dict) {
57 | x = [_dict objectForKey:domain.domain];
58 | }
59 |
60 | if (x == nil || x.count == 0) {
61 | return nil;
62 | }
63 | if (x.count >= 2) {
64 | QNHostsValue *first = [x firstObject];
65 | [x removeObjectAtIndex:0];
66 | [x addObject:first];
67 | }
68 | return filter(x, netInfo.provider);
69 | }
70 |
71 | - (void)put:(NSString *)domain ip:(NSString *)ip {
72 | [self put:domain ip:ip provider:kQNISP_GENERAL];
73 | }
74 |
75 | - (void)put:(NSString *)domain ip:(NSString *)ip provider:(int)provider {
76 | QNHostsValue *v = [[QNHostsValue alloc] init:ip provider:provider];
77 | @synchronized(_dict) {
78 | NSMutableArray *x = [_dict objectForKey:domain];
79 | if (x == nil) {
80 | x = [[NSMutableArray alloc] init];
81 | }
82 | [x addObject:v];
83 | [_dict setObject:x forKey:domain];
84 | }
85 | }
86 |
87 | - (instancetype)init {
88 | if (self = [super init]) {
89 | _dict = [[NSMutableDictionary alloc] init];
90 | }
91 | return self;
92 | }
93 |
94 | @end
95 |
--------------------------------------------------------------------------------
/ImageHosting/External/HappyDNS/Local/QNResolvUtil.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNResolv.h
3 | // HappyDNS
4 | //
5 | // Created by bailong on 16/5/28.
6 | // Copyright © 2016年 Qiniu Cloud Storage. All rights reserved.
7 | //
8 |
9 | #ifndef QNResolv_h
10 | #define QNResolv_h
11 |
12 | extern BOOL isV6(NSString *address);
13 |
14 | extern int setup_dns_server(void *res, NSString *dns_server, NSUInteger timeout);
15 |
16 | #endif /* QNResolv_h */
17 |
--------------------------------------------------------------------------------
/ImageHosting/External/HappyDNS/Local/QNResolvUtil.m:
--------------------------------------------------------------------------------
1 | //
2 | // QNResolvUtil.m
3 | // HappyDNS
4 | //
5 | // Created by bailong on 16/5/28.
6 | // Copyright © 2016年 Qiniu Cloud Storage. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #include
12 | #include
13 | #include
14 |
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 |
21 | #import "QNIP.h"
22 |
23 | #if __IPHONE_OS_VERSION_MIN_REQUIRED
24 | #import
25 | #import
26 | #endif
27 |
28 | BOOL isV6(NSString *address) {
29 | return strchr(address.UTF8String, ':') != NULL;
30 | }
31 |
32 | int setup_dns_server(void *_res_state, NSString *dns_server, NSUInteger timeout) {
33 | res_state res = (res_state)_res_state;
34 | int r = res_ninit(res);
35 | if (r != 0) {
36 | return r;
37 | }
38 | res->retrans = (int)timeout;
39 | res->retry = 1;
40 | if (dns_server == nil) {
41 | return 0;
42 | }
43 | res->options |= RES_IGNTC;
44 |
45 | union res_sockaddr_union server = {0};
46 |
47 | struct addrinfo hints = {0}, *ai = NULL;
48 | hints.ai_family = AF_UNSPEC;
49 | hints.ai_socktype = SOCK_STREAM;
50 | int ret = getaddrinfo(dns_server.UTF8String, "53", &hints, &ai);
51 | if (ret != 0) {
52 | return ret;
53 | }
54 | int family = ai->ai_family;
55 |
56 | if (family == AF_INET6) {
57 | ((struct sockaddr_in6 *)ai->ai_addr)->sin6_port = htons(53);
58 | server.sin6 = *((struct sockaddr_in6 *)ai->ai_addr);
59 | } else {
60 | server.sin = *((struct sockaddr_in *)ai->ai_addr);
61 | }
62 |
63 | if (![QNIP isIpV6FullySupported] && family == AF_INET) {
64 | if ([QNIP isV6]) {
65 | freeaddrinfo(ai);
66 | ai = NULL;
67 | bzero(&hints, 0);
68 | hints.ai_family = AF_UNSPEC;
69 | hints.ai_socktype = SOCK_STREAM;
70 | char buf[64] = {0};
71 | qn_nat64(buf, sizeof(buf), (uint32_t)server.sin.sin_addr.s_addr);
72 | int ret = getaddrinfo(buf, "53", &hints, &ai);
73 | if (ret != 0) {
74 | return -1;
75 | }
76 | ((struct sockaddr_in6 *)ai->ai_addr)->sin6_port = htons(53);
77 | server.sin6 = *((struct sockaddr_in6 *)ai->ai_addr);
78 | }
79 | }
80 |
81 | freeaddrinfo(ai);
82 | res_setservers(res, &server, 1);
83 | return 0;
84 | }
--------------------------------------------------------------------------------
/ImageHosting/External/HappyDNS/Local/QNResolver.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNResolver.h
3 | // HappyDNS
4 | //
5 | // Created by bailong on 15/6/23.
6 | // Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
7 | //
8 |
9 | #import "QNResolverDelegate.h"
10 | #import
11 |
12 | @interface QNResolver : NSObject
13 | - (NSArray *)query:(QNDomain *)domain networkInfo:(QNNetworkInfo *)netInfo error:(NSError *__autoreleasing *)error;
14 |
15 | // @deprecated typo
16 | - (instancetype)initWithAddres:(NSString *)address DEPRECATED_ATTRIBUTE;
17 |
18 | - (instancetype)initWithAddress:(NSString *)address;
19 |
20 | - (instancetype)initWithAddress:(NSString *)address
21 | timeout:(NSUInteger)time;
22 |
23 | + (instancetype)systemResolver;
24 | + (NSString *)systemDnsServer;
25 | @end
26 |
--------------------------------------------------------------------------------
/ImageHosting/External/HappyDNS/Local/QNTxtResolver.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNTxtResolver.h
3 | // HappyDNS
4 | //
5 | // Created by bailong on 16/1/5.
6 | // Copyright © 2016年 Qiniu Cloud Storage. All rights reserved.
7 | //
8 |
9 | #import "QNResolverDelegate.h"
10 | #import
11 |
12 | @interface QNTxtResolver : NSObject
13 | - (NSArray *)query:(QNDomain *)domain networkInfo:(QNNetworkInfo *)netInfo error:(NSError *__autoreleasing *)error;
14 |
15 | /**
16 | * 根据服务器地址进行初始化
17 | *
18 | * @param address DNS 服务器地址,nil 表示系统的
19 | */
20 | - (instancetype)initWithAddress:(NSString *)address;
21 |
22 | - (instancetype)initWithAddress:(NSString *)address timeout:(NSUInteger)time;
23 | @end
24 |
--------------------------------------------------------------------------------
/ImageHosting/External/HappyDNS/Local/QNTxtResolver.m:
--------------------------------------------------------------------------------
1 | //
2 | // QNTxtResolver.m
3 | // HappyDNS
4 | //
5 | // Created by bailong on 16/1/5.
6 | // Copyright © 2016年 Qiniu Cloud Storage. All rights reserved.
7 | //
8 |
9 | #import "QNTxtResolver.h"
10 |
11 | #include
12 | #include
13 | #include
14 |
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 |
21 | #import "QNDomain.h"
22 | #import "QNRecord.h"
23 | #import "QNResolvUtil.h"
24 | #import "QNResolver.h"
25 |
26 | @interface QNTxtResolver ()
27 | @property (nonatomic, readonly, strong) NSString *address;
28 | @property (nonatomic, readonly) NSUInteger timeout;
29 | @end
30 |
31 | static NSArray *query_ip(res_state res, const char *host) {
32 | u_char answer[1500];
33 | int len = res_nquery(res, host, ns_c_in, ns_t_txt, answer, sizeof(answer));
34 |
35 | ns_msg handle;
36 | ns_initparse(answer, len, &handle);
37 |
38 | int count = ns_msg_count(handle, ns_s_an);
39 | if (count != 1) {
40 | res_ndestroy(res);
41 | return nil;
42 | }
43 |
44 | char txtbuf[256];
45 | memset(txtbuf, 0, sizeof(txtbuf));
46 |
47 | ns_rr rr;
48 | if (ns_parserr(&handle, ns_s_an, 0, &rr) != 0) {
49 | res_ndestroy(res);
50 | return nil;
51 | }
52 | int t = ns_rr_type(rr);
53 | int ttl = ns_rr_ttl(rr);
54 | int rdlen = ns_rr_rdlen(rr);
55 | if (rdlen <= 1 + 7) {
56 | res_ndestroy(res);
57 | return nil;
58 | }
59 | NSString *val;
60 | if (t == ns_t_txt) {
61 | memcpy(txtbuf, ns_rr_rdata(rr) + 1, rdlen - 1);
62 | val = [NSString stringWithUTF8String:txtbuf];
63 | } else {
64 | res_ndestroy(res);
65 | return nil;
66 | }
67 | NSArray *ipArray = [val componentsSeparatedByString:@","];
68 | NSMutableArray *ret = [[NSMutableArray alloc] initWithCapacity:ipArray.count];
69 | for (int i = 0; i < ipArray.count; i++) {
70 | QNRecord *record = [[QNRecord alloc] init:[ipArray objectAtIndex:i] ttl:ttl type:kQNTypeA];
71 | [ret addObject:record];
72 | }
73 |
74 | res_ndestroy(res);
75 | return ret;
76 | }
77 |
78 | @implementation QNTxtResolver
79 | - (instancetype)initWithAddress:(NSString *)address {
80 | return [self initWithAddress:address timeout:QN_DNS_DEFAULT_TIMEOUT];
81 | }
82 |
83 | - (instancetype)initWithAddress:(NSString *)address timeout:(NSUInteger)time {
84 | if (self = [super init]) {
85 | _address = address;
86 | _timeout = time;
87 | }
88 | return self;
89 | }
90 |
91 | - (NSArray *)query:(QNDomain *)domain networkInfo:(QNNetworkInfo *)netInfo error:(NSError *__autoreleasing *)error {
92 | struct __res_state res;
93 |
94 | int r = setup_dns_server(&res, _address, _timeout);
95 | if (r != 0) {
96 | if (error != nil) {
97 | *error = [[NSError alloc] initWithDomain:@"qiniu.dns" code:kQNDomainSeverError userInfo:nil];
98 | }
99 | return nil;
100 | }
101 |
102 | NSArray *ret = query_ip(&res, [domain.domain cStringUsingEncoding:NSUTF8StringEncoding]);
103 | if (ret == nil && error != nil) {
104 | *error = [[NSError alloc] initWithDomain:@"qiniu.dns" code:NSURLErrorDNSLookupFailed userInfo:nil];
105 | }
106 | return ret;
107 | }
108 |
109 | @end
110 |
--------------------------------------------------------------------------------
/ImageHosting/External/HappyDNS/Util/QNDes.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNDes.h
3 | // HappyDNS
4 | //
5 | // Created by bailong on 15/8/1.
6 | // Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | extern const int kQN_ENCRYPT_FAILED;
12 | extern const int kQN_DECRYPT_FAILED;
13 |
14 | @interface QNDes : NSObject
15 |
16 | - (NSData *)encrypt:(NSData *)input;
17 |
18 | - (NSData *)decrpyt:(NSData *)input;
19 |
20 | - (instancetype)init:(NSData *)key;
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/ImageHosting/External/HappyDNS/Util/QNDes.m:
--------------------------------------------------------------------------------
1 | //
2 | // QNDes.m
3 | // HappyDNS
4 | //
5 | // Created by bailong on 15/8/1.
6 | // Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
7 | //
8 |
9 | #import "QNDes.h"
10 |
11 | #import
12 |
13 | @interface QNDes ()
14 | @property (nonatomic, strong) NSData *key;
15 | @end
16 |
17 | @implementation QNDes
18 |
19 | - (NSData *)encrypt:(NSData *)data {
20 | const void *input = data.bytes;
21 | size_t inputSize = data.length;
22 |
23 | size_t bufferSize = (inputSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
24 | uint8_t *buffer = malloc(bufferSize * sizeof(uint8_t));
25 | memset((void *)buffer, 0x0, bufferSize);
26 | size_t movedBytes = 0;
27 |
28 | const void *vkey = _key.bytes;
29 |
30 | CCCryptorStatus ccStatus = CCCrypt(kCCEncrypt,
31 | kCCAlgorithmDES,
32 | kCCOptionECBMode | kCCOptionPKCS7Padding,
33 | vkey,
34 | kCCKeySizeDES,
35 | NULL,
36 | input,
37 | inputSize,
38 | (void *)buffer,
39 | bufferSize,
40 | &movedBytes);
41 | if (ccStatus != kCCSuccess) {
42 | NSLog(@"error code %d", ccStatus);
43 | free(buffer);
44 | return nil;
45 | }
46 | NSData *encrypted = [NSData dataWithBytes:(const void *)buffer length:(NSUInteger)movedBytes];
47 | free(buffer);
48 | return encrypted;
49 | }
50 |
51 | - (NSData *)decrpyt:(NSData *)raw {
52 | const void *input = raw.bytes;
53 | size_t inputSize = raw.length;
54 |
55 | size_t bufferSize = 1024;
56 | uint8_t *buffer = malloc(bufferSize * sizeof(uint8_t));
57 | memset((void *)buffer, 0x0, bufferSize);
58 | size_t movedBytes = 0;
59 |
60 | const void *vkey = _key.bytes;
61 |
62 | CCCryptorStatus ccStatus = CCCrypt(kCCDecrypt,
63 | kCCAlgorithmDES,
64 | kCCOptionECBMode | kCCOptionPKCS7Padding,
65 | vkey,
66 | kCCKeySizeDES,
67 | NULL,
68 | input,
69 | inputSize,
70 | (void *)buffer,
71 | bufferSize,
72 | &movedBytes);
73 |
74 | if (ccStatus != kCCSuccess) {
75 | NSLog(@"error code %d", ccStatus);
76 | free(buffer);
77 | return nil;
78 | }
79 |
80 | NSData *decrypted = [NSData dataWithBytes:(const void *)buffer length:(NSUInteger)movedBytes];
81 | free(buffer);
82 | return decrypted;
83 | }
84 |
85 | - (instancetype)init:(NSData *)key {
86 | if (self = [super init]) {
87 | _key = key;
88 | }
89 | return self;
90 | }
91 |
92 | @end
93 |
--------------------------------------------------------------------------------
/ImageHosting/External/HappyDNS/Util/QNGetAddrInfo.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNGetAddrInfo.h
3 | // HappyDNS
4 | //
5 | // Created by bailong on 16/7/19.
6 | // Copyright © 2016年 Qiniu Cloud Storage. All rights reserved.
7 | //
8 |
9 | #ifndef QNGetAddrInfo_h
10 | #define QNGetAddrInfo_h
11 |
12 | #ifdef __cplusplus
13 | extern "C" {
14 | #endif
15 |
16 | typedef struct qn_ips_ret {
17 | char *ips[1];
18 | } qn_ips_ret;
19 |
20 | typedef qn_ips_ret *(*qn_dns_callback)(const char *host);
21 |
22 | extern void qn_free_ips_ret(qn_ips_ret *ip_list);
23 |
24 | extern int qn_getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res);
25 |
26 | extern void qn_freeaddrinfo(struct addrinfo *ai);
27 |
28 | extern void qn_set_dns_callback(qn_dns_callback cb);
29 |
30 | #ifdef __cplusplus
31 | };
32 | #endif
33 |
34 | #endif /* QNGetAddrInfo_h */
35 |
--------------------------------------------------------------------------------
/ImageHosting/External/HappyDNS/Util/QNGetAddrInfo.m:
--------------------------------------------------------------------------------
1 | //
2 | // QNGetAddrInfo.c
3 | // HappyDNS
4 | //
5 | // Created by bailong on 16/7/19.
6 | // Copyright © 2016年 Qiniu Cloud Storage. All rights reserved.
7 | //
8 |
9 | #include "string.h"
10 | #include "netdb.h"
11 | #include "stdlib.h"
12 |
13 | #include "QNGetAddrInfo.h"
14 |
15 | //fast judge domain or ip, not verify ip right.
16 | static int isIp(const char* domain) {
17 | size_t l = strlen(domain);
18 | if (l > 15 || l < 7) {
19 | return 0;
20 | }
21 |
22 | for (const char* p = domain; p < domain + l; p++) {
23 | if ((*p < '0' || *p > '9') && *p != '.') {
24 | return 0;
25 | }
26 | }
27 | return 1;
28 | }
29 |
30 | static struct addrinfo* addrinfo_clone(struct addrinfo* addr) {
31 | struct addrinfo* ai;
32 | ai = calloc(sizeof(struct addrinfo) + addr->ai_addrlen, 1);
33 | if (ai) {
34 | memcpy(ai, addr, sizeof(struct addrinfo));
35 | ai->ai_addr = (void*)(ai + 1);
36 | memcpy(ai->ai_addr, addr->ai_addr, addr->ai_addrlen);
37 | if (addr->ai_canonname) {
38 | ai->ai_canonname = strdup(addr->ai_canonname);
39 | }
40 | ai->ai_next = NULL;
41 | }
42 | return ai;
43 | }
44 |
45 | static void append_addrinfo(struct addrinfo** head, struct addrinfo* addr) {
46 | if (*head == NULL) {
47 | *head = addr;
48 | return;
49 | }
50 | struct addrinfo* ai = *head;
51 | while (ai->ai_next != NULL) {
52 | ai = ai->ai_next;
53 | }
54 | ai->ai_next = addr;
55 | }
56 |
57 | void qn_free_ips_ret(qn_ips_ret* ip_list) {
58 | if (ip_list == NULL) {
59 | return;
60 | }
61 | char** p = ip_list->ips;
62 | while (*p != NULL) {
63 | free(*p);
64 | p++;
65 | }
66 | free(ip_list);
67 | }
68 |
69 | static qn_dns_callback dns_callback = NULL;
70 | int qn_getaddrinfo(const char* hostname, const char* servname, const struct addrinfo* hints, struct addrinfo** res) {
71 | if (dns_callback == NULL || hostname == NULL || isIp(hostname)) {
72 | return getaddrinfo(hostname, servname, hints, res);
73 | }
74 |
75 | qn_ips_ret* ret = dns_callback(hostname);
76 | if (ret == NULL) {
77 | return EAI_NODATA;
78 | }
79 | if (ret->ips[0] == NULL) {
80 | qn_free_ips_ret(ret);
81 | return EAI_NODATA;
82 | }
83 | int i;
84 | struct addrinfo* ai = NULL;
85 | struct addrinfo* store = NULL;
86 | int r = 0;
87 | for (i = 0; ret->ips[i] != NULL; i++) {
88 | r = getaddrinfo(ret->ips[i], servname, hints, &ai);
89 | if (r != 0) {
90 | break;
91 | }
92 | struct addrinfo* temp = ai;
93 | ai = addrinfo_clone(ai);
94 | append_addrinfo(&store, ai);
95 | freeaddrinfo(temp);
96 | ai = NULL;
97 | }
98 | qn_free_ips_ret(ret);
99 | if (r != 0) {
100 | qn_freeaddrinfo(store);
101 | return r;
102 | }
103 | *res = store;
104 | return 0;
105 | }
106 |
107 | void qn_freeaddrinfo(struct addrinfo* ai) {
108 | if (ai == NULL) {
109 | return;
110 | }
111 | struct addrinfo* next;
112 | do {
113 | next = ai->ai_next;
114 | if (ai->ai_canonname)
115 | free(ai->ai_canonname);
116 | /* no need to free(ai->ai_addr) */
117 | free(ai);
118 | ai = next;
119 | } while (ai);
120 | }
121 |
122 | void qn_set_dns_callback(qn_dns_callback cb) {
123 | dns_callback = cb;
124 | }
--------------------------------------------------------------------------------
/ImageHosting/External/HappyDNS/Util/QNHex.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNHex.h
3 | // HappyDNS
4 | //
5 | // Created by bailong on 15/7/31.
6 | // Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | char *qn_encodeHexData(char *output_buf, const char *data, int data_size, BOOL up);
12 |
13 | @interface QNHex : NSObject
14 |
15 | + (NSString *)encodeHexData:(NSData *)data;
16 | + (NSString *)encodeHexString:(NSString *)str;
17 |
18 | + (NSData *)decodeHexString:(NSString *)hex;
19 | + (NSString *)decodeHexToString:(NSString *)hex;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/ImageHosting/External/HappyDNS/Util/QNHex.m:
--------------------------------------------------------------------------------
1 | //
2 | // QNHex.m
3 | // HappyDNS
4 | //
5 | // Created by bailong on 15/7/31.
6 | // Copyright (c) 2015年 Qiniu Cloud Storage. All rights reserved.
7 | //
8 |
9 | #import "QNHex.h"
10 |
11 | static char DIGITS_LOWER[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
12 |
13 | static char DIGITS_UPPER[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
14 |
15 | static int hexDigit(char c) {
16 | int result = -1;
17 | if ('0' <= c && c <= '9') {
18 | result = c - '0';
19 | } else if ('a' <= c && c <= 'f') {
20 | result = 10 + (c - 'a');
21 | } else if ('A' <= c && c <= 'F') {
22 | result = 10 + (c - 'A');
23 | }
24 | return result;
25 | }
26 |
27 | static char *decodeHex(const char *data, int size) {
28 | if ((size & 0x01) != 0) {
29 | return NULL;
30 | }
31 | char *output = malloc(size / 2);
32 | int outLimit = 0;
33 | for (int i = 0, j = 0; j < size; i++) {
34 | int f = hexDigit(data[j]);
35 | if (f < 0) {
36 | outLimit = 1;
37 | break;
38 | }
39 | j++;
40 | int f2 = hexDigit(data[j]);
41 | if (f2 < 0) {
42 | outLimit = 1;
43 | break;
44 | }
45 | f = (f << 4) | f2;
46 | j++;
47 | output[i] = (char)(f & 0xff);
48 | }
49 | if (outLimit) {
50 | free(output);
51 | return NULL;
52 | }
53 | return output;
54 | }
55 |
56 | static char *encodeHexInternal(char *output_buf, const char *data, int size, char hexTable[]) {
57 | for (int i = 0, j = 0; i < size; i++) {
58 | output_buf[j++] = hexTable[((0XF0 & data[i]) >> 4) & 0X0F];
59 | output_buf[j++] = hexTable[((0X0F & data[i])) & 0X0F];
60 | }
61 | return output_buf;
62 | }
63 |
64 | static char *encodeHex(const char *data, int size, char hexTable[]) {
65 | char *output = malloc(size * 2);
66 | return encodeHexInternal(output, data, size, hexTable);
67 | }
68 |
69 | char *qn_encodeHexData(char *buff, const char *data, int data_size, BOOL up) {
70 | char *hexTable = DIGITS_UPPER;
71 | if (!up) {
72 | hexTable = DIGITS_LOWER;
73 | }
74 | return encodeHexInternal(buff, data, data_size, hexTable);
75 | }
76 |
77 | @implementation QNHex
78 |
79 | + (NSString *)encodeHexData:(NSData *)data {
80 | char *e = encodeHex(data.bytes, (int)data.length, DIGITS_UPPER);
81 | NSString *str = [[NSString alloc] initWithBytes:e length:data.length * 2 encoding:NSASCIIStringEncoding];
82 | free(e);
83 | return str;
84 | }
85 |
86 | + (NSString *)encodeHexString:(NSString *)str {
87 | return [QNHex encodeHexData:[str dataUsingEncoding:NSUTF8StringEncoding]];
88 | }
89 |
90 | + (NSData *)decodeHexString:(NSString *)hex {
91 | char *d = decodeHex(hex.UTF8String, (int)hex.length);
92 | if (d == NULL) {
93 | return nil;
94 | }
95 | NSData *data = [NSData dataWithBytes:d length:hex.length / 2];
96 | free(d);
97 | return data;
98 | }
99 |
100 | + (NSString *)decodeHexToString:(NSString *)hex {
101 | NSData *data = [QNHex decodeHexString:hex];
102 | if (data == nil) {
103 | return nil;
104 | }
105 | return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
106 | }
107 |
108 | @end
109 |
--------------------------------------------------------------------------------
/ImageHosting/External/HappyDNS/Util/QNIP.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNIPV6.h
3 | // HappyDNS
4 | //
5 | // Created by bailong on 16/5/25.
6 | // Copyright © 2016年 Qiniu Cloud Storage. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | extern int qn_localIp(char *buf, int buf_size);
12 | extern void qn_nat64(char *buf, int buf_size, uint32_t ipv4_addr);
13 |
14 | @interface QNIP : NSObject
15 |
16 | + (BOOL)isV6;
17 |
18 | + (NSString *)adaptiveIp:(NSString *)ipv4;
19 |
20 | + (NSString *)local;
21 |
22 | // ipv6 in url like http://[::xxx]/
23 | + (NSString *)ipHost:(NSString *)ip;
24 |
25 | + (NSString *)nat64:(NSString *)ip;
26 |
27 | + (BOOL)isIpV6FullySupported;
28 |
29 | + (BOOL)mayBeIpV4:(NSString *)domain;
30 |
31 | @end
32 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Common/QNALAssetFile.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNALAssetFile.h
3 | // QiniuSDK
4 | //
5 | // Created by bailong on 15/7/25.
6 | // Copyright (c) 2015年 Qiniu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "QNFileDelegate.h"
12 |
13 | #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED)
14 | @class ALAsset;
15 | @interface QNALAssetFile : NSObject
16 |
17 | /**
18 | * 打开指定文件
19 | *
20 | * @param path 文件路径
21 | * @param error 输出的错误信息
22 | *
23 | * @return 实例
24 | */
25 | - (instancetype)init:(ALAsset *)asset
26 | error:(NSError *__autoreleasing *)error;
27 | @end
28 | #endif
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Common/QNALAssetFile.m:
--------------------------------------------------------------------------------
1 | //
2 | // QNALAssetFile.m
3 | // QiniuSDK
4 | //
5 | // Created by bailong on 15/7/25.
6 | // Copyright (c) 2015年 Qiniu. All rights reserved.
7 | //
8 |
9 | #import "QNALAssetFile.h"
10 |
11 | #ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
12 | #import
13 |
14 | #import "QNResponseInfo.h"
15 |
16 | @interface QNALAssetFile ()
17 |
18 | @property (nonatomic) ALAsset *asset;
19 |
20 | @property (readonly) int64_t fileSize;
21 |
22 | @property (readonly) int64_t fileModifyTime;
23 |
24 | @end
25 |
26 | @implementation QNALAssetFile
27 | - (instancetype)init:(ALAsset *)asset
28 | error:(NSError *__autoreleasing *)error {
29 | if (self = [super init]) {
30 | NSDate *createTime = [asset valueForProperty:ALAssetPropertyDate];
31 | int64_t t = 0;
32 | if (createTime != nil) {
33 | t = [createTime timeIntervalSince1970];
34 | }
35 | _fileModifyTime = t;
36 | _fileSize = asset.defaultRepresentation.size;
37 | _asset = asset;
38 | }
39 |
40 | return self;
41 | }
42 |
43 | - (NSData *)read:(long)offset
44 | size:(long)size {
45 | ALAssetRepresentation *rep = [self.asset defaultRepresentation];
46 | Byte *buffer = (Byte *)malloc(size);
47 | NSUInteger buffered = [rep getBytes:buffer fromOffset:offset length:size error:nil];
48 |
49 | return [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];
50 | }
51 |
52 | - (NSData *)readAll {
53 | return [self read:0 size:(long)_fileSize];
54 | }
55 |
56 | - (void)close {
57 | }
58 |
59 | - (NSString *)path {
60 | ALAssetRepresentation *rep = [self.asset defaultRepresentation];
61 | return [rep url].path;
62 | }
63 |
64 | - (int64_t)modifyTime {
65 | return _fileModifyTime;
66 | }
67 |
68 | - (int64_t)size {
69 | return _fileSize;
70 | }
71 | @end
72 | #endif
73 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Common/QNAsyncRun.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNAsyncRun.h
3 | // QiniuSDK
4 | //
5 | // Created by bailong on 14/10/17.
6 | // Copyright (c) 2014年 Qiniu. All rights reserved.
7 | //
8 |
9 | typedef void (^QNRun)(void);
10 |
11 | void QNAsyncRun(QNRun run);
12 |
13 | void QNAsyncRunInMain(QNRun run);
14 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Common/QNAsyncRun.m:
--------------------------------------------------------------------------------
1 | //
2 | // QNAsyncRun.m
3 | // QiniuSDK
4 | //
5 | // Created by bailong on 14/10/17.
6 | // Copyright (c) 2014年 Qiniu. All rights reserved.
7 | //
8 |
9 | #import "QNAsyncRun.h"
10 | #import
11 |
12 | void QNAsyncRun(QNRun run) {
13 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
14 | run();
15 | });
16 | }
17 |
18 | void QNAsyncRunInMain(QNRun run) {
19 | dispatch_async(dispatch_get_main_queue(), ^(void) {
20 | run();
21 | });
22 | }
23 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Common/QNCrc32.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNCrc.h
3 | // QiniuSDK
4 | //
5 | // Created by bailong on 14-9-29.
6 | // Copyright (c) 2014年 Qiniu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | /**
12 | * 生成crc32 校验码
13 | */
14 | @interface QNCrc32 : NSObject
15 |
16 | /**
17 | * 文件校验
18 | *
19 | * @param filePath 文件路径
20 | * @param error 文件读取错误
21 | *
22 | * @return 校验码
23 | */
24 | + (UInt32)file:(NSString *)filePath
25 | error:(NSError **)error;
26 |
27 | /**
28 | * 二进制字节校验
29 | *
30 | * @param data 二进制数据
31 | *
32 | * @return 校验码
33 | */
34 | + (UInt32)data:(NSData *)data;
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Common/QNCrc32.m:
--------------------------------------------------------------------------------
1 | //
2 | // QNCrc.m
3 | // QiniuSDK
4 | //
5 | // Created by bailong on 14-9-29.
6 | // Copyright (c) 2014年 Qiniu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "QNConfiguration.h"
12 | #import "QNCrc32.h"
13 |
14 | @implementation QNCrc32
15 |
16 | + (UInt32)data:(NSData *)data {
17 | uLong crc = crc32(0L, Z_NULL, 0);
18 |
19 | crc = crc32(crc, [data bytes], (uInt)[data length]);
20 | return (UInt32)crc;
21 | }
22 |
23 | + (UInt32)file:(NSString *)filePath
24 | error:(NSError **)error {
25 | @autoreleasepool {
26 | NSData *data = [NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedIfSafe error:error];
27 | if (*error != nil) {
28 | return 0;
29 | }
30 |
31 | int len = (int)[data length];
32 | int count = (len + kQNBlockSize - 1) / kQNBlockSize;
33 |
34 | uLong crc = crc32(0L, Z_NULL, 0);
35 | for (int i = 0; i < count; i++) {
36 | int offset = i * kQNBlockSize;
37 | int size = (len - offset) > kQNBlockSize ? kQNBlockSize : (len - offset);
38 | NSData *d = [data subdataWithRange:NSMakeRange(offset, (unsigned int)size)];
39 | crc = crc32(crc, [d bytes], (uInt)[d length]);
40 | }
41 | return (UInt32)crc;
42 | }
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Common/QNEtag.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNEtag.h
3 | // QiniuSDK
4 | //
5 | // Created by bailong on 14/10/4.
6 | // Copyright (c) 2014年 Qiniu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | /**
12 | * 服务器 hash etag 生成
13 | */
14 | @interface QNEtag : NSObject
15 |
16 | /**
17 | * 文件etag
18 | *
19 | * @param filePath 文件路径
20 | * @param error 输出文件读取错误
21 | *
22 | * @return etag
23 | */
24 | + (NSString *)file:(NSString *)filePath
25 | error:(NSError **)error;
26 |
27 | /**
28 | * 二进制数据etag
29 | *
30 | * @param data 数据
31 | *
32 | * @return etag
33 | */
34 | + (NSString *)data:(NSData *)data;
35 | @end
36 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Common/QNEtag.m:
--------------------------------------------------------------------------------
1 | //
2 | // QNEtag.m
3 | // QiniuSDK
4 | //
5 | // Created by bailong on 14/10/4.
6 | // Copyright (c) 2014年 Qiniu. All rights reserved.
7 | //
8 |
9 | #include
10 |
11 | #import "QNConfiguration.h"
12 | #import "QNEtag.h"
13 | #import "QNUrlSafeBase64.h"
14 |
15 | @implementation QNEtag
16 | + (NSString *)file:(NSString *)filePath
17 | error:(NSError **)error {
18 | @autoreleasepool {
19 | NSData *data = [NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedIfSafe error:error];
20 | if (*error != nil) {
21 | return 0;
22 | }
23 | return [QNEtag data:data];
24 | }
25 | }
26 |
27 | + (NSString *)data:(NSData *)data {
28 | if (data == nil || [data length] == 0) {
29 | return @"Fto5o-5ea0sNMlW_75VgGJCv2AcJ";
30 | }
31 | int len = (int)[data length];
32 | int count = (len + kQNBlockSize - 1) / kQNBlockSize;
33 |
34 | NSMutableData *retData = [NSMutableData dataWithLength:CC_SHA1_DIGEST_LENGTH + 1];
35 | UInt8 *ret = [retData mutableBytes];
36 |
37 | NSMutableData *blocksSha1 = nil;
38 | UInt8 *pblocksSha1 = ret + 1;
39 | if (count > 1) {
40 | blocksSha1 = [NSMutableData dataWithLength:CC_SHA1_DIGEST_LENGTH * count];
41 | pblocksSha1 = [blocksSha1 mutableBytes];
42 | }
43 |
44 | for (int i = 0; i < count; i++) {
45 | int offset = i * kQNBlockSize;
46 | int size = (len - offset) > kQNBlockSize ? kQNBlockSize : (len - offset);
47 | NSData *d = [data subdataWithRange:NSMakeRange(offset, (unsigned int)size)];
48 | CC_SHA1([d bytes], (CC_LONG)size, pblocksSha1 + i * CC_SHA1_DIGEST_LENGTH);
49 | }
50 | if (count == 1) {
51 | ret[0] = 0x16;
52 | } else {
53 | ret[0] = 0x96;
54 | CC_SHA1(pblocksSha1, (CC_LONG)CC_SHA1_DIGEST_LENGTH * count, ret + 1);
55 | }
56 |
57 | return [QNUrlSafeBase64 encodeData:retData];
58 | }
59 |
60 | @end
61 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Common/QNFile.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNFile.h
3 | // QiniuSDK
4 | //
5 | // Created by bailong on 15/7/25.
6 | // Copyright (c) 2015年 Qiniu. All rights reserved.
7 | //
8 |
9 | #import "QNFileDelegate.h"
10 | #import
11 |
12 | @interface QNFile : NSObject
13 | /**
14 | * 打开指定文件
15 | *
16 | * @param path 文件路径
17 | * @param error 输出的错误信息
18 | *
19 | * @return 实例
20 | */
21 | - (instancetype)init:(NSString *)path
22 | error:(NSError *__autoreleasing *)error;
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Common/QNFile.m:
--------------------------------------------------------------------------------
1 | //
2 | // QNFile.m
3 | // QiniuSDK
4 | //
5 | // Created by bailong on 15/7/25.
6 | // Copyright (c) 2015年 Qiniu. All rights reserved.
7 | //
8 |
9 | #import "QNFile.h"
10 | #import "QNResponseInfo.h"
11 |
12 | @interface QNFile ()
13 |
14 | @property (nonatomic, readonly) NSString *filepath;
15 |
16 | @property (nonatomic) NSData *data;
17 |
18 | @property (readonly) int64_t fileSize;
19 |
20 | @property (readonly) int64_t fileModifyTime;
21 |
22 | @property (nonatomic) NSFileHandle *file;
23 |
24 | @end
25 |
26 | @implementation QNFile
27 |
28 | - (instancetype)init:(NSString *)path
29 | error:(NSError *__autoreleasing *)error {
30 | if (self = [super init]) {
31 | _filepath = path;
32 | NSError *error2 = nil;
33 | NSDictionary *fileAttr = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:&error2];
34 | if (error2 != nil) {
35 | if (error != nil) {
36 | *error = error2;
37 | }
38 | return self;
39 | }
40 | _fileSize = [fileAttr fileSize];
41 | NSDate *modifyTime = fileAttr[NSFileModificationDate];
42 | int64_t t = 0;
43 | if (modifyTime != nil) {
44 | t = [modifyTime timeIntervalSince1970];
45 | }
46 | _fileModifyTime = t;
47 | NSFileHandle *f = nil;
48 | NSData *d = nil;
49 | //[NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedIfSafe error:&error] 不能用在大于 200M的文件上,改用filehandle
50 | // 参见 https://issues.apache.org/jira/browse/CB-5790
51 | if (_fileSize > 16 * 1024 * 1024) {
52 | f = [NSFileHandle fileHandleForReadingAtPath:path];
53 | if (f == nil) {
54 | if (error != nil) {
55 | *error = [[NSError alloc] initWithDomain:path code:kQNFileError userInfo:nil];
56 | }
57 | return self;
58 | }
59 | } else {
60 | d = [NSData dataWithContentsOfFile:path options:NSDataReadingMappedIfSafe error:&error2];
61 | if (error2 != nil) {
62 | if (error != nil) {
63 | *error = error2;
64 | }
65 | return self;
66 | }
67 | }
68 | _file = f;
69 | _data = d;
70 | }
71 |
72 | return self;
73 | }
74 |
75 | - (NSData *)read:(long)offset
76 | size:(long)size {
77 | if (_data != nil) {
78 | return [_data subdataWithRange:NSMakeRange(offset, (unsigned int)size)];
79 | }
80 | [_file seekToFileOffset:offset];
81 | return [_file readDataOfLength:size];
82 | }
83 |
84 | - (NSData *)readAll {
85 | return [self read:0 size:(long)_fileSize];
86 | }
87 |
88 | - (void)close {
89 | if (_file != nil) {
90 | [_file closeFile];
91 | }
92 | }
93 |
94 | - (NSString *)path {
95 | return _filepath;
96 | }
97 |
98 | - (int64_t)modifyTime {
99 | return _fileModifyTime;
100 | }
101 |
102 | - (int64_t)size {
103 | return _fileSize;
104 | }
105 |
106 | @end
107 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Common/QNFileDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNFileDelegate.h
3 | // QiniuSDK
4 | //
5 | // Created by bailong on 15/7/25.
6 | // Copyright (c) 2015年 Qiniu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | /**
12 | * 文件处理接口,支持ALAsset, NSFileHandle, NSData
13 | */
14 | @protocol QNFileDelegate
15 |
16 | /**
17 | * 从指定偏移读取数据
18 | *
19 | * @param offset 偏移地址
20 | * @param size 大小
21 | *
22 | * @return 数据
23 | */
24 | - (NSData *)read:(long)offset
25 | size:(long)size;
26 |
27 | /**
28 | * 读取所有文件内容
29 | *
30 | * @return 数据
31 | */
32 | - (NSData *)readAll;
33 |
34 | /**
35 | * 关闭文件
36 | *
37 | */
38 | - (void)close;
39 |
40 | /**
41 | * 文件路径
42 | *
43 | * @return 文件路径
44 | */
45 | - (NSString *)path;
46 |
47 | /**
48 | * 文件修改时间
49 | *
50 | * @return 修改时间
51 | */
52 | - (int64_t)modifyTime;
53 |
54 | /**
55 | * 文件大小
56 | *
57 | * @return 文件大小
58 | */
59 | - (int64_t)size;
60 |
61 | @end
62 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Common/QNPHAssetFile.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNPHAssetFile.h
3 | // Pods
4 | //
5 | // Created by 何舒 on 15/10/21.
6 | //
7 | //
8 |
9 | #import
10 |
11 | #import "QNFileDelegate.h"
12 |
13 | #if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000)
14 | @class PHAsset;
15 | @interface QNPHAssetFile : NSObject
16 | /**
17 | * 打开指定文件
18 | *
19 | * @param path 文件路径
20 | * @param error 输出的错误信息
21 | *
22 | * @return 实例
23 | */
24 | - (instancetype)init:(PHAsset *)phAsset
25 | error:(NSError *__autoreleasing *)error;
26 | @end
27 | #endif
28 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Common/QNPHAssetResource.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNPHAssetResource.h
3 | // QiniuSDK
4 | //
5 | // Created by 何舒 on 16/2/14.
6 | // Copyright © 2016年 Qiniu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "QNFileDelegate.h"
12 |
13 | #if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 90100)
14 |
15 | @class PHAssetResource;
16 |
17 | @interface QNPHAssetResource : NSObject
18 |
19 | /**
20 | * 打开指定文件
21 | *
22 | * @param path PHLivePhoto的PHAssetResource文件
23 | * @param error 输出的错误信息
24 | *
25 | * @return 实例
26 | */
27 | - (instancetype)init:(PHAssetResource *)phAssetResource
28 | error:(NSError *__autoreleasing *)error;
29 |
30 | @end
31 | #endif
32 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Common/QNSystem.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNSystem.h
3 | // QiniuSDK
4 | //
5 | // Created by bailong on 15/10/13.
6 | // Copyright © 2015年 Qiniu. All rights reserved.
7 | //
8 |
9 | #ifndef QNSystem_h
10 | #define QNSystem_h
11 |
12 | BOOL hasNSURLSession();
13 |
14 | BOOL hasAts();
15 |
16 | BOOL allowsArbitraryLoads();
17 |
18 | BOOL isIpV6FullySupported();
19 |
20 | #endif /* QNSystem_h */
21 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Common/QNSystem.m:
--------------------------------------------------------------------------------
1 | //
2 | // QNSystem.m
3 | // QiniuSDK
4 | //
5 | // Created by bailong on 15/10/13.
6 | // Copyright © 2015年 Qiniu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #if __IPHONE_OS_VERSION_MIN_REQUIRED
12 | #import
13 | #import
14 | #else
15 | #import
16 | #endif
17 |
18 | BOOL hasNSURLSession() {
19 | #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED)
20 | float sysVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
21 | if (sysVersion < 7.0) {
22 | return NO;
23 | }
24 | #else
25 | NSOperatingSystemVersion sysVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
26 | if (sysVersion.majorVersion < 10) {
27 | return NO;
28 | } else if (sysVersion.majorVersion == 10) {
29 | return sysVersion.minorVersion >= 9;
30 | }
31 | #endif
32 | return YES;
33 | }
34 |
35 | BOOL hasAts() {
36 | #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED)
37 | float sysVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
38 | if (sysVersion < 9.0) {
39 | return NO;
40 | }
41 | #else
42 | NSOperatingSystemVersion sysVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
43 | if (sysVersion.majorVersion < 10) {
44 | return NO;
45 | } else if (sysVersion.majorVersion == 10) {
46 | return sysVersion.minorVersion >= 11;
47 | }
48 | #endif
49 | return YES;
50 | }
51 |
52 | BOOL allowsArbitraryLoads() {
53 | if (!hasAts()) {
54 | return YES;
55 | }
56 |
57 | // for unit test
58 | NSDictionary* d = [[NSBundle mainBundle] infoDictionary];
59 | if (d == nil || d.count == 0) {
60 | return YES;
61 | }
62 |
63 | NSDictionary* sec = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSAppTransportSecurity"];
64 | if (sec == nil) {
65 | return NO;
66 | }
67 | NSNumber* ats = [sec objectForKey:@"NSAllowsArbitraryLoads"];
68 | if (ats == nil) {
69 | return NO;
70 | }
71 | return ats.boolValue;
72 | }
73 |
74 | BOOL isIpV6FullySupported() {
75 | #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED)
76 | float sysVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
77 | if (sysVersion < 9.0) {
78 | return NO;
79 | }
80 | #else
81 | NSOperatingSystemVersion sysVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
82 | if (sysVersion.majorVersion < 10) {
83 | return NO;
84 | } else if (sysVersion.majorVersion == 10) {
85 | return sysVersion.minorVersion >= 11;
86 | }
87 | #endif
88 | return YES;
89 | }
90 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Common/QNUrlSafeBase64.h:
--------------------------------------------------------------------------------
1 | //
2 | // QiniuSDK
3 | //
4 | // Created by bailong on 14-9-28.
5 | // Copyright (c) 2014年 Qiniu. All rights reserved.
6 | //
7 |
8 | #import
9 |
10 | /**
11 | * url safe base64 编码类, 对/ 做了处理
12 | */
13 | @interface QNUrlSafeBase64 : NSObject
14 |
15 | /**
16 | * 字符串编码
17 | *
18 | * @param source 字符串
19 | *
20 | * @return base64 字符串
21 | */
22 | + (NSString *)encodeString:(NSString *)source;
23 |
24 | /**
25 | * 二进制数据编码
26 | *
27 | * @param source 二进制数据
28 | *
29 | * @return base64字符串
30 | */
31 | + (NSString *)encodeData:(NSData *)source;
32 |
33 | /**
34 | * 字符串解码
35 | *
36 | * @param base64 字符串
37 | *
38 | * @return 数据
39 | */
40 | + (NSData *)decodeString:(NSString *)data;
41 | @end
42 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Common/QNUrlSafeBase64.m:
--------------------------------------------------------------------------------
1 | //
2 | // QiniuSDK
3 | //
4 | // Created by bailong on 14-9-28.
5 | // Copyright (c) 2014年 Qiniu. All rights reserved.
6 | //
7 |
8 | #import
9 |
10 | #import "QNUrlSafeBase64.h"
11 |
12 | #import "QN_GTM_Base64.h"
13 |
14 | @implementation QNUrlSafeBase64
15 |
16 | + (NSString *)encodeString:(NSString *)sourceString {
17 | NSData *data = [NSData dataWithBytes:[sourceString UTF8String] length:[sourceString lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];
18 | return [self encodeData:data];
19 | }
20 |
21 | + (NSString *)encodeData:(NSData *)data {
22 | return [QN_GTM_Base64 stringByWebSafeEncodingData:data padded:YES];
23 | }
24 |
25 | + (NSData *)decodeString:(NSString *)data {
26 | return [QN_GTM_Base64 webSafeDecodeString:data];
27 | }
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Common/QNVersion.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNVersion.h
3 | // QiniuSDK
4 | //
5 | // Created by bailong on 14-9-29.
6 | // Copyright (c) 2014年 Qiniu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | /**
12 | * sdk 版本
13 | */
14 | static const NSString *kQiniuVersion = @"7.1.0";
15 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Http/QNHttpDelegate.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | @class QNResponseInfo;
4 |
5 | typedef void (^QNInternalProgressBlock)(long long totalBytesWritten, long long totalBytesExpectedToWrite);
6 | typedef void (^QNCompleteBlock)(QNResponseInfo *info, NSDictionary *resp);
7 | typedef BOOL (^QNCancelBlock)(void);
8 |
9 | /**
10 | * Http 客户端接口
11 | */
12 | @protocol QNHttpDelegate
13 |
14 | - (void)multipartPost:(NSString *)url
15 | withData:(NSData *)data
16 | withParams:(NSDictionary *)params
17 | withFileName:(NSString *)key
18 | withMimeType:(NSString *)mime
19 | withCompleteBlock:(QNCompleteBlock)completeBlock
20 | withProgressBlock:(QNInternalProgressBlock)progressBlock
21 | withCancelBlock:(QNCancelBlock)cancelBlock;
22 |
23 | - (void)post:(NSString *)url
24 | withData:(NSData *)data
25 | withParams:(NSDictionary *)params
26 | withHeaders:(NSDictionary *)headers
27 | withCompleteBlock:(QNCompleteBlock)completeBlock
28 | withProgressBlock:(QNInternalProgressBlock)progressBlock
29 | withCancelBlock:(QNCancelBlock)cancelBlock;
30 |
31 | @end
32 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Http/QNResponseInfo.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNResponseInfo.h
3 | // QiniuSDK
4 | //
5 | // Created by bailong on 14/10/2.
6 | // Copyright (c) 2014年 Qiniu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | /**
12 | * 中途取消的状态码
13 | */
14 | extern const int kQNRequestCancelled;
15 |
16 | /**
17 | * 网络错误状态码
18 | */
19 | extern const int kQNNetworkError;
20 |
21 | /**
22 | * 错误参数状态码
23 | */
24 | extern const int kQNInvalidArgument;
25 |
26 | /**
27 | * 0 字节文件或数据
28 | */
29 | extern const int kQNZeroDataSize;
30 |
31 | /**
32 | * 错误token状态码
33 | */
34 | extern const int kQNInvalidToken;
35 |
36 | /**
37 | * 读取文件错误状态码
38 | */
39 | extern const int kQNFileError;
40 |
41 | /**
42 | * 上传完成后返回的状态信息
43 | */
44 | @interface QNResponseInfo : NSObject
45 |
46 | /**
47 | * 状态码
48 | */
49 | @property (readonly) int statusCode;
50 |
51 | /**
52 | * 七牛服务器生成的请求ID,用来跟踪请求信息,如果使用过程中出现问题,请反馈此ID
53 | */
54 | @property (nonatomic, copy, readonly) NSString *reqId;
55 |
56 | /**
57 | * 七牛服务器内部跟踪记录
58 | */
59 | @property (nonatomic, copy, readonly) NSString *xlog;
60 |
61 | /**
62 | * cdn服务器内部跟踪记录
63 | */
64 | @property (nonatomic, copy, readonly) NSString *xvia;
65 |
66 | /**
67 | * 错误信息,出错时请反馈此记录
68 | */
69 | @property (nonatomic, copy, readonly) NSError *error;
70 |
71 | /**
72 | * 服务器域名
73 | */
74 | @property (nonatomic, copy, readonly) NSString *host;
75 |
76 | /**
77 | * 请求消耗的时间,单位 秒
78 | */
79 | @property (nonatomic, readonly) double duration;
80 |
81 | /**
82 | * 服务器IP
83 | */
84 | @property (nonatomic, readonly) NSString *serverIp;
85 |
86 | /**
87 | * 客户端id
88 | */
89 | @property (nonatomic, readonly) NSString *id;
90 |
91 | /**
92 | * 时间戳
93 | */
94 | @property (readonly) UInt64 timeStamp;
95 |
96 | /**
97 | * 网络类型
98 | */
99 | //@property (nonatomic, readonly) NSString *networkType;
100 |
101 | /**
102 | * 是否取消
103 | */
104 | @property (nonatomic, readonly, getter=isCancelled) BOOL canceled;
105 |
106 | /**
107 | * 成功的请求
108 | */
109 | @property (nonatomic, readonly, getter=isOK) BOOL ok;
110 |
111 | /**
112 | * 是否网络错误
113 | */
114 | @property (nonatomic, readonly, getter=isConnectionBroken) BOOL broken;
115 |
116 | /**
117 | * 是否需要重试,内部使用
118 | */
119 | @property (nonatomic, readonly) BOOL couldRetry;
120 |
121 | /**
122 | * 是否需要换备用server,内部使用
123 | */
124 | @property (nonatomic, readonly) BOOL needSwitchServer;
125 |
126 | /**
127 | * 是否为 七牛响应
128 | */
129 | @property (nonatomic, readonly, getter=isNotQiniu) BOOL notQiniu;
130 |
131 | /**
132 | * 工厂函数,内部使用
133 | *
134 | * @return 取消的实例
135 | */
136 | + (instancetype)cancel;
137 |
138 | /**
139 | * 工厂函数,内部使用
140 | *
141 | * @param desc 错误参数描述
142 | *
143 | * @return 错误参数实例
144 | */
145 | + (instancetype)responseInfoWithInvalidArgument:(NSString *)desc;
146 |
147 | /**
148 | * 工厂函数,内部使用
149 | *
150 | * @param desc 错误token描述
151 | *
152 | * @return 错误token实例
153 | */
154 | + (instancetype)responseInfoWithInvalidToken:(NSString *)desc;
155 |
156 | /**
157 | * 工厂函数,内部使用
158 | *
159 | * @param error 错误信息
160 | * @param host 服务器域名
161 | * @param duration 请求完成时间,单位秒
162 | *
163 | * @return 网络错误实例
164 | */
165 | + (instancetype)responseInfoWithNetError:(NSError *)error
166 | host:(NSString *)host
167 | duration:(double)duration;
168 |
169 | /**
170 | * 工厂函数,内部使用
171 | *
172 | * @param error 错误信息
173 | *
174 | * @return 文件错误实例
175 | */
176 | + (instancetype)responseInfoWithFileError:(NSError *)error;
177 |
178 | /**
179 | * 工厂函数,内部使用
180 | *
181 | * @return 文件错误实例
182 | */
183 | + (instancetype)responseInfoOfZeroData:(NSString *)path;
184 |
185 | /**
186 | * 构造函数
187 | *
188 | * @param status 状态码
189 | * @param reqId 七牛服务器请求id
190 | * @param xlog 七牛服务器记录
191 | * @param body 服务器返回内容
192 | * @param host 服务器域名
193 | * @param duration 请求完成时间,单位秒
194 | *
195 | * @return 实例
196 | */
197 | - (instancetype)init:(int)status
198 | withReqId:(NSString *)reqId
199 | withXLog:(NSString *)xlog
200 | withXVia:(NSString *)xvia
201 | withHost:(NSString *)host
202 | withIp:(NSString *)ip
203 | withDuration:(double)duration
204 | withBody:(NSData *)body;
205 |
206 | @end
207 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Http/QNSessionManager.h:
--------------------------------------------------------------------------------
1 | #import "QNHttpDelegate.h"
2 | #import
3 |
4 | #import "QNConfiguration.h"
5 |
6 | #if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000) || (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1090)
7 |
8 | @interface QNSessionManager : NSObject
9 |
10 | - (instancetype)initWithProxy:(NSDictionary *)proxyDict
11 | timeout:(UInt32)timeout
12 | urlConverter:(QNUrlConvert)converter
13 | dns:(QNDnsManager *)dns;
14 |
15 | - (void)multipartPost:(NSString *)url
16 | withData:(NSData *)data
17 | withParams:(NSDictionary *)params
18 | withFileName:(NSString *)key
19 | withMimeType:(NSString *)mime
20 | withCompleteBlock:(QNCompleteBlock)completeBlock
21 | withProgressBlock:(QNInternalProgressBlock)progressBlock
22 | withCancelBlock:(QNCancelBlock)cancelBlock;
23 |
24 | - (void)post:(NSString *)url
25 | withData:(NSData *)data
26 | withParams:(NSDictionary *)params
27 | withHeaders:(NSDictionary *)headers
28 | withCompleteBlock:(QNCompleteBlock)completeBlock
29 | withProgressBlock:(QNInternalProgressBlock)progressBlock
30 | withCancelBlock:(QNCancelBlock)cancelBlock;
31 |
32 | @end
33 |
34 | #endif
35 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Http/QNUserAgent.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNUserAgent.h
3 | // QiniuSDK
4 | //
5 | // Created by bailong on 14-9-29.
6 | // Copyright (c) 2014年 Qiniu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | /**
12 | * UserAgent
13 | *
14 | */
15 |
16 | @interface QNUserAgent : NSObject
17 |
18 | /**
19 | * 用户id
20 | */
21 | @property (copy, nonatomic, readonly) NSString *id;
22 |
23 | /**
24 | * UserAgent 字串
25 | */
26 | - (NSString *)description;
27 |
28 | /**
29 | * 单例
30 | */
31 | + (instancetype)sharedInstance;
32 | @end
33 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Http/QNUserAgent.m:
--------------------------------------------------------------------------------
1 | //
2 | // QNUserAgent.m
3 | // QiniuSDK
4 | //
5 | // Created by bailong on 14-9-29.
6 | // Copyright (c) 2014年 Qiniu. All rights reserved.
7 | //
8 |
9 | #import
10 | #if __IPHONE_OS_VERSION_MIN_REQUIRED
11 | #import
12 | #import
13 | #else
14 | #import
15 | #endif
16 |
17 | #import "QNUserAgent.h"
18 | #import "QNVersion.h"
19 |
20 | static NSString *clientId(void) {
21 | #if __IPHONE_OS_VERSION_MIN_REQUIRED
22 | NSString *s = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
23 | if (s == nil) {
24 | s = @"simulator";
25 | }
26 | return s;
27 | #else
28 | long long now_timestamp = [[NSDate date] timeIntervalSince1970] * 1000;
29 | int r = arc4random() % 1000;
30 | return [NSString stringWithFormat:@"%lld%u", now_timestamp, r];
31 | #endif
32 | }
33 |
34 | static NSString *userAgent(NSString *id) {
35 | #if __IPHONE_OS_VERSION_MIN_REQUIRED
36 | return [NSString stringWithFormat:@"QiniuObject-C/%@ (%@; iOS %@; %@)", kQiniuVersion, [[UIDevice currentDevice] model], [[UIDevice currentDevice] systemVersion], id];
37 | #else
38 | return [NSString stringWithFormat:@"QiniuObject-C/%@ (Mac OS X %@; %@)", kQiniuVersion, [[NSProcessInfo processInfo] operatingSystemVersionString], id];
39 | #endif
40 | }
41 |
42 | @interface QNUserAgent ()
43 | @property (nonatomic) NSString *ua;
44 | @end
45 |
46 | @implementation QNUserAgent
47 |
48 | - (NSString *)description {
49 | return _ua;
50 | }
51 |
52 | - (instancetype)init {
53 | if (self = [super init]) {
54 | _id = clientId();
55 | _ua = userAgent(_id);
56 | }
57 | return self;
58 | }
59 |
60 | /**
61 | * 单例
62 | */
63 | + (instancetype)sharedInstance {
64 | static QNUserAgent *sharedInstance = nil;
65 |
66 | static dispatch_once_t onceToken;
67 | dispatch_once(&onceToken, ^{
68 | sharedInstance = [[self alloc] init];
69 | });
70 |
71 | return sharedInstance;
72 | }
73 |
74 | @end
75 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/QiniuSDK.h:
--------------------------------------------------------------------------------
1 | //
2 | // QiniuSDK.h
3 | // QiniuSDK
4 | //
5 | // Created by bailong on 14-9-28.
6 | // Copyright (c) 2014年 Qiniu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "QNConfiguration.h"
12 | #import "QNFileRecorder.h"
13 | #import "QNResponseInfo.h"
14 | #import "QNUploadManager.h"
15 | #import "QNUploadOption.h"
16 | #import "QNUrlSafeBase64.h"
17 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Recorder/QNFileRecorder.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNFileRecorder.h
3 | // QiniuSDK
4 | //
5 | // Created by bailong on 14/10/5.
6 | // Copyright (c) 2014年 Qiniu. All rights reserved.
7 | //
8 |
9 | #import "QNRecorderDelegate.h"
10 | #import
11 |
12 | /**
13 | * 将上传记录保存到文件系统中
14 | */
15 | @interface QNFileRecorder : NSObject
16 |
17 | /**
18 | * 用指定保存的目录进行初始化
19 | *
20 | * @param directory 目录
21 | * @param error 输出的错误信息
22 | *
23 | * @return 实例
24 | */
25 | + (instancetype)fileRecorderWithFolder:(NSString *)directory
26 | error:(NSError *__autoreleasing *)error;
27 |
28 | /**
29 | * 用指定保存的目录,以及是否进行base64编码进行初始化,
30 | *
31 | * @param directory 目录
32 | * @param encode 为避免因为特殊字符或含有/,无法保存持久化记录,故用此参数指定是否要base64编码
33 | * @param error 输出错误信息
34 | *
35 | * @return 实例
36 | */
37 | + (instancetype)fileRecorderWithFolder:(NSString *)directory
38 | encodeKey:(BOOL)encode
39 | error:(NSError *__autoreleasing *)error;
40 |
41 | /**
42 | * 从外部手动删除记录,如无特殊需求,不建议使用
43 | *
44 | * @param key 持久化记录key
45 | * @param dir 目录
46 | * @param encode 是否encode
47 | */
48 | + (void)removeKey:(NSString *)key
49 | directory:(NSString *)dir
50 | encodeKey:(BOOL)encode;
51 |
52 | @end
53 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Recorder/QNFileRecorder.m:
--------------------------------------------------------------------------------
1 | //
2 | // QNFileRecorder.m
3 | // QiniuSDK
4 | //
5 | // Created by bailong on 14/10/5.
6 | // Copyright (c) 2014年 Qiniu. All rights reserved.
7 | //
8 |
9 | #import "QNFileRecorder.h"
10 | #import "QNUrlSafeBase64.h"
11 |
12 | @interface QNFileRecorder ()
13 |
14 | @property (copy, readonly) NSString *directory;
15 | @property BOOL encode;
16 |
17 | @end
18 |
19 | @implementation QNFileRecorder
20 |
21 | - (NSString *)pathOfKey:(NSString *)key {
22 | return [QNFileRecorder pathJoin:key path:_directory];
23 | }
24 |
25 | + (NSString *)pathJoin:(NSString *)key
26 | path:(NSString *)path {
27 | return [[NSString alloc] initWithFormat:@"%@/%@", path, key];
28 | }
29 |
30 | + (instancetype)fileRecorderWithFolder:(NSString *)directory
31 | error:(NSError *__autoreleasing *)perror {
32 | return [QNFileRecorder fileRecorderWithFolder:directory encodeKey:false error:perror];
33 | }
34 |
35 | + (instancetype)fileRecorderWithFolder:(NSString *)directory
36 | encodeKey:(BOOL)encode
37 | error:(NSError *__autoreleasing *)perror {
38 | NSError *error;
39 | [[NSFileManager defaultManager] createDirectoryAtPath:directory withIntermediateDirectories:YES attributes:nil error:&error];
40 | if (error != nil) {
41 | if (perror) {
42 | *perror = error;
43 | }
44 | return nil;
45 | }
46 |
47 | return [[QNFileRecorder alloc] initWithFolder:directory encodeKey:encode];
48 | }
49 |
50 | - (instancetype)initWithFolder:(NSString *)directory encodeKey:(BOOL)encode {
51 | if (self = [super init]) {
52 | _directory = directory;
53 | _encode = encode;
54 | }
55 | return self;
56 | }
57 |
58 | - (NSError *)set:(NSString *)key
59 | data:(NSData *)value {
60 | NSError *error;
61 | if (_encode) {
62 | key = [QNUrlSafeBase64 encodeString:key];
63 | }
64 | [value writeToFile:[self pathOfKey:key] options:NSDataWritingAtomic error:&error];
65 | return error;
66 | }
67 |
68 | - (NSData *)get:(NSString *)key {
69 | if (_encode) {
70 | key = [QNUrlSafeBase64 encodeString:key];
71 | }
72 | return [NSData dataWithContentsOfFile:[self pathOfKey:key]];
73 | }
74 |
75 | - (NSError *)del:(NSString *)key {
76 | NSError *error;
77 | if (_encode) {
78 | key = [QNUrlSafeBase64 encodeString:key];
79 | }
80 | [[NSFileManager defaultManager] removeItemAtPath:[self pathOfKey:key] error:&error];
81 | return error;
82 | }
83 |
84 | + (void)removeKey:(NSString *)key
85 | directory:(NSString *)dir
86 | encodeKey:(BOOL)encode {
87 | if (encode) {
88 | key = [QNUrlSafeBase64 encodeString:key];
89 | }
90 | NSError *error;
91 | NSString *path = [QNFileRecorder pathJoin:key path:dir];
92 | [[NSFileManager defaultManager] removeItemAtPath:path error:&error];
93 | }
94 |
95 | - (NSString *)description {
96 | return [NSString stringWithFormat:@"<%@: %p, dir: %@>", NSStringFromClass([self class]), self, _directory];
97 | }
98 |
99 | @end
100 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Recorder/QNRecorderDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNRecorderDelegate.h
3 | // QiniuSDK
4 | //
5 | // Created by bailong on 14/10/5.
6 | // Copyright (c) 2014年 Qiniu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | /**
12 | * 为持久化上传记录,根据上传的key以及文件名 生成持久化的记录key
13 | *
14 | * @param uploadKey 上传的key
15 | * @param filePath 文件名
16 | *
17 | * @return 根据uploadKey, filepath 算出的记录key
18 | */
19 | typedef NSString * (^QNRecorderKeyGenerator)(NSString *uploadKey, NSString *filePath);
20 |
21 | /**
22 | * 持久化记录接口,可以实现将记录持久化到文件,数据库等
23 | */
24 | @protocol QNRecorderDelegate
25 |
26 | /**
27 | * 保存记录
28 | *
29 | * @param key 持久化记录的key
30 | * @param value 持久化记录上传状态信息
31 | *
32 | * @return 错误信息,成功为nil
33 | */
34 | - (NSError *)set:(NSString *)key
35 | data:(NSData *)value;
36 |
37 | /**
38 | * 取出保存的持久化上传状态信息
39 | *
40 | * @param key 持久化记录key
41 | *
42 | * @return 上传中间状态信息
43 | */
44 | - (NSData *)get:(NSString *)key;
45 |
46 | /**
47 | * 删除持久化记录,一般在上传成功后自动调用
48 | *
49 | * @param key 持久化记录key
50 | *
51 | * @return 错误信息,成功为nil
52 | */
53 | - (NSError *)del:(NSString *)key;
54 |
55 | @end
56 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Storage/QNConfiguration.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNConfiguration.h
3 | // QiniuSDK
4 | //
5 | // Created by bailong on 15/5/21.
6 | // Copyright (c) 2015年 Qiniu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "QNRecorderDelegate.h"
12 |
13 | /**
14 | * 断点上传时的分块大小
15 | */
16 | extern const UInt32 kQNBlockSize;
17 |
18 | /**
19 | * 转换为用户需要的url
20 | *
21 | * @param url 上传url
22 | *
23 | * @return 根据上传url算出代理url
24 | */
25 | typedef NSString * (^QNUrlConvert)(NSString *url);
26 |
27 | @class QNConfigurationBuilder;
28 | @class QNDnsManager;
29 | @class QNServiceAddress;
30 | /**
31 | * Builder block
32 | *
33 | * @param builder builder实例
34 | */
35 | typedef void (^QNConfigurationBuilderBlock)(QNConfigurationBuilder *builder);
36 |
37 | @interface QNConfiguration : NSObject
38 |
39 | /**
40 | * 默认上传服务器地址
41 | */
42 | @property (copy, nonatomic, readonly) QNServiceAddress *up;
43 |
44 | /**
45 | * 备用上传服务器地址
46 | */
47 | @property (copy, nonatomic, readonly) QNServiceAddress *upBackup;
48 |
49 | /**
50 | * 断点上传时的分片大小
51 | */
52 | @property (readonly) UInt32 chunkSize;
53 |
54 | /**
55 | * 如果大于此值就使用断点上传,否则使用form上传
56 | */
57 | @property (readonly) UInt32 putThreshold;
58 |
59 | /**
60 | * 上传失败的重试次数
61 | */
62 | @property (readonly) UInt32 retryMax;
63 |
64 | /**
65 | * 超时时间 单位 秒
66 | */
67 | @property (readonly) UInt32 timeoutInterval;
68 |
69 | @property (nonatomic, readonly) id recorder;
70 |
71 | @property (nonatomic, readonly) QNRecorderKeyGenerator recorderKeyGen;
72 |
73 | @property (nonatomic, readonly) NSDictionary *proxy;
74 |
75 | @property (nonatomic, readonly) QNUrlConvert converter;
76 |
77 | @property (nonatomic, readonly) QNDnsManager *dns;
78 |
79 | @property (readonly) BOOL disableATS;
80 |
81 | + (instancetype)build:(QNConfigurationBuilderBlock)block;
82 |
83 | @end
84 |
85 | /**
86 | * 上传服务地址
87 | */
88 | @interface QNServiceAddress : NSObject
89 |
90 | - (instancetype)init:(NSString *)address ips:(NSArray *)ips;
91 |
92 | @property (nonatomic, readonly) NSString *address;
93 | @property (nonatomic, readonly) NSArray *ips;
94 |
95 | @end
96 |
97 | @interface QNZone : NSObject
98 |
99 | /**
100 | * 默认上传服务器地址
101 | */
102 | @property (nonatomic, readonly) QNServiceAddress *up;
103 |
104 | /**
105 | * 备用上传服务器地址
106 | */
107 | @property (nonatomic, readonly) QNServiceAddress *upBackup;
108 |
109 | /**
110 | * Zone初始化方法
111 | *
112 | * @param upHost 默认上传服务器地址
113 | * @param upHostBackup 备用上传服务器地址
114 | * @param upIp 备用上传IP
115 | *
116 | * @return Zone实例
117 | */
118 | - (instancetype)initWithUp:(QNServiceAddress *)up
119 | upBackup:(QNServiceAddress *)upBackup;
120 |
121 | /**
122 | * zone 0
123 | *
124 | * @return 实例
125 | */
126 | + (instancetype)zone0;
127 |
128 | /**
129 | * zone 1
130 | *
131 | * @return 实例
132 | */
133 | + (instancetype)zone1;
134 |
135 | @end
136 |
137 | @interface QNConfigurationBuilder : NSObject
138 |
139 | /**
140 | * 默认上传服务器地址
141 | */
142 | @property (nonatomic, strong) QNZone *zone;
143 |
144 | /**
145 | * 断点上传时的分片大小
146 | */
147 | @property (assign) UInt32 chunkSize;
148 |
149 | /**
150 | * 如果大于此值就使用断点上传,否则使用form上传
151 | */
152 | @property (assign) UInt32 putThreshold;
153 |
154 | /**
155 | * 上传失败的重试次数
156 | */
157 | @property (assign) UInt32 retryMax;
158 |
159 | /**
160 | * 超时时间 单位 秒
161 | */
162 | @property (assign) UInt32 timeoutInterval;
163 |
164 | @property (nonatomic, strong) id recorder;
165 |
166 | @property (nonatomic, strong) QNRecorderKeyGenerator recorderKeyGen;
167 |
168 | @property (nonatomic, strong) NSDictionary *proxy;
169 |
170 | @property (nonatomic, strong) QNUrlConvert converter;
171 |
172 | @property (nonatomic, strong) QNDnsManager *dns;
173 |
174 | @property (assign) BOOL disableATS;
175 |
176 | @end
177 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Storage/QNFormUpload.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNFormUpload.h
3 | // QiniuSDK
4 | //
5 | // Created by bailong on 15/1/4.
6 | // Copyright (c) 2015年 Qiniu. All rights reserved.
7 | //
8 |
9 | #import "QNHttpDelegate.h"
10 | #import "QNUpToken.h"
11 | #import "QNUploadManager.h"
12 | #import
13 |
14 | @interface QNFormUpload : NSObject
15 |
16 | - (instancetype)initWithData:(NSData *)data
17 | withKey:(NSString *)key
18 | withToken:(QNUpToken *)token
19 | withCompletionHandler:(QNUpCompletionHandler)block
20 | withOption:(QNUploadOption *)option
21 | withHttpManager:(id)http
22 | withConfiguration:(QNConfiguration *)config;
23 |
24 | - (void)put;
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Storage/QNFormUpload.m:
--------------------------------------------------------------------------------
1 | //
2 | // QNFormUpload.m
3 | // QiniuSDK
4 | //
5 | // Created by bailong on 15/1/4.
6 | // Copyright (c) 2015年 Qiniu. All rights reserved.
7 | //
8 |
9 | #import "QNFormUpload.h"
10 | #import "QNConfiguration.h"
11 | #import "QNCrc32.h"
12 | #import "QNRecorderDelegate.h"
13 | #import "QNResponseInfo.h"
14 | #import "QNUploadManager.h"
15 | #import "QNUploadOption+Private.h"
16 | #import "QNUrlSafeBase64.h"
17 |
18 | @interface QNFormUpload ()
19 |
20 | @property (nonatomic, strong) NSData *data;
21 | @property (nonatomic, strong) id httpManager;
22 | @property (nonatomic) int retryTimes;
23 | @property (nonatomic, strong) NSString *key;
24 | @property (nonatomic, strong) QNUpToken *token;
25 | @property (nonatomic, strong) QNUploadOption *option;
26 | @property (nonatomic, strong) QNUpCompletionHandler complete;
27 | @property (nonatomic, strong) QNConfiguration *config;
28 | @property (nonatomic) float previousPercent;
29 |
30 | @end
31 |
32 | @implementation QNFormUpload
33 |
34 | - (instancetype)initWithData:(NSData *)data
35 | withKey:(NSString *)key
36 | withToken:(QNUpToken *)token
37 | withCompletionHandler:(QNUpCompletionHandler)block
38 | withOption:(QNUploadOption *)option
39 | withHttpManager:(id)http
40 | withConfiguration:(QNConfiguration *)config {
41 | if (self = [super init]) {
42 | _data = data;
43 | _key = key;
44 | _token = token;
45 | _option = option != nil ? option : [QNUploadOption defaultOptions];
46 | _complete = block;
47 | _httpManager = http;
48 | _config = config;
49 | _previousPercent = 0;
50 | }
51 | return self;
52 | }
53 |
54 | - (void)put {
55 | NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
56 | NSString *fileName = _key;
57 | if (_key) {
58 | parameters[@"key"] = _key;
59 | } else {
60 | fileName = @"?";
61 | }
62 |
63 | parameters[@"token"] = _token.token;
64 |
65 | [parameters addEntriesFromDictionary:_option.params];
66 |
67 | if (_option.checkCrc) {
68 | parameters[@"crc32"] = [NSString stringWithFormat:@"%u", (unsigned int)[QNCrc32 data:_data]];
69 | }
70 |
71 | QNInternalProgressBlock p = ^(long long totalBytesWritten, long long totalBytesExpectedToWrite) {
72 | float percent = (float)totalBytesWritten / (float)totalBytesExpectedToWrite;
73 | if (percent > 0.95) {
74 | percent = 0.95;
75 | }
76 | if (percent > _previousPercent) {
77 | _previousPercent = percent;
78 | } else {
79 | percent = _previousPercent;
80 | }
81 | _option.progressHandler(_key, percent);
82 | };
83 |
84 | QNCompleteBlock complete = ^(QNResponseInfo *info, NSDictionary *resp) {
85 | if (info.isOK) {
86 | _option.progressHandler(_key, 1.0);
87 | }
88 | if (info.isOK || !info.couldRetry) {
89 | _complete(info, _key, resp);
90 | return;
91 | }
92 | if (_option.cancellationSignal()) {
93 | _complete([QNResponseInfo cancel], _key, nil);
94 | return;
95 | }
96 | NSString *nextHost = _config.up.address;
97 | if (info.isConnectionBroken || info.needSwitchServer) {
98 | nextHost = _config.upBackup.address;
99 | }
100 |
101 | QNCompleteBlock retriedComplete = ^(QNResponseInfo *info, NSDictionary *resp) {
102 | if (info.isOK) {
103 | _option.progressHandler(_key, 1.0);
104 | }
105 | _complete(info, _key, resp);
106 | };
107 |
108 | [_httpManager multipartPost:nextHost
109 | withData:_data
110 | withParams:parameters
111 | withFileName:fileName
112 | withMimeType:_option.mimeType
113 | withCompleteBlock:retriedComplete
114 | withProgressBlock:p
115 | withCancelBlock:_option.cancellationSignal];
116 | };
117 |
118 | [_httpManager multipartPost:_config.up.address
119 | withData:_data
120 | withParams:parameters
121 | withFileName:fileName
122 | withMimeType:_option.mimeType
123 | withCompleteBlock:complete
124 | withProgressBlock:p
125 | withCancelBlock:_option.cancellationSignal];
126 | }
127 |
128 | @end
129 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Storage/QNResumeUpload.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNResumeUpload.h
3 | // QiniuSDK
4 | //
5 | // Created by bailong on 14/10/1.
6 | // Copyright (c) 2014年 Qiniu. All rights reserved.
7 | //
8 |
9 | #import "QNFileDelegate.h"
10 | #import "QNHttpDelegate.h"
11 | #import "QNUpToken.h"
12 | #import "QNUploadManager.h"
13 | #import
14 |
15 | @interface QNResumeUpload : NSObject
16 |
17 | - (instancetype)initWithFile:(id)file
18 | withKey:(NSString *)key
19 | withToken:(QNUpToken *)token
20 | withCompletionHandler:(QNUpCompletionHandler)block
21 | withOption:(QNUploadOption *)option
22 | withRecorder:(id)recorder
23 | withRecorderKey:(NSString *)recorderKey
24 | withHttpManager:(id)http
25 | withConfiguration:(QNConfiguration *)config;
26 |
27 | - (void)run;
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Storage/QNUpToken.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNUpToken.h
3 | // QiniuSDK
4 | //
5 | // Created by bailong on 15/6/7.
6 | // Copyright (c) 2015年 Qiniu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface QNUpToken : NSObject
12 |
13 | + (instancetype)parse:(NSString *)token;
14 |
15 | @property (copy, nonatomic, readonly) NSString *access;
16 | @property (copy, nonatomic, readonly) NSString *bucket;
17 | @property (copy, nonatomic, readonly) NSString *token;
18 |
19 | @property (readonly) BOOL hasReturnUrl;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Storage/QNUpToken.m:
--------------------------------------------------------------------------------
1 | //
2 | // QNUpToken.m
3 | // QiniuSDK
4 | //
5 | // Created by bailong on 15/6/7.
6 | // Copyright (c) 2015年 Qiniu. All rights reserved.
7 | //
8 |
9 | #import "QNUrlSafeBase64.h"
10 | #import "QNUpToken.h"
11 |
12 | @interface QNUpToken ()
13 |
14 | - (instancetype)init:(NSDictionary *)policy token:(NSString *)token;
15 |
16 | @end
17 |
18 | @implementation QNUpToken
19 |
20 | - (instancetype)init:(NSDictionary *)policy token:(NSString *)token {
21 | if (self = [super init]) {
22 | _token = token;
23 | _access = [self getAccess];
24 | _bucket = [self getBucket:policy];
25 | _hasReturnUrl = (policy[@"returnUrl"] != nil);
26 | }
27 |
28 | return self;
29 | }
30 |
31 | - (NSString *)getAccess {
32 |
33 | NSRange range = [_token rangeOfString:@":" options:NSCaseInsensitiveSearch];
34 | return [_token substringToIndex:range.location];
35 | }
36 |
37 | - (NSString *)getBucket:(NSDictionary *)info {
38 |
39 | NSString *scope = [info objectForKey:@"scope"];
40 | if (!scope) {
41 | return @"";
42 | }
43 |
44 | NSRange range = [scope rangeOfString:@":"];
45 | if (range.location == NSNotFound) {
46 | return scope;
47 | }
48 | return [scope substringToIndex:range.location];
49 | }
50 |
51 | + (instancetype)parse:(NSString *)token {
52 | if (token == nil) {
53 | return nil;
54 | }
55 | NSArray *array = [token componentsSeparatedByString:@":"];
56 | if (array == nil || array.count != 3) {
57 | return nil;
58 | }
59 |
60 | NSData *data = [QNUrlSafeBase64 decodeString:array[2]];
61 | NSError *tmp = nil;
62 | NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&tmp];
63 | if (tmp != nil || dict[@"scope"] == nil || dict[@"deadline"] == nil) {
64 | return nil;
65 | }
66 | return [[QNUpToken alloc] init:dict token:token];
67 | }
68 |
69 | @end
70 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Storage/QNUploadOption+Private.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNUploadOption+Private.h
3 | // QiniuSDK
4 | //
5 | // Created by bailong on 14/10/5.
6 | // Copyright (c) 2014年 Qiniu. All rights reserved.
7 | //
8 |
9 | #import "QNUploadOption.h"
10 |
11 | @interface QNUploadOption (Private)
12 |
13 | @property (nonatomic, getter=priv_isCancelled, readonly) BOOL cancelled;
14 | @end
15 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Storage/QNUploadOption.h:
--------------------------------------------------------------------------------
1 | //
2 | // QNUploadOption.h
3 | // QiniuSDK
4 | //
5 | // Created by bailong on 14/10/4.
6 | // Copyright (c) 2014年 Qiniu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | /**
12 | * 上传进度回调函数
13 | *
14 | * @param key 上传时指定的存储key
15 | * @param percent 进度百分比
16 | */
17 | typedef void (^QNUpProgressHandler)(NSString *key, float percent);
18 |
19 | /**
20 | * 上传中途取消函数
21 | *
22 | * @return 如果想取消,返回True, 否则返回No
23 | */
24 | typedef BOOL (^QNUpCancellationSignal)(void);
25 |
26 | /**
27 | * 可选参数集合,此类初始化后sdk上传使用时 不会对此进行改变;如果参数没有变化以及没有使用依赖,可以重复使用。
28 | */
29 | @interface QNUploadOption : NSObject
30 |
31 | /**
32 | * 用于服务器上传回调通知的自定义参数,参数的key必须以x: 开头
33 | */
34 | @property (copy, nonatomic, readonly) NSDictionary *params;
35 |
36 | /**
37 | * 指定文件的mime类型
38 | */
39 | @property (copy, nonatomic, readonly) NSString *mimeType;
40 |
41 | /**
42 | * 是否进行crc校验
43 | */
44 | @property (readonly) BOOL checkCrc;
45 |
46 | /**
47 | * 进度回调函数
48 | */
49 | @property (copy, readonly) QNUpProgressHandler progressHandler;
50 |
51 | /**
52 | * 中途取消函数
53 | */
54 | @property (copy, readonly) QNUpCancellationSignal cancellationSignal;
55 |
56 | /**
57 | * 可选参数的初始化方法
58 | *
59 | * @param mimeType mime类型
60 | * @param progress 进度函数
61 | * @param params 自定义服务器回调参数
62 | * @param check 是否进行crc检查
63 | * @param cancellation 中途取消函数
64 | *
65 | * @return 可选参数类实例
66 | */
67 | - (instancetype)initWithMime:(NSString *)mimeType
68 | progressHandler:(QNUpProgressHandler)progress
69 | params:(NSDictionary *)params
70 | checkCrc:(BOOL)check
71 | cancellationSignal:(QNUpCancellationSignal)cancellation;
72 |
73 | - (instancetype)initWithProgessHandler:(QNUpProgressHandler)progress DEPRECATED_ATTRIBUTE;
74 | - (instancetype)initWithProgressHandler:(QNUpProgressHandler)progress;
75 |
76 | /**
77 | * 内部使用,默认的参数实例
78 | *
79 | * @return 可选参数类实例
80 | */
81 | + (instancetype)defaultOptions;
82 |
83 | @end
84 |
--------------------------------------------------------------------------------
/ImageHosting/External/QiniuSDK/Storage/QNUploadOption.m:
--------------------------------------------------------------------------------
1 | //
2 | // QNUploadOption.m
3 | // QiniuSDK
4 | //
5 | // Created by bailong on 14/10/4.
6 | // Copyright (c) 2014年 Qiniu. All rights reserved.
7 | //
8 |
9 | #import "QNUploadOption+Private.h"
10 | #import "QNUploadManager.h"
11 |
12 | static NSString *mime(NSString *mimeType) {
13 | if (mimeType == nil || [mimeType isEqualToString:@""]) {
14 | return @"application/octet-stream";
15 | }
16 | return mimeType;
17 | }
18 |
19 | @implementation QNUploadOption
20 |
21 | + (NSDictionary *)filteParam:(NSDictionary *)params {
22 | NSMutableDictionary *ret = [NSMutableDictionary dictionary];
23 | if (params == nil) {
24 | return ret;
25 | }
26 |
27 | [params enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *obj, BOOL *stop) {
28 | if ([key hasPrefix:@"x:"] && ![obj isEqualToString:@""]) {
29 | ret[key] = obj;
30 | }
31 | }];
32 |
33 | return ret;
34 | }
35 |
36 | - (instancetype)initWithProgessHandler:(QNUpProgressHandler)progress {
37 | return [self initWithMime:nil progressHandler:progress params:nil checkCrc:NO cancellationSignal:nil];
38 | }
39 |
40 | - (instancetype)initWithProgressHandler:(QNUpProgressHandler)progress {
41 | return [self initWithMime:nil progressHandler:progress params:nil checkCrc:NO cancellationSignal:nil];
42 | }
43 |
44 | - (instancetype)initWithMime:(NSString *)mimeType
45 | progressHandler:(QNUpProgressHandler)progress
46 | params:(NSDictionary *)params
47 | checkCrc:(BOOL)check
48 | cancellationSignal:(QNUpCancellationSignal)cancel {
49 | if (self = [super init]) {
50 | _mimeType = mime(mimeType);
51 | _progressHandler = progress != nil ? progress : ^(NSString *key, float percent) {
52 | };
53 | _params = [QNUploadOption filteParam:params];
54 | _checkCrc = check;
55 | _cancellationSignal = cancel != nil ? cancel : ^BOOL() {
56 | return NO;
57 | };
58 | }
59 |
60 | return self;
61 | }
62 |
63 | + (instancetype)defaultOptions {
64 | return [[QNUploadOption alloc] initWithMime:nil progressHandler:nil params:nil checkCrc:NO cancellationSignal:nil];
65 | }
66 |
67 | @end
68 |
--------------------------------------------------------------------------------
/ImageHosting/External/UIKit+AFNetworking/UIActivityIndicatorView+AFNetworking.h:
--------------------------------------------------------------------------------
1 | // UIActivityIndicatorView+AFNetworking.h
2 | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 |
22 | #import
23 |
24 | #import
25 |
26 | #if TARGET_OS_IOS || TARGET_OS_TV
27 |
28 | #import
29 |
30 | /**
31 | This category adds methods to the UIKit framework's `UIActivityIndicatorView` class. The methods in this category provide support for automatically starting and stopping animation depending on the loading state of a session task.
32 | */
33 | @interface UIActivityIndicatorView (AFNetworking)
34 |
35 | ///----------------------------------
36 | /// @name Animating for Session Tasks
37 | ///----------------------------------
38 |
39 | /**
40 | Binds the animating state to the state of the specified task.
41 |
42 | @param task The task. If `nil`, automatic updating from any previously specified operation will be disabled.
43 | */
44 | - (void)setAnimatingWithStateOfTask:(nullable NSURLSessionTask *)task;
45 |
46 | @end
47 |
48 | #endif
49 |
--------------------------------------------------------------------------------
/ImageHosting/External/UIKit+AFNetworking/UIImage+AFNetworking.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+AFNetworking.h
3 | //
4 | //
5 | // Created by Paulo Ferreira on 08/07/15.
6 | //
7 | // Permission is hereby granted, free of charge, to any person obtaining a copy
8 | // of this software and associated documentation files (the "Software"), to deal
9 | // in the Software without restriction, including without limitation the rights
10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | // copies of the Software, and to permit persons to whom the Software is
12 | // furnished to do so, subject to the following conditions:
13 | //
14 | // The above copyright notice and this permission notice shall be included in
15 | // all copies or substantial portions of the Software.
16 | //
17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | // THE SOFTWARE.
24 |
25 | #if TARGET_OS_IOS || TARGET_OS_TV
26 |
27 | #import
28 |
29 | @interface UIImage (AFNetworking)
30 |
31 | + (UIImage*) safeImageWithData:(NSData*)data;
32 |
33 | @end
34 |
35 | #endif
36 |
--------------------------------------------------------------------------------
/ImageHosting/External/UIKit+AFNetworking/UIKit+AFNetworking.h:
--------------------------------------------------------------------------------
1 | // UIKit+AFNetworking.h
2 | //
3 | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #if TARGET_OS_IOS || TARGET_OS_TV
24 | #import
25 |
26 | #ifndef _UIKIT_AFNETWORKING_
27 | #define _UIKIT_AFNETWORKING_
28 |
29 | #if TARGET_OS_IOS
30 | #import "AFAutoPurgingImageCache.h"
31 | #import "AFImageDownloader.h"
32 | #import "AFNetworkActivityIndicatorManager.h"
33 | #import "UIRefreshControl+AFNetworking.h"
34 | #import "UIWebView+AFNetworking.h"
35 | #endif
36 |
37 | #import "UIActivityIndicatorView+AFNetworking.h"
38 | #import "UIButton+AFNetworking.h"
39 | #import "UIImageView+AFNetworking.h"
40 | #import "UIProgressView+AFNetworking.h"
41 | #endif /* _UIKIT_AFNETWORKING_ */
42 | #endif
43 |
--------------------------------------------------------------------------------
/ImageHosting/External/UIKit+AFNetworking/UIProgressView+AFNetworking.h:
--------------------------------------------------------------------------------
1 | // UIProgressView+AFNetworking.h
2 | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 |
22 | #import
23 |
24 | #import
25 |
26 | #if TARGET_OS_IOS || TARGET_OS_TV
27 |
28 | #import
29 |
30 | NS_ASSUME_NONNULL_BEGIN
31 |
32 |
33 | /**
34 | This category adds methods to the UIKit framework's `UIProgressView` class. The methods in this category provide support for binding the progress to the upload and download progress of a session task.
35 | */
36 | @interface UIProgressView (AFNetworking)
37 |
38 | ///------------------------------------
39 | /// @name Setting Session Task Progress
40 | ///------------------------------------
41 |
42 | /**
43 | Binds the progress to the upload progress of the specified session task.
44 |
45 | @param task The session task.
46 | @param animated `YES` if the change should be animated, `NO` if the change should happen immediately.
47 | */
48 | - (void)setProgressWithUploadProgressOfTask:(NSURLSessionUploadTask *)task
49 | animated:(BOOL)animated;
50 |
51 | /**
52 | Binds the progress to the download progress of the specified session task.
53 |
54 | @param task The session task.
55 | @param animated `YES` if the change should be animated, `NO` if the change should happen immediately.
56 | */
57 | - (void)setProgressWithDownloadProgressOfTask:(NSURLSessionDownloadTask *)task
58 | animated:(BOOL)animated;
59 |
60 | @end
61 |
62 | NS_ASSUME_NONNULL_END
63 |
64 | #endif
65 |
--------------------------------------------------------------------------------
/ImageHosting/External/UIKit+AFNetworking/UIRefreshControl+AFNetworking.h:
--------------------------------------------------------------------------------
1 | // UIRefreshControl+AFNetworking.m
2 | //
3 | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #import
24 |
25 | #import
26 |
27 | #if TARGET_OS_IOS
28 |
29 | #import
30 |
31 | NS_ASSUME_NONNULL_BEGIN
32 |
33 | /**
34 | This category adds methods to the UIKit framework's `UIRefreshControl` class. The methods in this category provide support for automatically beginning and ending refreshing depending on the loading state of a session task.
35 | */
36 | @interface UIRefreshControl (AFNetworking)
37 |
38 | ///-----------------------------------
39 | /// @name Refreshing for Session Tasks
40 | ///-----------------------------------
41 |
42 | /**
43 | Binds the refreshing state to the state of the specified task.
44 |
45 | @param task The task. If `nil`, automatic updating from any previously specified operation will be disabled.
46 | */
47 | - (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task;
48 |
49 | @end
50 |
51 | NS_ASSUME_NONNULL_END
52 |
53 | #endif
54 |
--------------------------------------------------------------------------------
/ImageHosting/ImageHosting-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // ImageHosting-Prefix.pch
3 | // ImageHosting
4 | //
5 | // Created by chars on 16/9/7.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #ifndef ImageHosting_Prefix_pch
10 | #define ImageHosting_Prefix_pch
11 |
12 | // Include any system framework and library headers here that should be included in all compilation units.
13 | // You will also need to set the Prefix Header build setting of one or more of your targets to reference this file.
14 |
15 | #import "IHCommon.h"
16 |
17 | #endif /* ImageHosting_Prefix_pch */
18 |
--------------------------------------------------------------------------------
/ImageHosting/ImageHosting.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.files.user-selected.read-only
8 |
9 | com.apple.security.network.client
10 |
11 | com.apple.security.print
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/ImageHosting/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.1.3
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 10
25 | LSApplicationCategoryType
26 | public.app-category.utilities
27 | LSMinimumSystemVersion
28 | $(MACOSX_DEPLOYMENT_TARGET)
29 | LSUIElement
30 |
31 | NSAppTransportSecurity
32 |
33 | NSAllowsArbitraryLoads
34 |
35 |
36 | NSHumanReadableCopyright
37 | Copyright © 2016年 chars. All rights reserved.
38 | NSMainStoryboardFile
39 | Main
40 | NSPrincipalClass
41 | NSApplication
42 |
43 |
44 |
--------------------------------------------------------------------------------
/ImageHosting/Model/IHAccount.h:
--------------------------------------------------------------------------------
1 | //
2 | // IHAccount.h
3 | // ImageHosting
4 | //
5 | // Created by chars on 16/8/19.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | typedef NS_ENUM(NSUInteger, IHAccountType) {
12 | IHAccountTypeNone = 0,
13 | IHAccountTypeQiniu
14 | };
15 |
16 | @interface IHAccount : NSObject
17 |
18 | @property (assign) IHAccountType accountType;
19 |
20 | /** 七牛云账号专用 */
21 | @property (copy) NSString *ak;
22 | @property (copy) NSString *sk;
23 | @property (copy) NSString *bucketName;
24 | @property (copy) NSString *region;
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/ImageHosting/Model/IHAccount.m:
--------------------------------------------------------------------------------
1 | //
2 | // IHAccount.m
3 | // ImageHosting
4 | //
5 | // Created by chars on 16/8/19.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import "IHAccount.h"
10 |
11 | #define ACCOUNT_TYPE_KEY @"account_type"
12 | #define AK_KEY @"ak"
13 | #define SK_KEY @"sk"
14 | #define BUCKET_NAME_KEY @"bucket_name"
15 | #define REGION_KEY @"region"
16 |
17 | @implementation IHAccount
18 |
19 | #pragma mark - 编码 对对象属性进行编码的处理
20 |
21 | - (void)encodeWithCoder:(NSCoder *)aCoder
22 | {
23 | [aCoder encodeInteger:_accountType forKey:ACCOUNT_TYPE_KEY];
24 | [aCoder encodeObject:_ak forKey:AK_KEY];
25 | [aCoder encodeObject:_sk forKey:SK_KEY];
26 | [aCoder encodeObject:_bucketName forKey:BUCKET_NAME_KEY];
27 | [aCoder encodeObject:_region forKey:REGION_KEY];
28 | }
29 |
30 | #pragma mark - 解码 解码归档数据来初始化对象
31 |
32 | - (id)initWithCoder:(NSCoder *)aDecoder
33 | {
34 | if (self = [super init]) {
35 | _accountType = [aDecoder decodeIntegerForKey:ACCOUNT_TYPE_KEY];
36 | _ak = [aDecoder decodeObjectForKey:AK_KEY];
37 | _sk = [aDecoder decodeObjectForKey:SK_KEY];
38 | _bucketName = [aDecoder decodeObjectForKey:BUCKET_NAME_KEY];
39 | _region = [aDecoder decodeObjectForKey:REGION_KEY];
40 | }
41 | return self;
42 | }
43 |
44 | @end
45 |
--------------------------------------------------------------------------------
/ImageHosting/Model/IHCache.h:
--------------------------------------------------------------------------------
1 | //
2 | // IHCache.h
3 | // ImageHosting
4 | //
5 | // Created by dengw on 16/8/20.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface IHCache : NSCache
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/ImageHosting/Model/IHCache.m:
--------------------------------------------------------------------------------
1 | //
2 | // IHCache.m
3 | // ImageHosting
4 | //
5 | // Created by dengw on 16/8/20.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import "IHCache.h"
10 |
11 | @implementation IHCache
12 |
13 | - (id)init {
14 | self = [super init];
15 | if (self) {
16 |
17 | }
18 | return self;
19 | }
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/ImageHosting/Model/IHGeneral.h:
--------------------------------------------------------------------------------
1 | //
2 | // IHGeneral.h
3 | // ImageHosting
4 | //
5 | // Created by chars on 16/9/6.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface IHGeneral : NSObject
12 |
13 | @property (copy) NSString *userNotification;
14 | @property (copy) NSString *launchStartUp;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/ImageHosting/Model/IHGeneral.m:
--------------------------------------------------------------------------------
1 | //
2 | // IHGeneral.m
3 | // ImageHosting
4 | //
5 | // Created by chars on 16/9/6.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import "IHGeneral.h"
10 |
11 | #define USER_NOTIFICATION_KEY @"user_notification"
12 | #define LAUNCH_START_UP_KEY @"launch_startup"
13 |
14 | @implementation IHGeneral
15 |
16 | #pragma mark - 编码 对对象属性进行编码的处理
17 |
18 | - (void)encodeWithCoder:(NSCoder *)aCoder
19 | {
20 | [aCoder encodeObject:_userNotification forKey:USER_NOTIFICATION_KEY];
21 | [aCoder encodeObject:_launchStartUp forKey:LAUNCH_START_UP_KEY];
22 | }
23 |
24 | #pragma mark - 解码 解码归档数据来初始化对象
25 |
26 | - (id)initWithCoder:(NSCoder *)aDecoder
27 | {
28 | if (self = [super init]) {
29 | _userNotification = [aDecoder decodeObjectForKey:USER_NOTIFICATION_KEY];
30 | _launchStartUp = [aDecoder decodeObjectForKey:LAUNCH_START_UP_KEY];
31 | }
32 | return self;
33 | }
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/ImageHosting/Model/const.h:
--------------------------------------------------------------------------------
1 | //
2 | // const.h
3 | // ImageHosting
4 | //
5 | // Created by dengw on 16/8/20.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #ifndef const_h
10 | #define const_h
11 |
12 | typedef NS_ENUM(NSUInteger, IHAlertStyle) {
13 | IHAlertStyleNone,
14 | IHAlertStyleWarning,
15 | IHAlertStyleInformational,
16 | IHAlertStyleCritical
17 | };
18 |
19 | #define AK_KEY @"ak"
20 | #define SK_KEY @"sk"
21 | #define BUCKET_KEY @"bucket"
22 | #define TYPE_KEY @"type"
23 | #define REGION_KEY @"region"
24 |
25 | #define REGION_EAST_CHINA @"east_china"
26 | #define REGION_NORTH_CHINA @"north_china"
27 |
28 | #define CURRENT_ACCOUNT_KEY @"current_account"
29 | #define ACCOUNTS_KEY @"accounts"
30 |
31 | #define SYSTEM_NOTIFICATION_KEY @"system_notification"
32 |
33 | #endif /* const_h */
34 |
--------------------------------------------------------------------------------
/ImageHosting/Util/IHAccountManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // IHAccountManager.h
3 | // ImageHosting
4 | //
5 | // Created by dengw on 16/8/19.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import "IHPreferencesManager.h"
10 |
11 | @class IHAccount;
12 |
13 | @interface IHAccountManager : IHPreferencesManager
14 |
15 | + (instancetype)sharedManager;
16 |
17 | - (IHAccount *)currentAccount;
18 |
19 | - (BOOL)archive:(id)object key:(NSString *)key;
20 |
21 | - (id)unarchiveForKey:(NSString *)key;
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/ImageHosting/Util/IHAccountManager.m:
--------------------------------------------------------------------------------
1 | //
2 | // IHAccountManager.m
3 | // ImageHosting
4 | //
5 | // Created by dengw on 16/8/19.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import "IHAccountManager.h"
10 | #import "IHAccount.h"
11 | #import "NSString+IHAddition.h"
12 | #import "const.h"
13 | #import "IHCache.h"
14 |
15 | #define ACCOUNT_FILE_NAME @"IHAccount.db"
16 |
17 | @interface IHAccountManager ()
18 |
19 | @property (strong) IHCache *cache;
20 |
21 | @end
22 |
23 | @implementation IHAccountManager
24 |
25 | + (instancetype)sharedManager
26 | {
27 | static IHAccountManager *sharedManager = nil;
28 | static dispatch_once_t once_token;
29 | dispatch_once(&once_token, ^{
30 | sharedManager = [[IHAccountManager alloc] init];
31 | });
32 | return sharedManager;
33 | }
34 |
35 | - (BOOL)archive:(id)object key:(NSString *)key
36 | {
37 | if (!object || !key) {
38 | return NO;
39 | }
40 |
41 | NSString *filePath = [self pathOfPreferences:ACCOUNT_FILE_NAME];
42 | NSMutableData *archiverData = [NSMutableData data];
43 | NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:archiverData];
44 | NSData *unarchiverData = [NSData dataWithContentsOfFile:filePath];
45 | NSKeyedUnarchiver *unachiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:unarchiverData];
46 |
47 | if ([object isKindOfClass:[IHAccount class]]) {
48 | NSMutableArray *accounts = [unachiver decodeObjectForKey:key];
49 | if (accounts) {
50 | BOOL replace = NO;
51 | for (IHAccount *cur in accounts) {
52 | if (cur.accountType == ((IHAccount *)object).accountType) {
53 | cur.ak = ((IHAccount *)object).ak;
54 | cur.sk = ((IHAccount *)object).sk;
55 | cur.bucketName = ((IHAccount *)object).bucketName;
56 | cur.region = ((IHAccount *)object).region;
57 | replace = YES;
58 | break;
59 | }
60 | }
61 |
62 | if (!replace) {
63 | [accounts addObject:object];
64 | }
65 | } else {
66 | accounts = [NSMutableArray arrayWithObject:object];
67 | }
68 |
69 | [archiver encodeObject:accounts forKey:key];
70 | } else {
71 | [archiver encodeObject:object forKey:key];
72 | }
73 |
74 | [archiver finishEncoding];
75 |
76 | return [archiverData writeToFile:filePath atomically:YES];
77 |
78 | }
79 |
80 | - (id)unarchiveForKey:(NSString *)key
81 | {
82 | NSString *filePath = [self pathOfPreferences:ACCOUNT_FILE_NAME];
83 | NSData *unarchiverData = [NSData dataWithContentsOfFile:filePath];
84 | NSKeyedUnarchiver *unachiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:unarchiverData];
85 |
86 | return [unachiver decodeObjectForKey:key];
87 | }
88 |
89 | - (IHAccount *)currentAccount
90 | {
91 | IHAccount *currentAccount = nil;
92 | if (self.cache) {
93 | currentAccount = [self.cache objectForKey:CURRENT_ACCOUNT_KEY];
94 | }
95 |
96 | if (!currentAccount) {
97 | NSMutableArray *accounts = [self unarchiveForKey:ACCOUNTS_KEY];
98 | currentAccount = [accounts lastObject];
99 |
100 | [self.cache setObject:currentAccount forKey:CURRENT_ACCOUNT_KEY];
101 | }
102 | IHLog(@"path of preferences file:%@ currentAccount:%@", [self pathOfPreferences:ACCOUNT_FILE_NAME], currentAccount);
103 | return currentAccount;
104 | }
105 |
106 | @end
107 |
--------------------------------------------------------------------------------
/ImageHosting/Util/IHGeneralManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // IHGeneralManager.h
3 | // ImageHosting
4 | //
5 | // Created by dengw on 16/8/24.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import "IHPreferencesManager.h"
10 |
11 | @interface IHGeneralManager : IHPreferencesManager
12 |
13 | + (instancetype)sharedManager;
14 |
15 | - (BOOL)archive:(id)object key:(NSString *)key;
16 |
17 | - (id)unarchiveForKey:(NSString *)key;
18 |
19 | - (void)startupAppWhenLogin:(BOOL)startup;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/ImageHosting/Util/IHGeneralManager.m:
--------------------------------------------------------------------------------
1 | //
2 | // IHGeneralManager.m
3 | // ImageHosting
4 | //
5 | // Created by dengw on 16/8/24.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import "IHGeneralManager.h"
10 | #import "const.h"
11 | #import
12 | #import
13 |
14 | #define GENERAL_FILE_NAME @"IHGeneral.db"
15 |
16 | @interface IHGeneralManager ()
17 |
18 | @end
19 |
20 | @implementation IHGeneralManager
21 |
22 | + (instancetype)sharedManager
23 | {
24 | static IHGeneralManager *sharedManager = nil;
25 | static dispatch_once_t once_token;
26 | dispatch_once(&once_token, ^{
27 | sharedManager = [[IHGeneralManager alloc] init];
28 | });
29 | return sharedManager;
30 | }
31 |
32 | - (instancetype)init
33 | {
34 | self = [super init];
35 | if (self) {
36 | }
37 | return self;
38 | }
39 |
40 | - (BOOL)archive:(id)object key:(NSString *)key
41 | {
42 | if (!object || !key) {
43 | return NO;
44 | }
45 |
46 | NSString *filePath = [self pathOfPreferences:GENERAL_FILE_NAME];
47 | NSMutableData *archiverData = [NSMutableData data];
48 | NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:archiverData];
49 |
50 | [archiver encodeObject:object forKey:key];
51 |
52 | [archiver finishEncoding];
53 |
54 | return [archiverData writeToFile:filePath atomically:YES];
55 |
56 | }
57 |
58 | - (id)unarchiveForKey:(NSString *)key
59 | {
60 | NSString *filePath = [self pathOfPreferences:GENERAL_FILE_NAME];
61 | NSData *unarchiverData = [NSData dataWithContentsOfFile:filePath];
62 | NSKeyedUnarchiver *unachiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:unarchiverData];
63 |
64 | return [unachiver decodeObjectForKey:key];
65 | }
66 |
67 | - (void)startupAppWhenLogin:(BOOL)startup
68 | {
69 | SMLoginItemSetEnabled((CFStringRef)@"cn.zaker.chars.ImageHostingHelper", startup);
70 | BOOL startedAtLogin = NO;
71 | NSArray *apps = [NSWorkspace sharedWorkspace].runningApplications;
72 | for (NSRunningApplication *app in apps) {
73 | if ([app.bundleIdentifier isEqualToString:@"cn.zaker.chars.ImageHostingHelper"]) {
74 | startedAtLogin = YES;
75 | break;
76 | }
77 | }
78 | if (startedAtLogin) {
79 | [[NSDistributedNotificationCenter defaultCenter] postNotificationName:@"killIHhelper" object:[NSBundle mainBundle].bundleIdentifier];
80 | }
81 | }
82 |
83 | @end
84 |
--------------------------------------------------------------------------------
/ImageHosting/Util/IHPreferencesManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // IHPreferencesManager.h
3 | // ImageHosting
4 | //
5 | // Created by dengw on 16/8/24.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface IHPreferencesManager : NSObject
12 |
13 | - (NSString *)pathOfPreferences:(NSString *)fileName;
14 |
15 | - (BOOL)fileExistAtPath:(NSString *)path;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/ImageHosting/Util/IHPreferencesManager.m:
--------------------------------------------------------------------------------
1 | //
2 | // IHPreferencesManager.m
3 | // ImageHosting
4 | //
5 | // Created by dengw on 16/8/24.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import "IHPreferencesManager.h"
10 |
11 | @implementation IHPreferencesManager
12 |
13 | + (instancetype)sharedManager
14 | {
15 | static IHPreferencesManager *sharedManager = nil;
16 | static dispatch_once_t once_token;
17 | dispatch_once(&once_token, ^{
18 | sharedManager = [[IHPreferencesManager alloc] init];
19 | });
20 | return sharedManager;
21 | }
22 |
23 | - (NSString *)pathLibraryPreferences
24 | {
25 | NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
26 | NSString *libraryDirectory = [paths lastObject];
27 | libraryDirectory = [libraryDirectory stringByAppendingString:@"/Preferences"];
28 | return libraryDirectory;
29 | }
30 |
31 | - (NSString *)pathOfPreferences:(NSString *)fileName
32 | {
33 | NSString *path = [self pathLibraryPreferences];
34 | NSString *append = [NSString stringWithFormat:@"/%@", fileName];
35 | path = [path stringByAppendingString:append];
36 | return path;
37 | }
38 |
39 | - (BOOL)fileExistAtPath:(NSString *)path
40 | {
41 | BOOL isExist = NO;
42 | isExist = [[NSFileManager defaultManager] fileExistsAtPath:path];
43 | return isExist;
44 | }
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/ImageHosting/Util/IHQiniuTokenManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // IHQiniuTokenManager.h
3 | // ImageHosting
4 | //
5 | // Created by dengw on 16/8/19.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class IHAccount;
12 |
13 | @interface IHQiniuTokenManager : NSObject
14 |
15 | + (instancetype) sharedManager;
16 |
17 | - (NSString *)generateUploadTokenForAccount:(IHAccount *)account;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/ImageHosting/Util/IHQiniuTokenManager.m:
--------------------------------------------------------------------------------
1 | //
2 | // IHQiniuTokenManager.m
3 | // ImageHosting
4 | //
5 | // Created by dengw on 16/8/19.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import "IHQiniuTokenManager.h"
10 | #import "IHAccount.h"
11 | #import "IHCache.h"
12 | #import "const.h"
13 | #include
14 | #import "JSONKit.h"
15 | #import "QN_GTM_Base64.h"
16 |
17 | @interface IHQiniuTokenManager ()
18 |
19 | @property (strong) IHCache *cache;
20 | @property (assign) NSUInteger expires;
21 |
22 | @end
23 |
24 | @implementation IHQiniuTokenManager
25 |
26 | + (instancetype)sharedManager
27 | {
28 | static IHQiniuTokenManager *sharedManager = nil;
29 | static dispatch_once_t once_token;
30 | dispatch_once(&once_token, ^{
31 | sharedManager = [[IHQiniuTokenManager alloc] init];
32 | });
33 | return sharedManager;
34 | }
35 |
36 | - (NSString *)generateUploadTokenForAccount:(IHAccount *)account
37 | {
38 | if (!account) {
39 | return nil;
40 | }
41 |
42 | const char *secretKeyStr = [account.sk UTF8String];
43 | NSString *policy = [self marshal:account.bucketName];
44 | NSData *policyData = [policy dataUsingEncoding:NSUTF8StringEncoding];
45 | NSString *encodedPolicy = [QN_GTM_Base64 stringByWebSafeEncodingData:policyData padded:TRUE];
46 | const char *encodedPolicyStr = [encodedPolicy cStringUsingEncoding:NSUTF8StringEncoding];
47 |
48 | char digestStr[CC_SHA1_DIGEST_LENGTH];
49 | bzero(digestStr, 0);
50 |
51 | CCHmac(kCCHmacAlgSHA1, secretKeyStr, strlen(secretKeyStr), encodedPolicyStr, strlen(encodedPolicyStr), digestStr);
52 |
53 | NSString *encodedDigest = [QN_GTM_Base64 stringByWebSafeEncodingBytes:digestStr length:CC_SHA1_DIGEST_LENGTH padded:TRUE];
54 |
55 | NSString *token = [NSString stringWithFormat:@"%@:%@:%@", account.ak, encodedDigest, encodedPolicy];
56 |
57 | return token;
58 | }
59 |
60 | - (NSString *)marshal:(NSString *)bucketName
61 | {
62 | if (!bucketName) {
63 | return nil;
64 | }
65 |
66 | time_t deadline;
67 | time(&deadline);//返回当前系统时间
68 |
69 | deadline += (self.expires > 0) ? self.expires : 3600; // +3600秒,即默认token保存1小时.
70 |
71 | NSNumber *deadlineNumber = [NSNumber numberWithLongLong:deadline];
72 | NSMutableDictionary *dict = [NSMutableDictionary dictionary];
73 | [dict setObject:bucketName forKey:@"scope"];
74 | [dict setObject:deadlineNumber forKey:@"deadline"];
75 |
76 | NSString *json = [dict JSONString];
77 |
78 | return json;
79 | }
80 |
81 | @end
82 |
--------------------------------------------------------------------------------
/ImageHosting/Util/IHQiniuUploadManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // IHQiniuUploadManager.h
3 | // ImageHosting
4 | //
5 | // Created by dengw on 16/8/21.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class IHAccount;
12 |
13 | typedef void(^IHQiniuCompletionHandler)(NSString *key, NSDictionary *resp);
14 | typedef void(^IHQiniuProgressHandler)(NSString *key, CGFloat percent);
15 |
16 | @interface IHQiniuUploadManager : NSObject
17 |
18 | + (instancetype) sharedManager;
19 |
20 | - (void)uploadQiniuForAccount:(IHAccount *)account key:(NSString *)key filePath:(NSString *)path completion:(IHQiniuCompletionHandler)completion progress:(IHQiniuProgressHandler)progress;
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/ImageHosting/Util/IHQiniuUploadManager.m:
--------------------------------------------------------------------------------
1 | //
2 | // IHQiniuUploadManager.m
3 | // ImageHosting
4 | //
5 | // Created by dengw on 16/8/21.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import "IHQiniuUploadManager.h"
10 | #import "const.h"
11 | #import "IHAccount.h"
12 | #import "IHQiniuTokenManager.h"
13 | #import "QiniuSDK.h"
14 |
15 | @interface IHQiniuUploadManager ()
16 |
17 | @end
18 |
19 | @implementation IHQiniuUploadManager
20 |
21 | + (instancetype)sharedManager
22 | {
23 | static IHQiniuUploadManager *sharedManager = nil;
24 | static dispatch_once_t once_token;
25 | dispatch_once(&once_token, ^{
26 | sharedManager = [[IHQiniuUploadManager alloc] init];
27 | });
28 | return sharedManager;
29 | }
30 |
31 | - (void)uploadQiniuForAccount:(IHAccount *)account key:(NSString *)key filePath:(NSString *)path completion:(IHQiniuCompletionHandler)completion progress:(IHQiniuProgressHandler)progress
32 | {
33 | NSString *token = [[IHQiniuTokenManager sharedManager] generateUploadTokenForAccount:account];
34 | QNUploadManager *manager = [[QNUploadManager alloc] init];
35 |
36 | QNUploadOption *option = [[QNUploadOption alloc] initWithProgressHandler:^(NSString *key, float percent) {
37 | if (progress) {
38 | progress(key, percent);
39 | }
40 | }];
41 | [manager putFile:path key:key token:token complete:^(QNResponseInfo *info, NSString *key, NSDictionary *resp) {
42 | IHLog(@"info:%@", info);
43 | if (completion) {
44 | completion(key, resp);
45 | }
46 | } option:option];
47 | }
48 |
49 | @end
50 |
--------------------------------------------------------------------------------
/ImageHosting/View/IHProgressIndicator.h:
--------------------------------------------------------------------------------
1 | //
2 | // IHProgressIndicator.h
3 | // ImageHosting
4 | //
5 | // Created by chars on 16/9/2.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface IHProgressIndicator : NSProgressIndicator
12 |
13 | @property (nonatomic, assign) NSInteger percent;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/ImageHosting/View/IHProgressIndicator.m:
--------------------------------------------------------------------------------
1 | //
2 | // IHProgressIndicator.m
3 | // ImageHosting
4 | //
5 | // Created by chars on 16/9/2.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import "IHProgressIndicator.h"
10 | #import "NSColor+IHAddition.h"
11 |
12 | @implementation IHProgressIndicator
13 |
14 | - (void)setPercent:(NSInteger)percent
15 | {
16 | if (_percent != percent) {
17 | _percent = percent;
18 | }
19 |
20 | [self setNeedsDisplay:YES];
21 | }
22 |
23 | - (void)drawRect:(NSRect)dirtyRect {
24 | [super drawRect:dirtyRect];
25 |
26 | NSRect fillingRect = dirtyRect;
27 | fillingRect.size.width = dirtyRect.size.width * _percent / 100;
28 | NSColor *indicatorColor;
29 |
30 | if (_percent >= 99) {
31 | indicatorColor = [NSColor ih_colorWithRGBString:@"#24A061"];
32 | } else if (_percent > 60) {
33 | indicatorColor = [NSColor ih_colorWithRGBString:@"#C28F30"];
34 | } else {
35 | indicatorColor = [NSColor ih_colorWithRGBString:@"#289ECE"];
36 | }
37 | [indicatorColor set];
38 | NSRectFill(fillingRect);
39 | }
40 |
41 | @end
42 |
--------------------------------------------------------------------------------
/ImageHosting/View/IHTableView.h:
--------------------------------------------------------------------------------
1 | //
2 | // IHTableView.h
3 | // ImageHosting
4 | //
5 | // Created by chars on 16/9/6.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class IHTableView;
12 |
13 | @protocol IHTableViewDelegate
14 |
15 | @optional
16 | - (void)ihTableView:(IHTableView *)tableView didFinishedDragWithFile:(NSString *)path;
17 | - (void)ihTableView:(IHTableView *)tableView didClickedClearAllUpload:(NSMenuItem *)item;
18 |
19 | @end
20 |
21 | @interface IHTableView : NSTableView
22 |
23 | @property (weak) id ihDelegate;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/ImageHosting/View/IHUploadFileCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // IHUploadFileCell.h
3 | // ImageHosting
4 | //
5 | // Created by chars on 16/9/1.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface IHUploadFileCell : NSTableCellView
12 |
13 | @property (nonatomic, copy) NSString *title;
14 | @property (nonatomic, copy) NSString *key;
15 | @property (nonatomic, strong) NSImage *image;
16 | @property (nonatomic, copy) NSString *progress;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/ImageHosting/View/IHUploadFileCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // IHUploadFileCell.m
3 | // ImageHosting
4 | //
5 | // Created by chars on 16/9/1.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import "IHUploadFileCell.h"
10 | #import "IHProgressIndicator.h"
11 |
12 | #define PERCENT_THROSHED 100
13 |
14 | #define WIDTH 380
15 |
16 | #define TITLE_WIDTH 300
17 | #define TITLE_HEIGHT 20
18 |
19 | #define PROGRESS_BAR_INDICATOR_WIDTH 300
20 | #define PROGRESS_BAR_INDICATOR_HEIGHT 3
21 |
22 | #define IMAGE_WIDTH 20
23 | #define IMAGE_HEIGHT 20
24 |
25 | @interface IHUploadFileCell ()
26 |
27 | @property (strong) NSTextField *titleTextField;
28 | @property (strong) IHProgressIndicator *progressBarIndicator;
29 | @property (strong) NSImageView *hintImageView;
30 |
31 | @end
32 |
33 | @implementation IHUploadFileCell
34 |
35 | - (void)awakeFromNib
36 | {
37 | [self initSubViews];
38 | }
39 |
40 | - (void)initSubViews
41 | {
42 | _progressBarIndicator = [[IHProgressIndicator alloc] initWithFrame:NSMakeRect(25, 3, PROGRESS_BAR_INDICATOR_WIDTH, PROGRESS_BAR_INDICATOR_HEIGHT)];
43 | _progressBarIndicator.style = NSProgressIndicatorBarStyle;
44 | _progressBarIndicator.indeterminate = NO;
45 | _progressBarIndicator.minValue = 0;
46 | _progressBarIndicator.maxValue = 100;
47 | [self addSubview:_progressBarIndicator];
48 |
49 | _titleTextField = [[NSTextField alloc] initWithFrame:NSMakeRect(27, 6, TITLE_WIDTH, TITLE_HEIGHT)];
50 | _titleTextField.editable = NO;
51 | _titleTextField.lineBreakMode = NSLineBreakByTruncatingTail;
52 | _titleTextField.bordered = NO;
53 | _titleTextField.alignment = NSTextAlignmentLeft;
54 | _titleTextField.backgroundColor = [NSColor clearColor];
55 | _titleTextField.textColor = [NSColor darkGrayColor];
56 | [self addSubview:_titleTextField];
57 |
58 | _hintImageView = [[NSImageView alloc] initWithFrame:NSMakeRect(334, 6, IMAGE_WIDTH, IMAGE_HEIGHT)];
59 | _hintImageView.image = [NSImage imageNamed:@"success"];
60 | [self addSubview:_hintImageView];
61 | }
62 |
63 | - (void)setTitle:(NSString *)title
64 | {
65 | if (!title) {
66 | return;
67 | }
68 |
69 | if (_title != title) {
70 | _title = title;
71 | }
72 |
73 | self.titleTextField.stringValue = title;
74 | }
75 |
76 | - (void)setProgress:(NSString *)progress
77 | {
78 | if (_progress != progress) {
79 | _progress = progress;
80 | }
81 | NSInteger percent = [progress integerValue];
82 |
83 | self.progressBarIndicator.percent = percent;
84 | }
85 |
86 | - (void)setImage:(NSImage *)image
87 | {
88 | if (_image != image) {
89 | _image = image;
90 | }
91 |
92 | self.hintImageView.image = image;
93 | }
94 |
95 | - (void)drawRect:(NSRect)dirtyRect
96 | {
97 | [super drawRect:dirtyRect];
98 |
99 | CGContextRef ctx = [[NSGraphicsContext currentContext] graphicsPort];
100 |
101 | NSColor *lineColor = [NSColor grayColor];
102 |
103 | CGRect lineRect = CGRectMake(5, 0, WIDTH - 5 * 2, 1);
104 | CGContextSaveGState(ctx);
105 | CGContextSetFillColorWithColor(ctx, lineColor.CGColor);
106 | CGContextFillRect(ctx, lineRect);
107 | CGContextRestoreGState(ctx);
108 | }
109 |
110 | @end
111 |
--------------------------------------------------------------------------------
/ImageHosting/View/IHUploadFileCell.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/ImageHosting/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // ImageHosting
4 | //
5 | // Created by chars on 16/8/16.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | int main(int argc, const char * argv[]) {
12 | return NSApplicationMain(argc, argv);
13 | }
14 |
--------------------------------------------------------------------------------
/ImageHostingHelper/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // ImageHostingHelper
4 | //
5 | // Created by chars on 16/9/7.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : NSObject
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/ImageHostingHelper/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // ImageHostingHelper
4 | //
5 | // Created by chars on 16/9/7.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 | - (void)dealloc
18 | {
19 | [[NSDistributedNotificationCenter defaultCenter] removeObserver:self];
20 | }
21 |
22 | - (void)terminate
23 | {
24 | [NSApp terminate:nil];
25 | }
26 |
27 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
28 | // Insert code here to initialize your application
29 | NSString *mainAppId = @"cn.zaker.chars.ImageHosting";
30 | NSArray *apps = [NSWorkspace sharedWorkspace].runningApplications;
31 | BOOL alreadyRunning = NO;
32 | for (NSRunningApplication *app in apps) {
33 | if ([app.bundleIdentifier isEqualToString:mainAppId]) {
34 | alreadyRunning = YES;
35 | break;
36 | }
37 | }
38 |
39 | if (!alreadyRunning) {
40 | [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(terminate) name:@"killIHhelper" object:mainAppId];
41 | NSString *path = [NSBundle mainBundle].bundlePath;
42 | NSMutableArray *components = [[path pathComponents] mutableCopy];
43 | [components removeLastObject];
44 | [components removeLastObject];
45 | [components removeLastObject];
46 | [components addObject:@"MacOS"];
47 | [components addObject:@"ImageHosting"];
48 |
49 | NSString *newPath = [NSString pathWithComponents:components];
50 | [[NSWorkspace sharedWorkspace] launchApplication:newPath];
51 | } else {
52 | [self terminate];
53 | }
54 | }
55 |
56 | - (void)applicationWillTerminate:(NSNotification *)aNotification {
57 | // Insert code here to tear down your application
58 | }
59 |
60 | @end
61 |
--------------------------------------------------------------------------------
/ImageHostingHelper/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "mac",
5 | "size" : "16x16",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "mac",
10 | "size" : "16x16",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "mac",
15 | "size" : "32x32",
16 | "scale" : "1x"
17 | },
18 | {
19 | "idiom" : "mac",
20 | "size" : "32x32",
21 | "scale" : "2x"
22 | },
23 | {
24 | "idiom" : "mac",
25 | "size" : "128x128",
26 | "scale" : "1x"
27 | },
28 | {
29 | "idiom" : "mac",
30 | "size" : "128x128",
31 | "scale" : "2x"
32 | },
33 | {
34 | "idiom" : "mac",
35 | "size" : "256x256",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "mac",
40 | "size" : "256x256",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "mac",
45 | "size" : "512x512",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "mac",
50 | "size" : "512x512",
51 | "scale" : "2x"
52 | }
53 | ],
54 | "info" : {
55 | "version" : 1,
56 | "author" : "xcode"
57 | }
58 | }
--------------------------------------------------------------------------------
/ImageHostingHelper/ImageHostingHelper.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.network.client
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ImageHostingHelper/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | LSApplicationCategoryType
26 | public.app-category.utilities
27 | LSBackgroundOnly
28 |
29 | LSMinimumSystemVersion
30 | $(MACOSX_DEPLOYMENT_TARGET)
31 | NSHumanReadableCopyright
32 | Copyright © 2016年 chars. All rights reserved.
33 | NSMainStoryboardFile
34 | Main
35 | NSPrincipalClass
36 | NSApplication
37 |
38 |
39 |
--------------------------------------------------------------------------------
/ImageHostingHelper/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // ImageHostingHelper
4 | //
5 | // Created by chars on 16/9/7.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : NSViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/ImageHostingHelper/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // ImageHostingHelper
4 | //
5 | // Created by chars on 16/9/7.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 |
11 | @implementation ViewController
12 |
13 | - (void)viewDidLoad {
14 | [super viewDidLoad];
15 |
16 | // Do any additional setup after loading the view.
17 | }
18 |
19 | - (void)setRepresentedObject:(id)representedObject {
20 | [super setRepresentedObject:representedObject];
21 |
22 | // Update the view, if already loaded.
23 | }
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/ImageHostingHelper/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // ImageHostingHelper
4 | //
5 | // Created by chars on 16/9/7.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | int main(int argc, const char * argv[]) {
12 | return NSApplicationMain(argc, argv);
13 | }
14 |
--------------------------------------------------------------------------------
/ImageHostingHelperTests/ImageHostingHelperTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // ImageHostingHelperTests.m
3 | // ImageHostingHelperTests
4 | //
5 | // Created by chars on 16/9/7.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ImageHostingHelperTests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation ImageHostingHelperTests
16 |
17 | - (void)setUp {
18 | [super setUp];
19 | // Put setup code here. This method is called before the invocation of each test method in the class.
20 | }
21 |
22 | - (void)tearDown {
23 | // Put teardown code here. This method is called after the invocation of each test method in the class.
24 | [super tearDown];
25 | }
26 |
27 | - (void)testExample {
28 | // This is an example of a functional test case.
29 | // Use XCTAssert and related functions to verify your tests produce the correct results.
30 | }
31 |
32 | - (void)testPerformanceExample {
33 | // This is an example of a performance test case.
34 | [self measureBlock:^{
35 | // Put the code you want to measure the time of here.
36 | }];
37 | }
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/ImageHostingHelperTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/ImageHostingHelperUITests/ImageHostingHelperUITests.m:
--------------------------------------------------------------------------------
1 | //
2 | // ImageHostingHelperUITests.m
3 | // ImageHostingHelperUITests
4 | //
5 | // Created by chars on 16/9/7.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ImageHostingHelperUITests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation ImageHostingHelperUITests
16 |
17 | - (void)setUp {
18 | [super setUp];
19 |
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 |
22 | // In UI tests it is usually best to stop immediately when a failure occurs.
23 | self.continueAfterFailure = NO;
24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
25 | [[[XCUIApplication alloc] init] launch];
26 |
27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
28 | }
29 |
30 | - (void)tearDown {
31 | // Put teardown code here. This method is called after the invocation of each test method in the class.
32 | [super tearDown];
33 | }
34 |
35 | - (void)testExample {
36 | // Use recording to get started writing UI tests.
37 | // Use XCTAssert and related functions to verify your tests produce the correct results.
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/ImageHostingHelperUITests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/ImageHostingTests/ImageHostingTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // ImageHostingTests.m
3 | // ImageHostingTests
4 | //
5 | // Created by chars on 16/8/16.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ImageHostingTests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation ImageHostingTests
16 |
17 | - (void)setUp {
18 | [super setUp];
19 | // Put setup code here. This method is called before the invocation of each test method in the class.
20 | }
21 |
22 | - (void)tearDown {
23 | // Put teardown code here. This method is called after the invocation of each test method in the class.
24 | [super tearDown];
25 | }
26 |
27 | - (void)testExample {
28 | // This is an example of a functional test case.
29 | // Use XCTAssert and related functions to verify your tests produce the correct results.
30 | }
31 |
32 | - (void)testPerformanceExample {
33 | // This is an example of a performance test case.
34 | [self measureBlock:^{
35 | // Put the code you want to measure the time of here.
36 | }];
37 | }
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/ImageHostingTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/ImageHostingUITests/ImageHostingUITests.m:
--------------------------------------------------------------------------------
1 | //
2 | // ImageHostingUITests.m
3 | // ImageHostingUITests
4 | //
5 | // Created by chars on 16/8/16.
6 | // Copyright © 2016年 chars. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ImageHostingUITests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation ImageHostingUITests
16 |
17 | - (void)setUp {
18 | [super setUp];
19 |
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 |
22 | // In UI tests it is usually best to stop immediately when a failure occurs.
23 | self.continueAfterFailure = NO;
24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
25 | [[[XCUIApplication alloc] init] launch];
26 |
27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
28 | }
29 |
30 | - (void)tearDown {
31 | // Put teardown code here. This method is called after the invocation of each test method in the class.
32 | [super tearDown];
33 | }
34 |
35 | - (void)testExample {
36 | // Use recording to get started writing UI tests.
37 | // Use XCTAssert and related functions to verify your tests produce the correct results.
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/ImageHostingUITests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Chars
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ImageHosting
2 | [](http://mit-license.org)
4 | [](https://developer.apple.com/resources/)
6 | 
8 |
9 |
10 | # ImageHosting for Mac Usage
11 |
12 | 博主在转战iOS开发以来,一直坚持撰写自己的技术博客。使用Github Pages + Hexo 搭建了属于自己的空间。具体搭建方法可以参考[《手把手教 GitHub + Hexo 搭建博客》](http://charsdavy.github.io/2016/05/31/build-blog-by-hexo/) 。 然而,博客中有很多时候需要使用图片说明,俗话说“一图胜千言”,博主使用 七牛云 做图床,然每次编写博客时需要打开Web版上传图片,甚是繁琐。故此,博主自己编写了一个自己的图片上传软件。
13 |
14 | 
15 |
16 | 软件下载地址:[ImageHosting for Mac](https://github.com/charsdavy/ImageHosting/releases)
17 |
18 | ## 安装
19 |
20 | 
21 |
22 | 遇到以上问题,处理方法如下:
23 |
24 | 将权限改为“任何来源”即可
25 |
26 | 
27 |
28 | ## 软件菜单栏
29 |
30 | 
31 |
32 | ## 打开软件配置,添加账户信息
33 |
34 | 
35 |
36 | ## 打开文件选择页,选择文件
37 |
38 | ## 上传文件
39 |
40 | 
41 |
42 | ## 上传进度提示
43 |
44 | 
45 |
46 | 
47 |
48 | 
49 |
50 | ## 上传完成
51 |
52 | 
53 |
54 | ## 操作提示
55 |
56 | ### 未添加账户信息提示
57 |
58 | 
59 |
60 | ### 未选择上传文件提示
61 |
62 | 
63 |
64 | ### 上传文件成功提示
65 |
66 | 
67 |
68 |
69 | [博客传送门](http://charsdavy.github.io)
70 |
71 |
--------------------------------------------------------------------------------
/SRC/archive/Applications:
--------------------------------------------------------------------------------
1 | /Applications
--------------------------------------------------------------------------------
/SRC/image/background.tif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charsdavy/ImageHosting/048e49b60b0f5212d8ae110d51cd83c387d982c4/SRC/image/background.tif
--------------------------------------------------------------------------------
/SRC/image/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charsdavy/ImageHosting/048e49b60b0f5212d8ae110d51cd83c387d982c4/SRC/image/icon.png
--------------------------------------------------------------------------------
/SRC/image/upload.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charsdavy/ImageHosting/048e49b60b0f5212d8ae110d51cd83c387d982c4/SRC/image/upload.png
--------------------------------------------------------------------------------
/SRC/image/upload_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charsdavy/ImageHosting/048e49b60b0f5212d8ae110d51cd83c387d982c4/SRC/image/upload_1.png
--------------------------------------------------------------------------------
/SRC/image/upload_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charsdavy/ImageHosting/048e49b60b0f5212d8ae110d51cd83c387d982c4/SRC/image/upload_2.png
--------------------------------------------------------------------------------
/SRC/image/upload_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/charsdavy/ImageHosting/048e49b60b0f5212d8ae110d51cd83c387d982c4/SRC/image/upload_3.png
--------------------------------------------------------------------------------