├── .gitignore
├── README.md
├── e-Hentai.xcodeproj
├── project.pbxproj
├── project.pbxproj.orig
├── project.xcworkspace
│ └── contents.xcworkspacedata
└── xcuserdata
│ └── ChilunChen.xcuserdatad
│ └── xcschemes
│ └── e-Hantai.xcscheme
├── e-Hentai
├── AppDelegate.h
├── AppDelegate.m
├── Common
│ ├── FakeViewController.h
│ ├── FakeViewController.m
│ ├── HentaiNavigationController.h
│ └── HentaiNavigationController.m
├── DownloadedViewController
│ ├── DownloadedViewController.h
│ └── DownloadedViewController.m
├── HentaiDownloadCenter
│ ├── HentaiDownloadBookOperation.h
│ ├── HentaiDownloadBookOperation.m
│ ├── HentaiDownloadCenter.h
│ ├── HentaiDownloadCenter.m
│ ├── HentaiDownloadImageOperation.h
│ └── HentaiDownloadImageOperation.m
├── HentaiParser
│ ├── HentaiParser.h
│ └── HentaiParser.m
├── HentaiSearchFilter
│ ├── HentaiFilterView.h
│ ├── HentaiFilterView.m
│ ├── HentaiSearchFilter.h
│ └── HentaiSearchFilter.m
├── Images.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── LaunchImage.launchimage
│ │ └── Contents.json
├── MainViewController
│ ├── GalleryCell
│ │ ├── CategoryTitle.h
│ │ ├── CategoryTitle.m
│ │ ├── GalleryCell.h
│ │ ├── GalleryCell.m
│ │ ├── GalleryCell.xib
│ │ ├── RatingStar.h
│ │ └── RatingStar.m
│ ├── MainViewController.h
│ ├── MainViewController.m
│ └── MainViewController.xib
├── PhotoViewController
│ ├── HentaiPhotoCell.h
│ ├── HentaiPhotoCell.m
│ ├── HentaiPhotoCell.xib
│ ├── PhotoViewController.h
│ ├── PhotoViewController.m
│ └── PhotoViewController.xib
├── ThirdParty
│ ├── FilesManager
│ │ ├── FMStream.h
│ │ ├── FMStream.m
│ │ ├── FilesManager.h
│ │ └── FilesManager.m
│ ├── Hpple
│ │ ├── TFHpple.h
│ │ ├── TFHpple.m
│ │ ├── TFHppleElement.h
│ │ ├── TFHppleElement.m
│ │ ├── XPathQuery.h
│ │ └── XPathQuery.m
│ ├── LightWeightPlist
│ │ ├── LightWeightPlist+AccessObject.h
│ │ ├── LightWeightPlist+AccessObject.m
│ │ ├── LightWeightPlist+FilePath.h
│ │ ├── LightWeightPlist+FilePath.m
│ │ ├── LightWeightPlist+HandleCache.h
│ │ ├── LightWeightPlist+HandleCache.m
│ │ ├── LightWeightPlist+SourceFromDisk.h
│ │ ├── LightWeightPlist+SourceFromDisk.m
│ │ ├── LightWeightPlist.h
│ │ ├── LightWeightPlist.m
│ │ ├── LightWeightPlistObjects.h
│ │ └── LightWeightPlistObjects.m
│ ├── SDWebImage
│ │ ├── MKAnnotationView+WebCache.h
│ │ ├── MKAnnotationView+WebCache.m
│ │ ├── NSData+ImageContentType.h
│ │ ├── NSData+ImageContentType.m
│ │ ├── SDImageCache.h
│ │ ├── SDImageCache.m
│ │ ├── SDWebImageCompat.h
│ │ ├── SDWebImageCompat.m
│ │ ├── SDWebImageDecoder.h
│ │ ├── SDWebImageDecoder.m
│ │ ├── SDWebImageDownloader.h
│ │ ├── SDWebImageDownloader.m
│ │ ├── SDWebImageDownloaderOperation.h
│ │ ├── SDWebImageDownloaderOperation.m
│ │ ├── SDWebImageManager.h
│ │ ├── SDWebImageManager.m
│ │ ├── SDWebImageOperation.h
│ │ ├── SDWebImagePrefetcher.h
│ │ ├── SDWebImagePrefetcher.m
│ │ ├── UIButton+WebCache.h
│ │ ├── UIButton+WebCache.m
│ │ ├── UIImage+GIF.h
│ │ ├── UIImage+GIF.m
│ │ ├── UIImage+MultiFormat.h
│ │ ├── UIImage+MultiFormat.m
│ │ ├── UIImage+WebP.h
│ │ ├── UIImage+WebP.m
│ │ ├── UIImageView+HighlightedWebCache.h
│ │ ├── UIImageView+HighlightedWebCache.m
│ │ ├── UIImageView+WebCache.h
│ │ ├── UIImageView+WebCache.m
│ │ ├── UIView+WebCacheOperation.h
│ │ └── UIView+WebCacheOperation.m
│ └── SVProgressHUD
│ │ ├── SVProgressHUD-Prefix.pch
│ │ ├── SVProgressHUD.bundle
│ │ ├── angle-mask@2x.png
│ │ ├── error@2x.png
│ │ └── success@2x.png
│ │ ├── SVProgressHUD.h
│ │ └── SVProgressHUD.m
├── e-Hentai-Info.plist
├── e-Hentai-Prefix.pch
├── en.lproj
│ └── InfoPlist.strings
└── main.m
└── e-HentaiTests
├── e-HentaiTests-Info.plist
├── e_HentaiTests.m
└── en.lproj
└── InfoPlist.strings
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by http://www.gitignore.io
2 |
3 | #!! ERROR: xc is undefined. Use list command to see defined gitignore types !!#
4 |
5 | ### Xcode ###
6 | build/
7 | *.pbxuser
8 | !default.pbxuser
9 | *.mode1v3
10 | !default.mode1v3
11 | *.mode2v3
12 | !default.mode2v3
13 | *.perspectivev3
14 | !default.perspectivev3
15 | xcuserdata
16 | *.xccheckout
17 | *.moved-aside
18 | DerivedData
19 | *.xcuserstate
20 |
21 |
22 | ### Objective-C ###
23 | # Xcode
24 | #
25 | build/
26 | *.pbxuser
27 | !default.pbxuser
28 | *.mode1v3
29 | !default.mode1v3
30 | *.mode2v3
31 | !default.mode2v3
32 | *.perspectivev3
33 | !default.perspectivev3
34 | xcuserdata
35 | *.xccheckout
36 | *.moved-aside
37 | DerivedData
38 | *.hmap
39 | *.ipa
40 | *.xcuserstate
41 |
42 | # CocoaPods
43 | #
44 | # We recommend against adding the Pods directory to your .gitignore. However
45 | # you should judge for yourself, the pros and cons are mentioned at:
46 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
47 | #
48 | # Pods/
49 |
50 |
51 | ### OSX ###
52 | .DS_Store
53 | .AppleDouble
54 | .LSOverride
55 |
56 | # Icon must end with two \r
57 | Icon
58 |
59 |
60 | # Thumbnails
61 | ._*
62 |
63 | # Files that might appear on external disk
64 | .Spotlight-V100
65 | .Trashes
66 |
67 | # Directories potentially created on remote AFP share
68 | .AppleDB
69 | .AppleDesktop
70 | Network Trash Folder
71 | Temporary Items
72 | .apdisk
73 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | e-Hentai
2 | ========
3 |
4 | iOS e-Hentai Reader
5 |
--------------------------------------------------------------------------------
/e-Hentai.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/e-Hentai.xcodeproj/xcuserdata/ChilunChen.xcuserdatad/xcschemes/e-Hantai.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
49 |
50 |
51 |
52 |
61 |
62 |
68 |
69 |
70 |
71 |
72 |
73 |
79 |
80 |
86 |
87 |
88 |
89 |
91 |
92 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/e-Hentai/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // e-Hentai
4 | //
5 | // Created by 啟倫 陳 on 2014/8/27.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "HentaiNavigationController.h"
12 | #import "MainViewController.h"
13 |
14 | @interface AppDelegate : UIResponder
15 |
16 | @property (strong, nonatomic) UIWindow *window;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/e-Hentai/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // e-Hentai
4 | //
5 | // Created by 啟倫 陳 on 2014/8/27.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @implementation AppDelegate
12 |
13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
14 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
15 | HentaiNavigationController *hentaiNavigation = [[HentaiNavigationController alloc] initWithRootViewController:[MainViewController new]];
16 | hentaiNavigation.autorotate = NO;
17 | hentaiNavigation.hentaiMask = UIInterfaceOrientationMaskPortrait;
18 | self.window.rootViewController = hentaiNavigation;
19 | [self.window makeKeyAndVisible];
20 | return YES;
21 | }
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/e-Hentai/Common/FakeViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // FakeViewController.h
3 | // TEST_2014_9_2
4 | //
5 | // Created by 啟倫 陳 on 2014/9/3.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface FakeViewController : UIViewController
12 |
13 | @property (nonatomic, copy) void (^BackBlock)(void);
14 |
15 | - (void)onPresentCompletion;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/e-Hentai/Common/FakeViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // FakeViewController.m
3 | // TEST_2014_9_2
4 | //
5 | // Created by 啟倫 陳 on 2014/9/3.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import "FakeViewController.h"
10 |
11 | @interface FakeViewController ()
12 |
13 | @end
14 |
15 | @implementation FakeViewController
16 |
17 | - (void)onPresentCompletion
18 | {
19 | [self dismissViewControllerAnimated:NO completion: ^{
20 | self.BackBlock();
21 | }];
22 | }
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/e-Hentai/Common/HentaiNavigationController.h:
--------------------------------------------------------------------------------
1 | //
2 | // HentaiNavigationController.h
3 | // TEST_2014_9_2
4 | //
5 | // Created by 啟倫 陳 on 2014/9/3.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface HentaiNavigationController : UINavigationController
12 |
13 | @property (nonatomic, assign) BOOL autorotate;
14 | @property (nonatomic, assign) UIInterfaceOrientationMask hentaiMask;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/e-Hentai/Common/HentaiNavigationController.m:
--------------------------------------------------------------------------------
1 | //
2 | // HentaiNavigationController.m
3 | // TEST_2014_9_2
4 | //
5 | // Created by 啟倫 陳 on 2014/9/3.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import "HentaiNavigationController.h"
10 |
11 | @interface HentaiNavigationController ()
12 |
13 | @end
14 |
15 | @implementation HentaiNavigationController
16 |
17 |
18 | #pragma mark - Configuring the View Rotation Settings
19 |
20 | - (BOOL)shouldAutorotate {
21 | return self.autorotate;
22 | }
23 |
24 | - (NSUInteger)supportedInterfaceOrientations {
25 | return self.hentaiMask;
26 | }
27 |
28 | @end
29 |
--------------------------------------------------------------------------------
/e-Hentai/DownloadedViewController/DownloadedViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // DownloadedViewController.h
3 | // e-Hentai
4 | //
5 | // Created by 啟倫 陳 on 2014/9/29.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import "MainViewController.h"
10 |
11 | @interface DownloadedViewController : MainViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/e-Hentai/DownloadedViewController/DownloadedViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // DownloadedViewController.m
3 | // e-Hentai
4 | //
5 | // Created by 啟倫 陳 on 2014/9/29.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import "DownloadedViewController.h"
10 |
11 | @interface DownloadedViewController ()
12 |
13 | @property (nonatomic, strong) NSMutableArray *listArray;
14 |
15 | @end
16 |
17 | @implementation DownloadedViewController
18 |
19 | #pragma mark - UICollectionViewDataSource
20 |
21 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
22 | return [HentaiSaveLibraryArray count];
23 | }
24 |
25 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
26 | GalleryCell *cell = (GalleryCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"GalleryCell" forIndexPath:indexPath];
27 | NSDictionary *hentaiInfo = HentaiSaveLibraryArray[indexPath.row][@"hentaiInfo"];
28 | [hentaiInfo setValue:@(YES) forKey:imageMode];
29 | [cell setGalleryDict:hentaiInfo];
30 | return cell;
31 | }
32 |
33 | #pragma mark - UICollectionViewDelegate
34 |
35 | - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
36 | NSDictionary *hentaiInfo = HentaiSaveLibraryArray[indexPath.row][@"hentaiInfo"];
37 | HentaiNavigationController *hentaiNavigation = (HentaiNavigationController *)self.navigationController;
38 | hentaiNavigation.autorotate = YES;
39 | hentaiNavigation.hentaiMask = UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscape;
40 | PhotoViewController *photoViewController = [PhotoViewController new];
41 | photoViewController.hentaiInfo = hentaiInfo;
42 | [hentaiNavigation pushViewController:photoViewController animated:YES];
43 | }
44 |
45 | #pragma mark - recv notification
46 |
47 | - (void)hentaiDownloadSuccess:(NSNotification *)notification {
48 | [self.listCollectionView reloadData];
49 | }
50 |
51 | #pragma mark - ibaction
52 |
53 | //override 這個 method 避免可以一直 push
54 | - (IBAction)pushToDownloadedAction:(id)sender {
55 | }
56 |
57 | #pragma mark - life cycle
58 |
59 | //這邊我故意沒有放 [super viewDidLoad], 不然會跑到很多 mainviewcontroller 的東西
60 | - (void)viewDidLoad {
61 | self.title = @"已經下載的漫畫";
62 | [self.listCollectionView registerNib:[UINib nibWithNibName:@"GalleryCell" bundle:nil] forCellWithReuseIdentifier:@"GalleryCell"];
63 | }
64 |
65 | - (void)viewWillAppear:(BOOL)animated {
66 | [super viewWillAppear:animated];
67 | [self.listCollectionView reloadData];
68 | }
69 |
70 | @end
71 |
--------------------------------------------------------------------------------
/e-Hentai/HentaiDownloadCenter/HentaiDownloadBookOperation.h:
--------------------------------------------------------------------------------
1 | //
2 | // HentaiDownloadBookOperation.h
3 | // e-Hentai
4 | //
5 | // Created by 啟倫 陳 on 2014/9/11.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "HentaiDownloadImageOperation.h"
12 |
13 | @interface HentaiDownloadBookOperation : NSOperation
14 |
15 | @property (nonatomic, strong) NSDictionary *bookInfo;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/e-Hentai/HentaiDownloadCenter/HentaiDownloadBookOperation.m:
--------------------------------------------------------------------------------
1 | //
2 | // HentaiDownloadBookOperation.m
3 | // e-Hentai
4 | //
5 | // Created by 啟倫 陳 on 2014/9/11.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import "HentaiDownloadBookOperation.h"
10 |
11 | @interface HentaiDownloadBookOperation ()
12 |
13 | @property (nonatomic, assign) NSUInteger hentaiIndex;
14 | @property (nonatomic, strong) NSMutableArray *hentaiImageURLs;
15 | @property (nonatomic, strong) NSMutableDictionary *retryMap;
16 | @property (nonatomic, assign) NSUInteger failCount;
17 | @property (nonatomic, strong) NSMutableDictionary *hentaiResults;
18 | @property (nonatomic, readonly) NSString *hentaiKey;
19 | @property (nonatomic, strong) NSOperationQueue *hentaiQueue;
20 | @property (nonatomic, strong) NSString *maxHentaiCount;
21 |
22 | @property (nonatomic, assign) BOOL isExecuting;
23 | @property (nonatomic, assign) BOOL isFinished;
24 |
25 | @end
26 |
27 | @implementation HentaiDownloadBookOperation
28 |
29 | #pragma mark - Methods to Override
30 |
31 | - (BOOL)isConcurrent {
32 | return YES;
33 | }
34 |
35 | - (void)start {
36 | if ([self isCancelled]) {
37 | [self hentaiFinish];
38 | return;
39 | }
40 |
41 | [self hentaiStart];
42 | self.hentaiIndex = -1;
43 | self.hentaiImageURLs = [NSMutableArray array];
44 | self.retryMap = [NSMutableDictionary dictionary];
45 | self.failCount = 0;
46 | self.hentaiResults = [NSMutableDictionary dictionary];
47 | self.hentaiQueue = [NSOperationQueue new];
48 | [self.hentaiQueue setMaxConcurrentOperationCount:2];
49 | self.maxHentaiCount = self.bookInfo[@"filecount"];
50 |
51 | dispatch_async(dispatch_get_main_queue(), ^{
52 | [self checkEndOfFile];
53 | });
54 | }
55 |
56 | + (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key {
57 | return YES;
58 | }
59 |
60 | #pragma mark - getter
61 |
62 | @dynamic hentaiKey;
63 |
64 | - (NSString *)hentaiKey {
65 | NSArray *splitStrings = [self.bookInfo[@"url"] componentsSeparatedByString:@"/"];
66 | NSUInteger splitCount = [splitStrings count];
67 | NSString *checkHentaiKey = [NSString stringWithFormat:@"%@-%@-%@", splitStrings[splitCount - 3], splitStrings[splitCount - 2], self.bookInfo[@"title"]];
68 | return [checkHentaiKey stringByReplacingOccurrencesOfString:@"/" withString:@"-"];
69 | }
70 |
71 | #pragma mark - HentaiDownloadImageOperationDelegate
72 |
73 | - (void)downloadResult:(NSString *)urlString heightOfSize:(CGFloat)height isSuccess:(BOOL)isSuccess {
74 | if (isSuccess) {
75 | self.hentaiResults[[urlString lastPathComponent]] = @(height);
76 | }
77 | else {
78 | NSNumber *retryCount = self.retryMap[urlString];
79 | if (retryCount) {
80 | retryCount = @([retryCount integerValue] + 1);
81 | }
82 | else {
83 | retryCount = @(1);
84 | }
85 | self.retryMap[urlString] = retryCount;
86 |
87 | if ([retryCount integerValue] <= 3) {
88 | [self createNewOperation:urlString];
89 | }
90 | else {
91 | self.failCount++;
92 | self.maxHentaiCount = [NSString stringWithFormat:@"%d", [self.maxHentaiCount integerValue] - 1];
93 | [self.hentaiImageURLs removeObject:urlString];
94 | }
95 | }
96 | }
97 |
98 | #pragma mark - operation status
99 |
100 | - (void)hentaiStart {
101 | self.isFinished = NO;
102 | self.isExecuting = YES;
103 | }
104 |
105 | - (void)hentaiFinish {
106 | [self.hentaiQueue cancelAllOperations];
107 | self.isFinished = YES;
108 | self.isExecuting = NO;
109 | }
110 |
111 | #pragma mark - download methods
112 |
113 | //將要下載的圖片加到 queue 裡面
114 | - (void)preloadImages:(NSArray *)images {
115 | for (NSString *eachImageString in images) {
116 | [self createNewOperation:eachImageString];
117 | }
118 | }
119 |
120 | //等待圖片下載完成
121 | - (void)waitingOnDownloadFinish {
122 | __weak HentaiDownloadBookOperation *weakSelf = self;
123 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
124 | [weakSelf.hentaiQueue waitUntilAllOperationsAreFinished];
125 | if (weakSelf && ![self isCancelled]) {
126 | __strong HentaiDownloadBookOperation *strongSelf = weakSelf;
127 | dispatch_async(dispatch_get_main_queue(), ^{
128 | [strongSelf checkEndOfFile];
129 | });
130 | }
131 | else {
132 | [self hentaiFinish];
133 | }
134 | });
135 | }
136 |
137 | //檢查是不是還有圖片需要下載
138 | - (void)checkEndOfFile {
139 | if ([self.hentaiImageURLs count] < [self.maxHentaiCount integerValue]) {
140 | self.hentaiIndex++;
141 | __weak HentaiDownloadBookOperation *weakSelf = self;
142 | [HentaiParser requestImagesAtURL:self.bookInfo[@"url"] atIndex:self.hentaiIndex completion: ^(HentaiParserStatus status, NSArray *images) {
143 | if (status && weakSelf && ![self isCancelled]) {
144 | __strong HentaiDownloadBookOperation *strongSelf = weakSelf;
145 | [strongSelf.hentaiImageURLs addObjectsFromArray:images];
146 | [strongSelf preloadImages:images];
147 | [strongSelf waitingOnDownloadFinish];
148 | }
149 | else {
150 | [self hentaiFinish];
151 | }
152 | }];
153 | }
154 | else {
155 | if (![self isCancelled]) {
156 | NSDictionary *saveInfo = @{ @"hentaiKey":self.hentaiKey, @"images":self.hentaiImageURLs, @"hentaiResult":self.hentaiResults, @"hentaiInfo":self.bookInfo };
157 | [HentaiSaveLibraryArray addObject:saveInfo];
158 |
159 | //如果 cache 有暫存就殺光光
160 | [[[FilesManager cacheFolder] fcd:@"Hentai"] rd:self.hentaiKey];
161 | [HentaiCacheLibraryDictionary removeObjectForKey:self.hentaiKey];
162 | LWPForceWrite();
163 | [[NSNotificationCenter defaultCenter] postNotificationName:HentaiDownloadSuccessNotification object:self.bookInfo[@"title"]];
164 | [self hentaiFinish];
165 | }
166 | else {
167 | [self hentaiFinish];
168 | }
169 | }
170 | }
171 |
172 | #pragma mark - private
173 |
174 | - (void)createNewOperation:(NSString *)urlString {
175 | HentaiDownloadImageOperation *newOperation = [HentaiDownloadImageOperation new];
176 | newOperation.downloadURLString = urlString;
177 | newOperation.isCacheOperation = NO;
178 | newOperation.hentaiKey = self.hentaiKey;
179 | newOperation.delegate = self;
180 | [self.hentaiQueue addOperation:newOperation];
181 | }
182 |
183 | @end
184 |
--------------------------------------------------------------------------------
/e-Hentai/HentaiDownloadCenter/HentaiDownloadCenter.h:
--------------------------------------------------------------------------------
1 | //
2 | // HentaiDownloadCenter.h
3 | // e-Hentai
4 | //
5 | // Created by 啟倫 陳 on 2014/9/11.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "HentaiDownloadBookOperation.h"
12 |
13 | #define HentaiDownloadSuccessNotification @"HentaiDownloadSuccessNotification"
14 | #define HentaiDownloadFailNotification @"HentaiDownloadFailNotification"
15 |
16 | @interface HentaiDownloadCenter : NSObject
17 |
18 | + (void)addBook:(NSDictionary *)bookInfo;
19 | + (BOOL)isDownloading:(NSDictionary *)bookInfo;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/e-Hentai/HentaiDownloadCenter/HentaiDownloadCenter.m:
--------------------------------------------------------------------------------
1 | //
2 | // HentaiDownloadCenter.m
3 | // e-Hentai
4 | //
5 | // Created by 啟倫 陳 on 2014/9/11.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import "HentaiDownloadCenter.h"
10 |
11 | #import
12 |
13 | @implementation HentaiDownloadCenter
14 |
15 | #pragma mark - class method
16 |
17 | + (void)addBook:(NSDictionary *)bookInfo {
18 | BOOL isExist = NO;
19 |
20 | //如果下載過的話不給下
21 | for (NSDictionary *eachInfo in HentaiSaveLibraryArray) {
22 | if ([eachInfo[@"url"] isEqualToString:bookInfo[@"url"]]) {
23 | isExist = YES;
24 | break;
25 | }
26 | }
27 |
28 | //如果在 queue 裡面也不給下
29 | isExist = isExist | [self isDownloading:bookInfo];
30 |
31 | if (isExist) {
32 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"不行~ O3O" message:@"你可能已經下載過或是正在下載中!" delegate:nil cancelButtonTitle:@"確定" otherButtonTitles:nil];
33 | [alert show];
34 | }
35 | else {
36 | HentaiDownloadBookOperation *newOperation = [HentaiDownloadBookOperation new];
37 | newOperation.bookInfo = bookInfo;
38 | [[self allBooksOperationQueue] addOperation:newOperation];
39 | }
40 | }
41 |
42 | + (BOOL)isDownloading:(NSDictionary *)bookInfo {
43 | BOOL isExist = NO;
44 |
45 | for (HentaiDownloadBookOperation *eachOperation in[[self allBooksOperationQueue] operations]) {
46 | if ([eachOperation.bookInfo[@"url"] isEqualToString:bookInfo[@"url"]]) {
47 | isExist = YES;
48 | break;
49 | }
50 | }
51 | return isExist;
52 | }
53 |
54 | #pragma mark - private
55 |
56 | + (NSOperationQueue *)allBooksOperationQueue {
57 | static dispatch_once_t onceToken;
58 | dispatch_once(&onceToken, ^{
59 | NSOperationQueue *hentaiQueue = [NSOperationQueue new];
60 | [hentaiQueue setMaxConcurrentOperationCount:2];
61 | objc_setAssociatedObject(self, _cmd, hentaiQueue, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
62 | });
63 | return objc_getAssociatedObject(self, _cmd);
64 | }
65 |
66 | @end
67 |
--------------------------------------------------------------------------------
/e-Hentai/HentaiDownloadCenter/HentaiDownloadImageOperation.h:
--------------------------------------------------------------------------------
1 | //
2 | // HentaiDownloadOperation.h
3 | // e-Hentai
4 | //
5 | // Created by 啟倫 陳 on 2014/9/5.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @protocol HentaiDownloadImageOperationDelegate;
12 |
13 | @interface HentaiDownloadImageOperation : NSOperation
14 |
15 | @property (nonatomic, weak) id delegate;
16 | @property (nonatomic, strong) NSString *downloadURLString;
17 | @property (nonatomic, strong) NSString *hentaiKey;
18 | @property (nonatomic, assign) BOOL isCacheOperation;
19 |
20 | @end
21 |
22 | @protocol HentaiDownloadImageOperationDelegate
23 |
24 | @required
25 | - (void)downloadResult:(NSString *)urlString heightOfSize:(CGFloat)height isSuccess:(BOOL)isSuccess;
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/e-Hentai/HentaiDownloadCenter/HentaiDownloadImageOperation.m:
--------------------------------------------------------------------------------
1 | //
2 | // HentaiDownloadOperation.m
3 | // e-Hentai
4 | //
5 | // Created by 啟倫 陳 on 2014/9/5.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import "HentaiDownloadImageOperation.h"
10 |
11 | @interface HentaiDownloadImageOperation ()
12 |
13 | @property (nonatomic, strong) NSMutableData *recvData;
14 | @property (nonatomic, assign) BOOL isExecuting;
15 | @property (nonatomic, assign) BOOL isFinished;
16 |
17 | @end
18 |
19 | @implementation HentaiDownloadImageOperation
20 |
21 | #pragma mark - Methods to Override
22 |
23 | - (BOOL)isConcurrent {
24 | return YES;
25 | }
26 |
27 | - (void)start {
28 | if ([self isCancelled]) {
29 | [self hentaiFinish];
30 | return;
31 | }
32 |
33 | [self hentaiStart];
34 | NSNumber *imageHeight = HentaiCacheLibraryDictionary[self.hentaiKey][[self.downloadURLString lastPathComponent]];
35 |
36 | //從 imageHeight 的有無可以判斷這個檔案是否已經有了
37 | if (!imageHeight) {
38 | NSURL *url = [NSURL URLWithString:self.downloadURLString];
39 |
40 | NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:[NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30.0f] delegate:self startImmediately:NO];
41 | [conn scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
42 | [conn start];
43 | }
44 | else {
45 | if (![self isCancelled]) {
46 | dispatch_sync(dispatch_get_main_queue(), ^{
47 | [self.delegate downloadResult:self.downloadURLString heightOfSize:[imageHeight floatValue] isSuccess:YES];
48 | [self hentaiFinish];
49 | });
50 | }
51 | }
52 | }
53 |
54 | + (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key {
55 | return YES;
56 | }
57 |
58 | #pragma mark - NSURLConnectionDelegate
59 |
60 |
61 | - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
62 | self.recvData = [NSMutableData data];
63 | }
64 |
65 | - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
66 | if (![self isCancelled]) {
67 | [self.recvData appendData:data];
68 | }
69 | else {
70 | [self hentaiFinish];
71 | [connection cancel];
72 | connection = nil;
73 | }
74 | }
75 |
76 | - (void)connectionDidFinishLoading:(NSURLConnection *)connection {
77 | if (![self isCancelled]) {
78 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
79 | UIImage *image = [self resizeImageWithImage:[[UIImage alloc] initWithData:self.recvData]];
80 |
81 | if (self.isCacheOperation) {
82 | [[[[FilesManager cacheFolder] fcd:@"Hentai"] fcd:self.hentaiKey] write:UIImageJPEGRepresentation(image, 0.6f) filename:[self.downloadURLString lastPathComponent]];
83 | }
84 | else {
85 | [[[FilesManager documentFolder] fcd:self.hentaiKey] write:UIImageJPEGRepresentation(image, 0.6f) filename:[self.downloadURLString lastPathComponent]];
86 | }
87 |
88 | //讓檔案轉存這件事情不擋線程
89 | dispatch_async(dispatch_get_main_queue(), ^{
90 | [self.delegate downloadResult:self.downloadURLString heightOfSize:image.size.height isSuccess:YES];
91 | [self hentaiFinish];
92 | });
93 | });
94 | }
95 | [connection cancel];
96 | connection = nil;
97 | }
98 |
99 | - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
100 | if (![self isCancelled]) {
101 | [self.delegate downloadResult:self.downloadURLString heightOfSize:-1 isSuccess:NO];
102 | }
103 | [self hentaiFinish];
104 | [connection cancel];
105 | connection = nil;
106 | }
107 |
108 | #pragma mark - private
109 |
110 | - (void)hentaiStart {
111 | self.isFinished = NO;
112 | self.isExecuting = YES;
113 | }
114 |
115 | - (void)hentaiFinish {
116 | self.isFinished = YES;
117 | self.isExecuting = NO;
118 | }
119 |
120 | //計算符合螢幕 size 的新大小
121 | - (CGSize)calendarNewSize:(UIImage *)image {
122 | CGFloat oldWidth = image.size.width;
123 | CGFloat scaleFactor = [UIScreen mainScreen].bounds.size.height / oldWidth;
124 | CGFloat newHeight = image.size.height * scaleFactor;
125 | CGFloat newWidth = oldWidth * scaleFactor;
126 | return CGSizeMake(newWidth, newHeight);
127 | }
128 |
129 | //根據新的大小把圖片縮小, 原網站上面的圖片都過大
130 | - (UIImage *)resizeImageWithImage:(UIImage *)image {
131 | CGSize newSize = [self calendarNewSize:image];
132 | UIGraphicsBeginImageContext(newSize);
133 | //retina 的圖片實在太大, 吃不消 所以先不 retina 試試
134 | //UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
135 | [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
136 | UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
137 | UIGraphicsEndImageContext();
138 | return newImage;
139 | }
140 |
141 | @end
142 |
--------------------------------------------------------------------------------
/e-Hentai/HentaiParser/HentaiParser.h:
--------------------------------------------------------------------------------
1 | //
2 | // HentaiParser.h
3 | // TEST_2014_9_2
4 | //
5 | // Created by 啟倫 陳 on 2014/9/2.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | typedef enum {
12 | HentaiParserStatusFail,
13 | HentaiParserStatusSuccess
14 | } HentaiParserStatus;
15 |
16 | @interface HentaiParser : NSObject
17 |
18 | + (void)requestListAtIndex:(NSUInteger)index completion:(void (^)(HentaiParserStatus status, NSArray *listArray))completion;
19 | + (void)requestListAtFilterUrl:(NSString *)urlString completion:(void (^)(HentaiParserStatus status, NSArray *listArray))completion;
20 | + (void)requestImagesAtURL:(NSString *)urlString atIndex:(NSUInteger)index completion:(void (^)(HentaiParserStatus status, NSArray *images))completion;
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/e-Hentai/HentaiSearchFilter/HentaiFilterView.h:
--------------------------------------------------------------------------------
1 | //
2 | // HentaiFilterView.h
3 | // e-Hentai
4 | //
5 | // Created by OptimusKe on 2014/9/28.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface HentaiFilterView : UIView
12 |
13 | - (void)selectAll;
14 | - (NSArray *)filterResult;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/e-Hentai/HentaiSearchFilter/HentaiFilterView.m:
--------------------------------------------------------------------------------
1 | //
2 | // HentaiFilterView.m
3 | // e-Hentai
4 | //
5 | // Created by OptimusKe on 2014/9/28.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import "HentaiFilterView.h"
10 | #import "HentaiSearchFilter.h"
11 |
12 | #define colorDoujinshi [UIColor colorWithRed:251.0 / 255.0 green:99.0 / 255.0 blue:102.0 / 255.0 alpha:1]
13 | #define colorManga [UIColor colorWithRed:252.0 / 255.0 green:194.0 / 255.0 blue:82.0 / 255.0 alpha:1]
14 | #define colorArtistcg [UIColor colorWithRed:238.0 / 255.0 green:230.0 / 255.0 blue:102.0 / 255.0 alpha:1]
15 | #define colorGamecg [UIColor colorWithRed:192.0 / 255.0 green:129.0 / 255.0 blue:127.0 / 255.0 alpha:1]
16 | #define colorWestern [UIColor colorWithRed:170.0 / 255.0 green:255.0 / 255.0 blue:87.0 / 255.0 alpha:1]
17 | #define colorNonh [UIColor colorWithRed:132.0 / 255.0 green:199.0 / 255.0 blue:255.0 / 255.0 alpha:1]
18 | #define colorImageset [UIColor colorWithRed:108.0 / 255.0 green:96.0 / 255.0 blue:255.0 / 255.0 alpha:1]
19 | #define colorCosplay [UIColor colorWithRed:144.0 / 255.0 green:97.0 / 255.0 blue:181.0 / 255.0 alpha:1]
20 | #define colorAsianporn [UIColor colorWithRed:245.0 / 255.0 green:175.0 / 255.0 blue:246.0 / 255.0 alpha:1]
21 | #define colorMisc [UIColor colorWithRed:219.0 / 255.0 green:219.0 / 255.0 blue:219.0 / 255.0 alpha:1]
22 | #define colorAll [UIColor grayColor]
23 |
24 | @interface HentaiFilterView ()
25 | {
26 | NSMutableArray *filterEnableArray;
27 | }
28 |
29 |
30 | @end
31 |
32 | @implementation HentaiFilterView
33 |
34 | - (id)initWithFrame:(CGRect)frame {
35 | self = [super initWithFrame:frame];
36 | if (self) {
37 | // Initialization code
38 | self.backgroundColor = [UIColor blackColor];
39 | [self setButtons];
40 | }
41 | return self;
42 | }
43 |
44 | - (void)selectAll {
45 | for (int i = 0; i < filterEnableArray.count; i++) {
46 | [filterEnableArray replaceObjectAtIndex:i withObject:@(YES)];
47 | }
48 |
49 | for (UIButton *btn in self.subviews) {
50 | [self setButtonEnableStyle:btn enable:YES];
51 | }
52 | }
53 |
54 | - (NSArray *)filterResult {
55 | NSMutableArray *resultArray = [NSMutableArray array];
56 |
57 | for (int i = 0; i < filterEnableArray.count; i++) {
58 | NSNumber *filterNum = [filterEnableArray objectAtIndex:i];
59 | if ([filterNum boolValue]) {
60 | [resultArray addObject:@(i)];
61 | }
62 | }
63 |
64 | return resultArray;
65 | }
66 |
67 | #pragma mark - private
68 |
69 |
70 | - (void)setButtons {
71 | filterEnableArray = [NSMutableArray arrayWithCapacity:10];
72 |
73 | for (int i = 0; i < 10; i++) {
74 | CGFloat x = (i % 2 == 0) ? 0 : CGRectGetWidth(self.frame) / 2;
75 | CGFloat y = (i / 2) * 40;
76 |
77 | //init all Tag YES
78 | NSNumber *tapTag = @(YES);
79 | [filterEnableArray insertObject:tapTag atIndex:i];
80 |
81 | UIButton *filterBtn = [[UIButton alloc] initWithFrame:CGRectMake(x, y, CGRectGetWidth(self.frame) / 2, 40)];
82 | filterBtn.tag = i;
83 | filterBtn.titleLabel.textColor = [UIColor whiteColor];
84 | NSNumber *filterTag = @(i);
85 | filterBtn.backgroundColor = [self colorMapping:filterTag];
86 | [filterBtn setTitle:[self titleMapping:filterTag] forState:UIControlStateNormal];
87 | [filterBtn setTitleColor:[UIColor grayColor] forState:UIControlStateHighlighted];
88 | [filterBtn addTarget:self action:@selector(buttonPress:) forControlEvents:UIControlEventTouchUpInside];
89 | [self addSubview:filterBtn];
90 | }
91 | }
92 |
93 | - (UIColor *)colorMapping:(NSNumber *)filterTag {
94 | NSDictionary *mapping = @{ @(HentaiFilterTypeDoujinshi) : colorDoujinshi,
95 | @(HentaiFilterTypeManga) : colorManga,
96 | @(HentaiFilterTypeArtistcg) : colorArtistcg,
97 | @(HentaiFilterTypeGamecg) : colorGamecg,
98 | @(HentaiFilterTypeWestern) : colorWestern,
99 | @(HentaiFilterTypeNonh) : colorNonh,
100 | @(HentaiFilterTypeImagesets) : colorImageset,
101 | @(HentaiFilterTypeCosplay) : colorCosplay,
102 | @(HentaiFilterTypeAsianporn) : colorAsianporn,
103 | @(HentaiFilterTypeMisc) : colorMisc };
104 | return mapping[filterTag] ? mapping[filterTag] : colorAll;
105 | }
106 |
107 | - (NSString *)titleMapping:(NSNumber *)filterTag {
108 | NSDictionary *mapping = @{ @(HentaiFilterTypeDoujinshi) : @"Doujinshi",
109 | @(HentaiFilterTypeManga) : @"Manga",
110 | @(HentaiFilterTypeArtistcg) : @"Artistcg",
111 | @(HentaiFilterTypeGamecg) : @"Gamecg",
112 | @(HentaiFilterTypeWestern) : @"Western",
113 | @(HentaiFilterTypeNonh) : @"Nonh",
114 | @(HentaiFilterTypeImagesets) : @"Imageset",
115 | @(HentaiFilterTypeCosplay) : @"Cosplay",
116 | @(HentaiFilterTypeAsianporn) : @"Asianporn",
117 | @(HentaiFilterTypeMisc) : @"Misc" };
118 | return mapping[filterTag] ? mapping[filterTag] : @"All";
119 | }
120 |
121 | - (void)setButtonEnableStyle:(UIButton *)btn enable:(BOOL)enable {
122 | NSNumber *filterTag = @(btn.tag);
123 | if (enable) {
124 | btn.backgroundColor = [self colorMapping:filterTag];
125 | [btn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
126 | }
127 | else {
128 | btn.backgroundColor = [UIColor blackColor];
129 | [btn setTitleColor:[self colorMapping:filterTag] forState:UIControlStateNormal];
130 | }
131 | }
132 |
133 | - (void)buttonPress:(UIButton *)btn {
134 | BOOL enable = [[filterEnableArray objectAtIndex:btn.tag] boolValue];
135 | enable = !enable;
136 | [filterEnableArray replaceObjectAtIndex:btn.tag withObject:@(enable)];
137 | [self setButtonEnableStyle:btn enable:enable];
138 | }
139 |
140 | @end
141 |
--------------------------------------------------------------------------------
/e-Hentai/HentaiSearchFilter/HentaiSearchFilter.h:
--------------------------------------------------------------------------------
1 | //
2 | // HentaiSearchFilter.h
3 | // CoreGraphicsTest
4 | //
5 | // Created by OptimusKe on 2014/9/26.
6 | // Copyright (c) 2014年 Jack. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | typedef NS_ENUM (NSInteger, HentaiFilterType) {
12 | HentaiFilterTypeDoujinshi = 0,
13 | HentaiFilterTypeManga,
14 | HentaiFilterTypeArtistcg,
15 | HentaiFilterTypeGamecg,
16 | HentaiFilterTypeWestern,
17 | HentaiFilterTypeNonh,
18 | HentaiFilterTypeImagesets,
19 | HentaiFilterTypeCosplay,
20 | HentaiFilterTypeAsianporn,
21 | HentaiFilterTypeMisc
22 | };
23 |
24 | @interface HentaiSearchFilter : NSObject
25 |
26 | + (NSString *)searchFilterUrlByKeyword:(NSString *)searchWord
27 | filterArray:(NSArray *)filterArray
28 | baseUrl:(NSString *)baseUrl;
29 |
30 | @end
31 |
--------------------------------------------------------------------------------
/e-Hentai/HentaiSearchFilter/HentaiSearchFilter.m:
--------------------------------------------------------------------------------
1 | //
2 | // HentaiSearchFilter.m
3 | // CoreGraphicsTest
4 | //
5 | // Created by OptimusKe on 2014/9/26.
6 | // Copyright (c) 2014年 Jack. All rights reserved.
7 | //
8 |
9 | #import "HentaiSearchFilter.h"
10 |
11 | @implementation HentaiSearchFilter
12 |
13 | + (NSString *)searchFilterUrlByKeyword:(NSString *)searchWord
14 | filterArray:(NSArray *)filterArray
15 | baseUrl:(NSString *)baseUrl {
16 | NSString *filterUrl = [[NSString alloc] initWithString:baseUrl];
17 |
18 | //do nothing
19 | if ([searchWord isEqualToString:@""] && filterArray.count == 0) {
20 | return filterUrl;
21 | }
22 |
23 |
24 | NSDictionary *filterMapping = @{ @(HentaiFilterTypeDoujinshi) : @"f_doujinshi=1",
25 | @(HentaiFilterTypeManga) : @"f_manga=1",
26 | @(HentaiFilterTypeArtistcg) : @"f_artistcg=1",
27 | @(HentaiFilterTypeGamecg) : @"f_gamecg=1",
28 | @(HentaiFilterTypeWestern) : @"f_western=1",
29 | @(HentaiFilterTypeNonh) : @"f_non-h=1",
30 | @(HentaiFilterTypeImagesets) : @"f_imageset=1",
31 | @(HentaiFilterTypeCosplay) : @"f_cosplay=1",
32 | @(HentaiFilterTypeAsianporn) : @"f_asianporn=1",
33 | @(HentaiFilterTypeMisc) : @"f_misc=1" };
34 |
35 | if (filterArray.count != 0 || filterArray.count != 10) {
36 | for (NSNumber *filterNum in filterArray) {
37 | filterUrl = [filterUrl stringByAppendingString:[NSString stringWithFormat:@"&%@", filterMapping[filterNum]]];
38 | }
39 | }
40 |
41 | if (![searchWord isEqualToString:@""]) {
42 | filterUrl = [filterUrl stringByAppendingString:[NSString stringWithFormat:@"&f_search=%@", searchWord]];
43 | }
44 |
45 | //apply
46 | filterUrl = [filterUrl stringByAppendingString:@"&f_apply=Apply+Filter"];
47 |
48 | return filterUrl;
49 | }
50 |
51 | @end
52 |
--------------------------------------------------------------------------------
/e-Hentai/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "40x40",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "60x60",
16 | "scale" : "2x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/e-Hentai/Images.xcassets/LaunchImage.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "orientation" : "portrait",
5 | "idiom" : "iphone",
6 | "extent" : "full-screen",
7 | "minimum-system-version" : "7.0",
8 | "scale" : "2x"
9 | },
10 | {
11 | "orientation" : "portrait",
12 | "idiom" : "iphone",
13 | "subtype" : "retina4",
14 | "extent" : "full-screen",
15 | "minimum-system-version" : "7.0",
16 | "scale" : "2x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/e-Hentai/MainViewController/GalleryCell/CategoryTitle.h:
--------------------------------------------------------------------------------
1 | //
2 | // CategoryTitle.h
3 | // e-Hentai
4 | //
5 | // Created by Jack on 2014/9/5.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface CategoryTitle : UIView
12 | {
13 | NSString *categoryString;
14 | UILabel *categoryLabel;
15 | }
16 |
17 | - (void)setCategoryStr:(NSString *)category;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/e-Hentai/MainViewController/GalleryCell/CategoryTitle.m:
--------------------------------------------------------------------------------
1 | //
2 | // CategoryTitle.m
3 | // e-Hentai
4 | //
5 | // Created by Jack on 2014/9/5.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import "CategoryTitle.h"
10 |
11 | #define colorDoujinshi [UIColor colorWithRed:251.0 / 255.0 green:99.0 / 255.0 blue:102.0 / 255.0 alpha:1]
12 | #define colorManga [UIColor colorWithRed:252.0 / 255.0 green:194.0 / 255.0 blue:82.0 / 255.0 alpha:1]
13 | #define colorArtistcg [UIColor colorWithRed:238.0 / 255.0 green:230.0 / 255.0 blue:102.0 / 255.0 alpha:1]
14 | #define colorGamecg [UIColor colorWithRed:192.0 / 255.0 green:129.0 / 255.0 blue:127.0 / 255.0 alpha:1]
15 | #define colorWestern [UIColor colorWithRed:170.0 / 255.0 green:255.0 / 255.0 blue:87.0 / 255.0 alpha:1]
16 | #define colorNonh [UIColor colorWithRed:132.0 / 255.0 green:199.0 / 255.0 blue:255.0 / 255.0 alpha:1]
17 | #define colorImageset [UIColor colorWithRed:108.0 / 255.0 green:96.0 / 255.0 blue:255.0 / 255.0 alpha:1]
18 | #define colorCosplay [UIColor colorWithRed:144.0 / 255.0 green:97.0 / 255.0 blue:181.0 / 255.0 alpha:1]
19 | #define colorAsianporn [UIColor colorWithRed:245.0 / 255.0 green:175.0 / 255.0 blue:246.0 / 255.0 alpha:1]
20 | #define colorMisc [UIColor colorWithRed:219.0 / 255.0 green:219.0 / 255.0 blue:219.0 / 255.0 alpha:1]
21 |
22 | //Flat Blue
23 | #define CORLOR_TEXT [UIColor colorWithRed:52.0 / 255.0 green:152.0 / 255.0 blue:219.0 / 255.0 alpha:1]
24 |
25 | @implementation CategoryTitle
26 |
27 |
28 | - (id)initWithCoder:(NSCoder *)aDecoder {
29 | self = [super initWithCoder:aDecoder];
30 | if (self) {
31 | self.backgroundColor = [UIColor colorWithWhite:0 alpha:0.7];
32 | categoryString = @"";
33 | categoryLabel = [UILabel new];
34 | [self addSubview:categoryLabel];
35 | }
36 | return self;
37 | }
38 |
39 | - (void)setCategoryStr:(NSString *)category {
40 | categoryString = category;
41 | categoryLabel.textColor = [self colorMapping:category];
42 | [self layoutSubviews];
43 | }
44 |
45 | - (UIColor *)colorMapping:(NSString *)category {
46 | NSDictionary *mapping = @{ @"Doujinshi" : colorDoujinshi,
47 | @"Manga" : colorManga,
48 | @"Artist CG Sets" : colorArtistcg,
49 | @"Game CG Sets" : colorGamecg,
50 | @"Western" : colorWestern,
51 | @"Non-H" : colorNonh,
52 | @"Image Sets" : colorImageset,
53 | @"Cosplay" : colorCosplay,
54 | @"Asian Porn" : colorAsianporn };
55 | return mapping[category] ? : colorMisc;
56 | }
57 |
58 | - (void)layoutSubviews {
59 | CGRect labelFrame = CGRectOffset(self.bounds, 5, 0); //padding 5
60 | categoryLabel.frame = labelFrame;
61 | categoryLabel.backgroundColor = [UIColor clearColor];
62 | categoryLabel.font = [UIFont systemFontOfSize:14.0];
63 | categoryLabel.text = categoryString;
64 |
65 | self.layer.cornerRadius = CGRectGetHeight(self.bounds) / 4;
66 | }
67 |
68 | @end
69 |
--------------------------------------------------------------------------------
/e-Hentai/MainViewController/GalleryCell/GalleryCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // GalleryCell.h
3 | // e-Hentai
4 | //
5 | // Created by Jack on 2014/9/4.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #define imageMode @"IMAGE_MODE"
12 |
13 | @class CategoryTitle;
14 | @class RatingStar;
15 |
16 | @interface GalleryCell : UICollectionViewCell
17 |
18 | @property (weak, nonatomic) IBOutlet UILabel *cellLabel;
19 | @property (weak, nonatomic) IBOutlet UIImageView *cellImageView;
20 | @property (weak, nonatomic) IBOutlet CategoryTitle *cellCategory;
21 | @property (weak, nonatomic) IBOutlet RatingStar *cellStar;
22 |
23 | //設定資料
24 | - (void)setGalleryDict:(NSDictionary *)dataDict;
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/e-Hentai/MainViewController/GalleryCell/GalleryCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // GalleryCell.m
3 | // e-Hentai
4 | //
5 | // Created by Jack on 2014/9/4.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import "GalleryCell.h"
10 | #import "UIImageView+WebCache.h"
11 | #import "CategoryTitle.h"
12 | #import "RatingStar.h"
13 |
14 | @implementation GalleryCell
15 |
16 |
17 |
18 | #pragma mark -
19 |
20 | //設定資料
21 | - (void)setGalleryDict:(NSDictionary *)dataDict {
22 | self.cellLabel.text = dataDict[@"title"];
23 |
24 |
25 | BOOL enableImageMode = [dataDict[imageMode] boolValue];
26 |
27 | NSString *imgUrl = @"http://i.imgur.com/1gzbPf1.jpg"; //貓貓圖(公司用)
28 |
29 | if (enableImageMode) {
30 | imgUrl = dataDict[@"thumb"]; //(真的H縮圖)
31 | }
32 |
33 | [self.cellImageView sd_setImageWithURL:[NSURL URLWithString:imgUrl]
34 | placeholderImage:nil
35 | options:SDWebImageRefreshCached];
36 |
37 | [self.cellCategory setCategoryStr:dataDict[@"category"]];
38 | [self.cellStar setStar:dataDict[@"rating"]];
39 | }
40 |
41 | - (void)layoutSubviews {
42 | //Fit並置中
43 | self.cellImageView.contentMode = UIViewContentModeScaleAspectFit;
44 | self.cellImageView.clipsToBounds = YES;
45 | self.cellImageView.center = CGPointMake(self.cellImageView.center.x, CGRectGetMidY(self.bounds));
46 | self.layer.cornerRadius = CGRectGetHeight(self.cellCategory.frame) / 4;
47 | }
48 |
49 | @end
50 |
--------------------------------------------------------------------------------
/e-Hentai/MainViewController/GalleryCell/GalleryCell.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 |
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 |
--------------------------------------------------------------------------------
/e-Hentai/MainViewController/GalleryCell/RatingStar.h:
--------------------------------------------------------------------------------
1 | //
2 | // RatingStar.h
3 | // e-Hentai
4 | //
5 | // Created by Jack on 2014/9/5.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface RatingStar : UIView
12 | {
13 | NSString *starString;
14 | }
15 |
16 | - (void)setStar:(NSString *)star;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/e-Hentai/MainViewController/GalleryCell/RatingStar.m:
--------------------------------------------------------------------------------
1 | //
2 | // RatingStar.m
3 | // e-Hentai
4 | //
5 | // Created by Jack on 2014/9/5.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import "RatingStar.h"
10 |
11 |
12 |
13 | @implementation RatingStar
14 |
15 |
16 | - (id)initWithCoder:(NSCoder *)aDecoder {
17 | self = [super initWithCoder:aDecoder];
18 | if (self) {
19 | self.backgroundColor = [UIColor clearColor];
20 | starString = @"";
21 | }
22 | return self;
23 | }
24 |
25 | - (void)setStar:(NSString *)star {
26 | starString = star;
27 | [self setNeedsDisplay];
28 | }
29 |
30 | - (void)drawRect:(CGRect)rect {
31 |
32 | int aSize = CGRectGetWidth(rect);
33 | const CGFloat color[4] = { 255.0 / 255.0, 215.0 / 255.0, 0.0, 1.0 }; // Gold
34 | CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
35 | CGColorRef aColor = CGColorCreate(colorspace, color);
36 | CGContextRef context = UIGraphicsGetCurrentContext();
37 | CGContextSetLineWidth(context, aSize);
38 | CGFloat xCenter = CGRectGetMidX(rect);
39 | CGFloat yCenter = CGRectGetMidY(rect);
40 |
41 |
42 | float w = CGRectGetWidth(rect); //星形寬
43 | double r = w / 2.0;
44 | float flip = -1.0;
45 |
46 |
47 | CGContextSetFillColorWithColor(context, aColor);
48 | CGContextSetStrokeColorWithColor(context, aColor);
49 |
50 | double theta = 2.0 * M_PI * (2.0 / 5.0); // 144 degrees
51 |
52 | CGContextMoveToPoint(context, xCenter, r * flip + yCenter);
53 |
54 | for (NSUInteger k = 1; k < 5; k++) {
55 | float x = r * sin(k * theta);
56 | float y = r * cos(k * theta);
57 | CGContextAddLineToPoint(context, x + xCenter, y * flip + yCenter);
58 | }
59 |
60 | CGContextClosePath(context);
61 | CGContextFillPath(context);
62 |
63 | CGFloat fontSize = CGRectGetWidth(rect) / 2;
64 |
65 | NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
66 | style.alignment = NSTextAlignmentCenter;
67 |
68 | NSDictionary *attributes = @{ NSFontAttributeName:[UIFont systemFontOfSize:fontSize],
69 | NSForegroundColorAttributeName:[UIColor blackColor],
70 | NSParagraphStyleAttributeName:style };
71 |
72 | NSString *star = [starString substringToIndex:1];
73 | NSAttributedString *attrStr = [[NSAttributedString alloc] initWithString:star attributes:attributes];
74 |
75 |
76 | [attrStr drawInRect:CGRectMake(CGRectGetMidX(rect) - fontSize / 2,
77 | CGRectGetMidY(rect) - fontSize / 2,
78 | fontSize,
79 | fontSize)];
80 | CGColorRelease(aColor);
81 | CGColorSpaceRelease(colorspace);
82 | }
83 |
84 | @end
85 |
--------------------------------------------------------------------------------
/e-Hentai/MainViewController/MainViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // MainViewController.h
3 | // TEST_2014_9_2
4 | //
5 | // Created by 啟倫 陳 on 2014/9/2.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "HentaiParser.h"
12 | #import "GalleryCell.h"
13 | #import "HentaiNavigationController.h"
14 | #import "PhotoViewController.h"
15 | #import "FakeViewController.h"
16 |
17 | @interface MainViewController : UIViewController
18 |
19 | @property (weak, nonatomic) IBOutlet UICollectionView *listCollectionView;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/e-Hentai/MainViewController/MainViewController.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 |
--------------------------------------------------------------------------------
/e-Hentai/PhotoViewController/HentaiPhotoCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // HentaiPhotoCell.h
3 | // e-Hentai
4 | //
5 | // Created by 啟倫 陳 on 2014/9/4.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface HentaiPhotoCell : UITableViewCell
12 |
13 | @property (weak, nonatomic) IBOutlet UIImageView *hentaiImageView;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/e-Hentai/PhotoViewController/HentaiPhotoCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // HentaiPhotoCell.m
3 | // e-Hentai
4 | //
5 | // Created by 啟倫 陳 on 2014/9/4.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import "HentaiPhotoCell.h"
10 |
11 | @implementation HentaiPhotoCell
12 |
13 | - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
14 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
15 | if (self) {
16 | NSArray *arrayOfViews = [[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:self options:nil];
17 | self = arrayOfViews[0];
18 | }
19 | return self;
20 | }
21 |
22 | - (void)layoutSubviews {
23 | [super layoutSubviews];
24 | self.hentaiImageView.frame = self.bounds;
25 | }
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/e-Hentai/PhotoViewController/HentaiPhotoCell.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 |
--------------------------------------------------------------------------------
/e-Hentai/PhotoViewController/PhotoViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // PhotoViewController.h
3 | // TEST_2014_9_2
4 | //
5 | // Created by 啟倫 陳 on 2014/9/3.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "HentaiNavigationController.h"
12 | #import "FakeViewController.h"
13 | #import "HentaiPhotoCell.h"
14 | #import "HentaiDownloadImageOperation.h"
15 |
16 | @interface PhotoViewController : UIViewController
17 |
18 | @property (nonatomic, strong) NSDictionary *hentaiInfo;
19 |
20 | @property (weak, nonatomic) IBOutlet UITableView *hentaiTableView;
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/e-Hentai/PhotoViewController/PhotoViewController.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 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/FilesManager/FMStream.h:
--------------------------------------------------------------------------------
1 | //
2 | // FMStream.h
3 | // TycheToolsV2
4 | //
5 | // Created by 啟倫 陳 on 2014/6/30.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface FMStream : NSObject
12 |
13 | @property (nonatomic, strong) NSString *basePath;
14 | @property (nonatomic, strong) NSMutableArray *subPaths;
15 |
16 | @end
17 |
18 | @interface FMStream (Information)
19 |
20 | - (NSArray *)listFiles;
21 | - (NSArray *)listFolders;
22 | - (NSString *)currentPath;
23 |
24 | @end
25 |
26 | @interface FMStream (Folder)
27 |
28 | - (FMStream *)cdpp;
29 | - (FMStream *)cd:(NSString *)folder;
30 | - (FMStream *)fcd:(NSString *)folder;
31 |
32 | - (FMStream *)md:(NSString *)folder;
33 | - (FMStream *)rd:(NSString *)folder;
34 |
35 | - (void)moveToPath:(NSString *)toPath;
36 |
37 | @end
38 |
39 | @interface FMStream (IO)
40 |
41 | - (BOOL)write:(NSData *)data filename:(NSString *)name;
42 | - (NSData *)read:(NSString *)name;
43 |
44 | @end
45 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/FilesManager/FMStream.m:
--------------------------------------------------------------------------------
1 | //
2 | // FMStream.m
3 | // TycheToolsV2
4 | //
5 | // Created by 啟倫 陳 on 2014/6/30.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import "FMStream.h"
10 |
11 | @implementation FMStream
12 |
13 | - (id)init {
14 | self = [super init];
15 | if (self) {
16 | self.subPaths = [NSMutableArray array];
17 | }
18 | return self;
19 | }
20 |
21 | - (NSString *)tmpPath:(NSString *)folder {
22 | NSMutableArray *tmpSubPaths = [NSMutableArray arrayWithArray:self.subPaths];
23 | [tmpSubPaths addObject:folder];
24 | return [self.basePath stringByAppendingPathComponent:[tmpSubPaths componentsJoinedByString:@"/"]];
25 | }
26 |
27 | @end
28 |
29 | @implementation FMStream (Information)
30 |
31 | - (NSArray *)listFiles {
32 | NSFileManager *fileManager = [NSFileManager defaultManager];
33 | NSArray *itemsArray = [fileManager contentsOfDirectoryAtPath:[self currentPath] error:nil];
34 | NSMutableArray *filesArray = [NSMutableArray array];
35 | BOOL isFolder;
36 |
37 | for (NSString *item in itemsArray) {
38 | NSString *itempath = [[self currentPath] stringByAppendingPathComponent:item];
39 | [fileManager fileExistsAtPath:itempath isDirectory:(&isFolder)];
40 |
41 | if (!isFolder) {
42 | [filesArray addObject:item];
43 | }
44 | }
45 | return filesArray;
46 | }
47 |
48 | - (NSArray *)listFolders {
49 | NSFileManager *fileManager = [NSFileManager defaultManager];
50 | NSArray *itemsArray = [fileManager contentsOfDirectoryAtPath:[self currentPath] error:nil];
51 | NSMutableArray *foldersArray = [NSMutableArray array];
52 | BOOL isFolder;
53 |
54 | for (NSString *item in itemsArray) {
55 | NSString *itempath = [[self currentPath] stringByAppendingPathComponent:item];
56 | [fileManager fileExistsAtPath:itempath isDirectory:(&isFolder)];
57 |
58 | if (isFolder) {
59 | [foldersArray addObject:item];
60 | }
61 | }
62 | return foldersArray;
63 | }
64 |
65 | - (NSString *)currentPath {
66 | return [self.basePath stringByAppendingPathComponent:[self.subPaths componentsJoinedByString:@"/"]];
67 | }
68 |
69 | @end
70 |
71 |
72 | @implementation FMStream (Folder)
73 |
74 | - (FMStream *)cdpp {
75 | [self.subPaths removeLastObject];
76 | return self;
77 | }
78 |
79 | - (FMStream *)cd:(NSString *)folder {
80 | NSFileManager *fileManager = [NSFileManager defaultManager];
81 |
82 | if ([fileManager fileExistsAtPath:[self tmpPath:folder]]) {
83 | [self.subPaths addObject:folder];
84 | return self;
85 | }
86 | else {
87 | return nil;
88 | }
89 | }
90 |
91 | - (FMStream *)fcd:(NSString *)folder {
92 | NSFileManager *fileManager = [NSFileManager defaultManager];
93 |
94 | if ([fileManager fileExistsAtPath:[self tmpPath:folder]]) {
95 | [self.subPaths addObject:folder];
96 | }
97 | else {
98 | [[self md:folder] cd:folder];
99 | }
100 | return self;
101 | }
102 |
103 | - (FMStream *)md:(NSString *)folder {
104 | NSFileManager *fileManager = [NSFileManager defaultManager];
105 |
106 | if (![fileManager fileExistsAtPath:[self tmpPath:folder]]) {
107 | if ([[NSFileManager defaultManager] createDirectoryAtPath:[self tmpPath:folder] withIntermediateDirectories:NO attributes:nil error:nil]) {
108 | return self;
109 | }
110 | }
111 | return nil;
112 | }
113 |
114 | - (FMStream *)rd:(NSString *)folder {
115 | NSFileManager *fileManager = [NSFileManager defaultManager];
116 |
117 | if ([fileManager fileExistsAtPath:[self tmpPath:folder]]) {
118 | if ([fileManager removeItemAtPath:[self tmpPath:folder] error:nil]) {
119 | return self;
120 | }
121 | }
122 | return nil;
123 | }
124 |
125 | - (void)moveToPath:(NSString *)toPath {
126 | NSFileManager *fileManager = [NSFileManager defaultManager];
127 | [fileManager moveItemAtPath:self.currentPath toPath:toPath error:nil];
128 | }
129 |
130 | @end
131 |
132 |
133 | @implementation FMStream (IO)
134 |
135 | - (BOOL)write:(NSData *)data filename:(NSString *)name {
136 | return [data writeToFile:[[self currentPath] stringByAppendingPathComponent:name] atomically:YES];
137 | }
138 |
139 | - (NSData *)read:(NSString *)name {
140 | return [[NSFileManager defaultManager] contentsAtPath:[[self currentPath] stringByAppendingPathComponent:name]];
141 | }
142 |
143 | @end
144 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/FilesManager/FilesManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // FilesManager.h
3 | // TycheToolsV2
4 | //
5 | // Created by 啟倫 陳 on 2014/6/30.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import "FMStream.h"
10 |
11 | @interface FilesManager : FMStream
12 |
13 | + (FMStream *)documentFolder;
14 | + (FMStream *)resourceFolder;
15 | + (FMStream *)cacheFolder;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/FilesManager/FilesManager.m:
--------------------------------------------------------------------------------
1 | //
2 | // FilesManager.m
3 | // TycheToolsV2
4 | //
5 | // Created by 啟倫 陳 on 2014/6/30.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import "FilesManager.h"
10 |
11 | @implementation FilesManager
12 |
13 | #pragma mark - class method
14 |
15 | + (FMStream *)documentFolder {
16 | FMStream *newStream = [FMStream new];
17 | newStream.basePath = [self documentFolderPathString];
18 | return newStream;
19 | }
20 |
21 | + (FMStream *)resourceFolder {
22 | FMStream *newStream = [FMStream new];
23 | newStream.basePath = [self resourceFolderPathString];
24 | return newStream;
25 | }
26 |
27 | + (FMStream *)cacheFolder {
28 | FMStream *newStream = [FMStream new];
29 | newStream.basePath = [self cacheFolderPathString];
30 | return newStream;
31 | }
32 |
33 | #pragma mark - private
34 |
35 | + (NSString *)documentFolderPathString {
36 | NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
37 | return paths[0];
38 | }
39 |
40 | + (NSString *)resourceFolderPathString {
41 | return [[NSBundle mainBundle] bundlePath];
42 | }
43 |
44 | + (NSString *)cacheFolderPathString {
45 | NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
46 | return paths[0];
47 | }
48 |
49 | @end
50 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/Hpple/TFHpple.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFHpple.h
3 | // Hpple
4 | //
5 | // Created by Geoffrey Grosenbach on 1/31/09.
6 | //
7 | // Copyright (c) 2009 Topfunky Corporation, http://topfunky.com
8 | //
9 | // MIT LICENSE
10 | //
11 | // Permission is hereby granted, free of charge, to any person obtaining
12 | // a copy of this software and associated documentation files (the
13 | // "Software"), to deal in the Software without restriction, including
14 | // without limitation the rights to use, copy, modify, merge, publish,
15 | // distribute, sublicense, and/or sell copies of the Software, and to
16 | // permit persons to whom the Software is furnished to do so, subject to
17 | // the following conditions:
18 | //
19 | // The above copyright notice and this permission notice shall be
20 | // included in all copies or substantial portions of the Software.
21 | //
22 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 |
30 |
31 | #import
32 |
33 | #import "TFHppleElement.h"
34 |
35 | @interface TFHpple : NSObject
36 |
37 | - (id) initWithData:(NSData *)theData encoding:(NSString *)encoding isXML:(BOOL)isDataXML;
38 | - (id) initWithData:(NSData *)theData isXML:(BOOL)isDataXML;
39 | - (id) initWithXMLData:(NSData *)theData encoding:(NSString *)encoding;
40 | - (id) initWithXMLData:(NSData *)theData;
41 | - (id) initWithHTMLData:(NSData *)theData encoding:(NSString *)encoding;
42 | - (id) initWithHTMLData:(NSData *)theData;
43 |
44 | + (TFHpple *) hppleWithData:(NSData *)theData encoding:(NSString *)encoding isXML:(BOOL)isDataXML;
45 | + (TFHpple *) hppleWithData:(NSData *)theData isXML:(BOOL)isDataXML;
46 | + (TFHpple *) hppleWithXMLData:(NSData *)theData encoding:(NSString *)encoding;
47 | + (TFHpple *) hppleWithXMLData:(NSData *)theData;
48 | + (TFHpple *) hppleWithHTMLData:(NSData *)theData encoding:(NSString *)encoding;
49 | + (TFHpple *) hppleWithHTMLData:(NSData *)theData;
50 |
51 | - (NSArray *) searchWithXPathQuery:(NSString *)xPathOrCSS;
52 | - (TFHppleElement *) peekAtSearchWithXPathQuery:(NSString *)xPathOrCSS;
53 |
54 | @property (nonatomic, readonly) NSData * data;
55 | @property (nonatomic, readonly) NSString * encoding;
56 |
57 | @end
58 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/Hpple/TFHpple.m:
--------------------------------------------------------------------------------
1 | //
2 | // TFHpple.m
3 | // Hpple
4 | //
5 | // Created by Geoffrey Grosenbach on 1/31/09.
6 | //
7 | // Copyright (c) 2009 Topfunky Corporation, http://topfunky.com
8 | //
9 | // MIT LICENSE
10 | //
11 | // Permission is hereby granted, free of charge, to any person obtaining
12 | // a copy of this software and associated documentation files (the
13 | // "Software"), to deal in the Software without restriction, including
14 | // without limitation the rights to use, copy, modify, merge, publish,
15 | // distribute, sublicense, and/or sell copies of the Software, and to
16 | // permit persons to whom the Software is furnished to do so, subject to
17 | // the following conditions:
18 | //
19 | // The above copyright notice and this permission notice shall be
20 | // included in all copies or substantial portions of the Software.
21 | //
22 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 |
30 | #import "TFHpple.h"
31 | #import "XPathQuery.h"
32 |
33 | @interface TFHpple ()
34 | {
35 | NSData * data;
36 | NSString * encoding;
37 | BOOL isXML;
38 | }
39 |
40 | @end
41 |
42 |
43 | @implementation TFHpple
44 |
45 | @synthesize data;
46 | @synthesize encoding;
47 |
48 |
49 | - (id) initWithData:(NSData *)theData encoding:(NSString *)theEncoding isXML:(BOOL)isDataXML
50 | {
51 | if (!(self = [super init])) {
52 | return nil;
53 | }
54 |
55 | data = theData;
56 | encoding = theEncoding;
57 | isXML = isDataXML;
58 |
59 | return self;
60 | }
61 |
62 | - (id) initWithData:(NSData *)theData isXML:(BOOL)isDataXML
63 | {
64 | return [self initWithData:theData encoding:nil isXML:isDataXML];
65 | }
66 |
67 | - (id) initWithXMLData:(NSData *)theData encoding:(NSString *)theEncoding
68 | {
69 | return [self initWithData:theData encoding:theEncoding isXML:YES];
70 | }
71 |
72 | - (id) initWithXMLData:(NSData *)theData
73 | {
74 | return [self initWithData:theData encoding:nil isXML:YES];
75 | }
76 |
77 | - (id) initWithHTMLData:(NSData *)theData encoding:(NSString *)theEncoding
78 | {
79 | return [self initWithData:theData encoding:theEncoding isXML:NO];
80 | }
81 |
82 | - (id) initWithHTMLData:(NSData *)theData
83 | {
84 | return [self initWithData:theData encoding:nil isXML:NO];
85 | }
86 |
87 | + (TFHpple *) hppleWithData:(NSData *)theData encoding:(NSString *)theEncoding isXML:(BOOL)isDataXML {
88 | return [[[self class] alloc] initWithData:theData encoding:theEncoding isXML:isDataXML];
89 | }
90 |
91 | + (TFHpple *) hppleWithData:(NSData *)theData isXML:(BOOL)isDataXML {
92 | return [[self class] hppleWithData:theData encoding:nil isXML:isDataXML];
93 | }
94 |
95 | + (TFHpple *) hppleWithHTMLData:(NSData *)theData encoding:(NSString *)theEncoding {
96 | return [[self class] hppleWithData:theData encoding:theEncoding isXML:NO];
97 | }
98 |
99 | + (TFHpple *) hppleWithHTMLData:(NSData *)theData {
100 | return [[self class] hppleWithData:theData encoding:nil isXML:NO];
101 | }
102 |
103 | + (TFHpple *) hppleWithXMLData:(NSData *)theData encoding:(NSString *)theEncoding {
104 | return [[self class] hppleWithData:theData encoding:theEncoding isXML:YES];
105 | }
106 |
107 | + (TFHpple *) hppleWithXMLData:(NSData *)theData {
108 | return [[self class] hppleWithData:theData encoding:nil isXML:YES];
109 | }
110 |
111 | #pragma mark -
112 |
113 | // Returns all elements at xPath.
114 | - (NSArray *) searchWithXPathQuery:(NSString *)xPathOrCSS
115 | {
116 | NSArray * detailNodes = nil;
117 | if (isXML) {
118 | detailNodes = PerformXMLXPathQueryWithEncoding(data, xPathOrCSS, encoding);
119 | } else {
120 | detailNodes = PerformHTMLXPathQueryWithEncoding(data, xPathOrCSS, encoding);
121 | }
122 |
123 | NSMutableArray * hppleElements = [NSMutableArray array];
124 | for (id node in detailNodes) {
125 | [hppleElements addObject:[TFHppleElement hppleElementWithNode:node isXML:isXML withEncoding:encoding]];
126 | }
127 | return hppleElements;
128 | }
129 |
130 | // Returns first element at xPath
131 | - (TFHppleElement *) peekAtSearchWithXPathQuery:(NSString *)xPathOrCSS
132 | {
133 | NSArray * elements = [self searchWithXPathQuery:xPathOrCSS];
134 | if ([elements count] >= 1) {
135 | return [elements objectAtIndex:0];
136 | }
137 |
138 | return nil;
139 | }
140 |
141 | @end
142 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/Hpple/TFHppleElement.h:
--------------------------------------------------------------------------------
1 | //
2 | // TFHppleElement.h
3 | // Hpple
4 | //
5 | // Created by Geoffrey Grosenbach on 1/31/09.
6 | //
7 | // Copyright (c) 2009 Topfunky Corporation, http://topfunky.com
8 | //
9 | // MIT LICENSE
10 | //
11 | // Permission is hereby granted, free of charge, to any person obtaining
12 | // a copy of this software and associated documentation files (the
13 | // "Software"), to deal in the Software without restriction, including
14 | // without limitation the rights to use, copy, modify, merge, publish,
15 | // distribute, sublicense, and/or sell copies of the Software, and to
16 | // permit persons to whom the Software is furnished to do so, subject to
17 | // the following conditions:
18 | //
19 | // The above copyright notice and this permission notice shall be
20 | // included in all copies or substantial portions of the Software.
21 | //
22 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 |
30 | #import
31 |
32 |
33 | @interface TFHppleElement : NSObject
34 |
35 | - (id) initWithNode:(NSDictionary *) theNode isXML:(BOOL)isDataXML withEncoding:(NSString *)theEncoding;
36 |
37 | + (TFHppleElement *) hppleElementWithNode:(NSDictionary *) theNode isXML:(BOOL)isDataXML withEncoding:(NSString *)theEncoding;
38 |
39 | @property (nonatomic, copy, readonly) NSString *raw;
40 | // Returns this tag's innerHTML content.
41 | @property (nonatomic, copy, readonly) NSString *content;
42 |
43 | // Returns the name of the current tag, such as "h3".
44 | @property (nonatomic, copy, readonly) NSString *tagName;
45 |
46 | // Returns tag attributes with name as key and content as value.
47 | // href = 'http://peepcode.com'
48 | // class = 'highlight'
49 | @property (nonatomic, strong, readonly) NSDictionary *attributes;
50 |
51 | // Returns the children of a given node
52 | @property (nonatomic, strong, readonly) NSArray *children;
53 |
54 | // Returns the first child of a given node
55 | @property (nonatomic, strong, readonly) TFHppleElement *firstChild;
56 |
57 | // the parent of a node
58 | @property (nonatomic, unsafe_unretained, readonly) TFHppleElement *parent;
59 |
60 | // Returns YES if the node has any child
61 | // This is more efficient than using the children property since no NSArray is constructed
62 | - (BOOL)hasChildren;
63 |
64 | // Returns YES if this is a text node
65 | - (BOOL)isTextNode;
66 |
67 | // Provides easy access to the content of a specific attribute,
68 | // such as 'href' or 'class'.
69 | - (NSString *) objectForKey:(NSString *) theKey;
70 |
71 | // Returns the children whose tag name equals the given string
72 | // (comparison is performed with NSString's isEqualToString)
73 | // Returns an empty array if no matching child is found
74 | - (NSArray *) childrenWithTagName:(NSString *)tagName;
75 |
76 | // Returns the first child node whose tag name equals the given string
77 | // (comparison is performed with NSString's isEqualToString)
78 | // Returns nil if no matching child is found
79 | - (TFHppleElement *) firstChildWithTagName:(NSString *)tagName;
80 |
81 | // Returns the children whose class equals the given string
82 | // (comparison is performed with NSString's isEqualToString)
83 | // Returns an empty array if no matching child is found
84 | - (NSArray *) childrenWithClassName:(NSString *)className;
85 |
86 | // Returns the first child whose class requals the given string
87 | // (comparison is performed with NSString's isEqualToString)
88 | // Returns nil if no matching child is found
89 | - (TFHppleElement *) firstChildWithClassName:(NSString*)className;
90 |
91 | // Returns the first text node from this element's children
92 | // Returns nil if there is no text node among the children
93 | - (TFHppleElement *) firstTextChild;
94 |
95 | // Returns the string contained by the first text node from this element's children
96 | // Convenience method which can be used instead of firstTextChild.content
97 | - (NSString *) text;
98 |
99 | // Returns elements searched with xpath
100 | - (NSArray *) searchWithXPathQuery:(NSString *)xPathOrCSS;
101 |
102 | // Custom keyed subscripting
103 | - (id)objectForKeyedSubscript:(id)key;
104 |
105 |
106 | @end
107 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/Hpple/TFHppleElement.m:
--------------------------------------------------------------------------------
1 | //
2 | // TFHppleElement.m
3 | // Hpple
4 | //
5 | // Created by Geoffrey Grosenbach on 1/31/09.
6 | //
7 | // Copyright (c) 2009 Topfunky Corporation, http://topfunky.com
8 | //
9 | // MIT LICENSE
10 | //
11 | // Permission is hereby granted, free of charge, to any person obtaining
12 | // a copy of this software and associated documentation files (the
13 | // "Software"), to deal in the Software without restriction, including
14 | // without limitation the rights to use, copy, modify, merge, publish,
15 | // distribute, sublicense, and/or sell copies of the Software, and to
16 | // permit persons to whom the Software is furnished to do so, subject to
17 | // the following conditions:
18 | //
19 | // The above copyright notice and this permission notice shall be
20 | // included in all copies or substantial portions of the Software.
21 | //
22 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 |
30 |
31 | #import "TFHppleElement.h"
32 | #import "XPathQuery.h"
33 |
34 | static NSString * const TFHppleNodeContentKey = @"nodeContent";
35 | static NSString * const TFHppleNodeNameKey = @"nodeName";
36 | static NSString * const TFHppleNodeChildrenKey = @"nodeChildArray";
37 | static NSString * const TFHppleNodeAttributeArrayKey = @"nodeAttributeArray";
38 | static NSString * const TFHppleNodeAttributeNameKey = @"attributeName";
39 |
40 | static NSString * const TFHppleTextNodeName = @"text";
41 |
42 | @interface TFHppleElement ()
43 | {
44 | NSDictionary * node;
45 | BOOL isXML;
46 | NSString *encoding;
47 | __unsafe_unretained TFHppleElement *parent;
48 | }
49 |
50 | @property (nonatomic, unsafe_unretained, readwrite) TFHppleElement *parent;
51 |
52 | @end
53 |
54 | @implementation TFHppleElement
55 | @synthesize parent;
56 |
57 |
58 | - (id) initWithNode:(NSDictionary *) theNode isXML:(BOOL)isDataXML withEncoding:(NSString *)theEncoding
59 | {
60 | if (!(self = [super init]))
61 | return nil;
62 |
63 | isXML = isDataXML;
64 | node = theNode;
65 | encoding = theEncoding;
66 |
67 | return self;
68 | }
69 |
70 | + (TFHppleElement *) hppleElementWithNode:(NSDictionary *) theNode isXML:(BOOL)isDataXML withEncoding:(NSString *)theEncoding
71 | {
72 | return [[[self class] alloc] initWithNode:theNode isXML:isDataXML withEncoding:theEncoding];
73 | }
74 |
75 | #pragma mark -
76 |
77 | - (NSString *)raw
78 | {
79 | return [node objectForKey:@"raw"];
80 | }
81 |
82 | - (NSString *) content
83 | {
84 | return [node objectForKey:TFHppleNodeContentKey];
85 | }
86 |
87 |
88 | - (NSString *) tagName
89 | {
90 | return [node objectForKey:TFHppleNodeNameKey];
91 | }
92 |
93 | - (NSArray *) children
94 | {
95 | NSMutableArray *children = [NSMutableArray array];
96 | for (NSDictionary *child in [node objectForKey:TFHppleNodeChildrenKey]) {
97 | TFHppleElement *element = [TFHppleElement hppleElementWithNode:child isXML:isXML withEncoding:encoding];
98 | element.parent = self;
99 | [children addObject:element];
100 | }
101 | return children;
102 | }
103 |
104 | - (TFHppleElement *) firstChild
105 | {
106 | NSArray * children = self.children;
107 | if (children.count)
108 | return [children objectAtIndex:0];
109 | return nil;
110 | }
111 |
112 |
113 | - (NSDictionary *) attributes
114 | {
115 | NSMutableDictionary * translatedAttributes = [NSMutableDictionary dictionary];
116 | for (NSDictionary * attributeDict in [node objectForKey:TFHppleNodeAttributeArrayKey]) {
117 | if ([attributeDict objectForKey:TFHppleNodeContentKey] && [attributeDict objectForKey:TFHppleNodeAttributeNameKey]) {
118 | [translatedAttributes setObject:[attributeDict objectForKey:TFHppleNodeContentKey]
119 | forKey:[attributeDict objectForKey:TFHppleNodeAttributeNameKey]];
120 | }
121 | }
122 | return translatedAttributes;
123 | }
124 |
125 | - (NSString *) objectForKey:(NSString *) theKey
126 | {
127 | return [[self attributes] objectForKey:theKey];
128 | }
129 |
130 | - (id) description
131 | {
132 | return [node description];
133 | }
134 |
135 | - (BOOL)hasChildren
136 | {
137 | if ([node objectForKey:TFHppleNodeChildrenKey])
138 | return YES;
139 | else
140 | return NO;
141 | }
142 |
143 | - (BOOL)isTextNode
144 | {
145 | // we must distinguish between real text nodes and standard nodes with tha name "text" ()
146 | // real text nodes must have content
147 | if ([self.tagName isEqualToString:TFHppleTextNodeName] && (self.content))
148 | return YES;
149 | else
150 | return NO;
151 | }
152 |
153 | - (NSArray*) childrenWithTagName:(NSString*)tagName
154 | {
155 | NSMutableArray* matches = [NSMutableArray array];
156 |
157 | for (TFHppleElement* child in self.children)
158 | {
159 | if ([child.tagName isEqualToString:tagName])
160 | [matches addObject:child];
161 | }
162 |
163 | return matches;
164 | }
165 |
166 | - (TFHppleElement *) firstChildWithTagName:(NSString*)tagName
167 | {
168 | for (TFHppleElement* child in self.children)
169 | {
170 | if ([child.tagName isEqualToString:tagName])
171 | return child;
172 | }
173 |
174 | return nil;
175 | }
176 |
177 | - (NSArray*) childrenWithClassName:(NSString*)className
178 | {
179 | NSMutableArray* matches = [NSMutableArray array];
180 |
181 | for (TFHppleElement* child in self.children)
182 | {
183 | if ([[child objectForKey:@"class"] isEqualToString:className])
184 | [matches addObject:child];
185 | }
186 |
187 | return matches;
188 | }
189 |
190 | - (TFHppleElement *) firstChildWithClassName:(NSString*)className
191 | {
192 | for (TFHppleElement* child in self.children)
193 | {
194 | if ([[child objectForKey:@"class"] isEqualToString:className])
195 | return child;
196 | }
197 |
198 | return nil;
199 | }
200 |
201 | - (TFHppleElement *) firstTextChild
202 | {
203 | for (TFHppleElement* child in self.children)
204 | {
205 | if ([child isTextNode])
206 | return child;
207 | }
208 |
209 | return [self firstChildWithTagName:TFHppleTextNodeName];
210 | }
211 |
212 | - (NSString *) text
213 | {
214 | return self.firstTextChild.content;
215 | }
216 |
217 | // Returns all elements at xPath.
218 | - (NSArray *) searchWithXPathQuery:(NSString *)xPathOrCSS
219 | {
220 |
221 | NSData *data = [self.raw dataUsingEncoding:NSUTF8StringEncoding];
222 |
223 | NSArray * detailNodes = nil;
224 | if (isXML) {
225 | detailNodes = PerformXMLXPathQueryWithEncoding(data, xPathOrCSS, encoding);
226 | } else {
227 | detailNodes = PerformHTMLXPathQueryWithEncoding(data, xPathOrCSS, encoding);
228 | }
229 |
230 | NSMutableArray * hppleElements = [NSMutableArray array];
231 | for (id newNode in detailNodes) {
232 | [hppleElements addObject:[TFHppleElement hppleElementWithNode:newNode isXML:isXML withEncoding:encoding]];
233 | }
234 | return hppleElements;
235 | }
236 |
237 | // Custom keyed subscripting
238 | - (id)objectForKeyedSubscript:(id)key
239 | {
240 | return [self objectForKey:key];
241 | }
242 |
243 | @end
244 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/Hpple/XPathQuery.h:
--------------------------------------------------------------------------------
1 | //
2 | // XPathQuery.h
3 | // FuelFinder
4 | //
5 | // Created by Matt Gallagher on 4/08/08.
6 | // Copyright 2008 __MyCompanyName__. All rights reserved.
7 | //
8 |
9 | NSArray *PerformHTMLXPathQuery(NSData *document, NSString *query);
10 | NSArray *PerformHTMLXPathQueryWithEncoding(NSData *document, NSString *query,NSString *encoding);
11 | NSArray *PerformXMLXPathQuery(NSData *document, NSString *query);
12 | NSArray *PerformXMLXPathQueryWithEncoding(NSData *document, NSString *query,NSString *encoding);
13 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/Hpple/XPathQuery.m:
--------------------------------------------------------------------------------
1 | //
2 | // XPathQuery.m
3 | // FuelFinder
4 | //
5 | // Created by Matt Gallagher on 4/08/08.
6 | // Copyright 2008 __MyCompanyName__. All rights reserved.
7 | //
8 |
9 | #import "XPathQuery.h"
10 |
11 | #import
12 | #import
13 | #import
14 | #import
15 | #import
16 |
17 | NSDictionary *DictionaryForNode(xmlNodePtr currentNode, NSMutableDictionary *parentResult,BOOL parentContent);
18 | NSArray *PerformXPathQuery(xmlDocPtr doc, NSString *query);
19 |
20 | NSDictionary *DictionaryForNode(xmlNodePtr currentNode, NSMutableDictionary *parentResult,BOOL parentContent)
21 | {
22 | NSMutableDictionary *resultForNode = [NSMutableDictionary dictionary];
23 |
24 | if (currentNode->name)
25 | {
26 | NSString *currentNodeContent =
27 | [NSString stringWithCString:(const char *)currentNode->name encoding:NSUTF8StringEncoding];
28 | [resultForNode setObject:currentNodeContent forKey:@"nodeName"];
29 | }
30 |
31 | if (currentNode->content && currentNode->content != (xmlChar *)-1)
32 | {
33 | NSString *currentNodeContent =
34 | [NSString stringWithCString:(const char *)currentNode->content encoding:NSUTF8StringEncoding];
35 |
36 | if ([[resultForNode objectForKey:@"nodeName"] isEqual:@"text"] && parentResult)
37 | {
38 | if(parentContent)
39 | {
40 | [parentResult setObject:[currentNodeContent stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] forKey:@"nodeContent"];
41 | return nil;
42 | }
43 | if (currentNodeContent != nil)
44 | {
45 | [resultForNode setObject:currentNodeContent forKey:@"nodeContent"];
46 | }
47 | // NSLog(@"content: %@",currentNodeContent);
48 | return resultForNode;
49 |
50 | }
51 | else {
52 | [resultForNode setObject:currentNodeContent forKey:@"nodeContent"];
53 | }
54 |
55 |
56 | }
57 |
58 | xmlAttr *attribute = currentNode->properties;
59 | if (attribute)
60 | {
61 | NSMutableArray *attributeArray = [NSMutableArray array];
62 | while (attribute)
63 | {
64 | NSMutableDictionary *attributeDictionary = [NSMutableDictionary dictionary];
65 | NSString *attributeName =
66 | [NSString stringWithCString:(const char *)attribute->name encoding:NSUTF8StringEncoding];
67 | if (attributeName)
68 | {
69 | // NSLog(@"Attribute Name Set: %@",attributeName);
70 | [attributeDictionary setObject:attributeName forKey:@"attributeName"];
71 | }
72 |
73 | if (attribute->children)
74 | {
75 | NSDictionary *childDictionary = DictionaryForNode(attribute->children, attributeDictionary,true);
76 | if (childDictionary)
77 | {
78 | [attributeDictionary setObject:childDictionary forKey:@"attributeContent"];
79 | }
80 | }
81 |
82 | if ([attributeDictionary count] > 0)
83 | {
84 | [attributeArray addObject:attributeDictionary];
85 | }
86 | attribute = attribute->next;
87 | }
88 |
89 | if ([attributeArray count] > 0)
90 | {
91 | [resultForNode setObject:attributeArray forKey:@"nodeAttributeArray"];
92 | }
93 | }
94 |
95 | xmlNodePtr childNode = currentNode->children;
96 | if (childNode)
97 | {
98 | NSMutableArray *childContentArray = [NSMutableArray array];
99 | while (childNode)
100 | {
101 | NSDictionary *childDictionary = DictionaryForNode(childNode, resultForNode,false);
102 | if (childDictionary)
103 | {
104 | [childContentArray addObject:childDictionary];
105 | }
106 | childNode = childNode->next;
107 | }
108 | if ([childContentArray count] > 0)
109 | {
110 | [resultForNode setObject:childContentArray forKey:@"nodeChildArray"];
111 | }
112 | }
113 |
114 | xmlBufferPtr buffer = xmlBufferCreate();
115 | xmlNodeDump(buffer, currentNode->doc, currentNode, 0, 0);
116 |
117 | NSString *rawContent = [NSString stringWithCString:(const char *)buffer->content encoding:NSUTF8StringEncoding];
118 | if (rawContent != nil)
119 | {
120 | [resultForNode setObject:rawContent forKey:@"raw"];
121 | }
122 | xmlBufferFree(buffer);
123 |
124 | return resultForNode;
125 | }
126 |
127 | NSArray *PerformXPathQuery(xmlDocPtr doc, NSString *query)
128 | {
129 | xmlXPathContextPtr xpathCtx;
130 | xmlXPathObjectPtr xpathObj;
131 |
132 | /* Make sure that passed query is non-nil and is NSString object */
133 | if (query == nil || ![query isKindOfClass:[NSString class]])
134 | {
135 | return nil;
136 | }
137 |
138 | /* Create xpath evaluation context */
139 | xpathCtx = xmlXPathNewContext(doc);
140 | if(xpathCtx == NULL)
141 | {
142 | NSLog(@"Unable to create XPath context.");
143 | return nil;
144 | }
145 |
146 | /* Evaluate xpath expression */
147 | xpathObj = xmlXPathEvalExpression((xmlChar *)[query cStringUsingEncoding:NSUTF8StringEncoding], xpathCtx);
148 | if(xpathObj == NULL) {
149 | NSLog(@"Unable to evaluate XPath.");
150 | xmlXPathFreeContext(xpathCtx);
151 | return nil;
152 | }
153 |
154 | xmlNodeSetPtr nodes = xpathObj->nodesetval;
155 | if (!nodes)
156 | {
157 | NSLog(@"Nodes was nil.");
158 | xmlXPathFreeObject(xpathObj);
159 | xmlXPathFreeContext(xpathCtx);
160 | return nil;
161 | }
162 |
163 | NSMutableArray *resultNodes = [NSMutableArray array];
164 | for (NSInteger i = 0; i < nodes->nodeNr; i++)
165 | {
166 | NSDictionary *nodeDictionary = DictionaryForNode(nodes->nodeTab[i], nil,false);
167 | if (nodeDictionary)
168 | {
169 | [resultNodes addObject:nodeDictionary];
170 | }
171 | }
172 |
173 | /* Cleanup */
174 | xmlXPathFreeObject(xpathObj);
175 | xmlXPathFreeContext(xpathCtx);
176 |
177 | return resultNodes;
178 | }
179 |
180 | NSArray *PerformHTMLXPathQuery(NSData *document, NSString *query)
181 | {
182 | return PerformHTMLXPathQueryWithEncoding(document, query, nil);
183 | }
184 |
185 | NSArray *PerformHTMLXPathQueryWithEncoding(NSData *document, NSString *query,NSString *encoding)
186 | {
187 | xmlDocPtr doc;
188 |
189 | /* Load XML document */
190 | const char *encoded = encoding ? [encoding cStringUsingEncoding:NSUTF8StringEncoding] : NULL;
191 |
192 | doc = htmlReadMemory([document bytes], (int)[document length], "", encoded, HTML_PARSE_NOWARNING | HTML_PARSE_NOERROR);
193 |
194 | if (doc == NULL)
195 | {
196 | NSLog(@"Unable to parse.");
197 | return nil;
198 | }
199 |
200 | NSArray *result = PerformXPathQuery(doc, query);
201 | xmlFreeDoc(doc);
202 |
203 | return result;
204 | }
205 |
206 | NSArray *PerformXMLXPathQuery(NSData *document, NSString *query)
207 | {
208 | return PerformXMLXPathQueryWithEncoding(document, query, nil);
209 | }
210 |
211 | NSArray *PerformXMLXPathQueryWithEncoding(NSData *document, NSString *query,NSString *encoding)
212 | {
213 | xmlDocPtr doc;
214 |
215 | /* Load XML document */
216 | const char *encoded = encoding ? [encoding cStringUsingEncoding:NSUTF8StringEncoding] : NULL;
217 |
218 | doc = xmlReadMemory([document bytes], (int)[document length], "", encoded, XML_PARSE_RECOVER);
219 |
220 | if (doc == NULL)
221 | {
222 | NSLog(@"Unable to parse.");
223 | return nil;
224 | }
225 |
226 | NSArray *result = PerformXPathQuery(doc, query);
227 | xmlFreeDoc(doc);
228 |
229 | return result;
230 | }
231 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/LightWeightPlist/LightWeightPlist+AccessObject.h:
--------------------------------------------------------------------------------
1 | //
2 | // LightWeightPlist+AccessObject.h
3 | // LightWeightPlist
4 | //
5 | // Created by 啟倫 陳 on 2014/3/4.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import "LightWeightPlist.h"
10 |
11 | #import "LightWeightPlistObjects.h"
12 |
13 | #define lwpCache [LightWeightPlist objects].dataCache
14 | #define lwpPointerMapping [LightWeightPlist objects].pointerMapping
15 |
16 | @interface LightWeightPlist (AccessObject)
17 |
18 | + (LightWeightPlistObjects *)objects;
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/LightWeightPlist/LightWeightPlist+AccessObject.m:
--------------------------------------------------------------------------------
1 | //
2 | // LightWeightPlist+AccessObject.m
3 | // LightWeightPlist
4 | //
5 | // Created by 啟倫 陳 on 2014/3/4.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import "LightWeightPlist+AccessObject.h"
10 |
11 | #import
12 |
13 | @implementation LightWeightPlist (AccessObject)
14 |
15 | #pragma mark - class method
16 |
17 | + (LightWeightPlistObjects *)objects
18 | {
19 | static dispatch_once_t onceToken;
20 | dispatch_once(&onceToken, ^{
21 | LightWeightPlistObjects *objects = [LightWeightPlistObjects new];
22 | [objects.dataCache setDelegate:(id )self];
23 | objc_setAssociatedObject(self, _cmd, objects, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
24 | });
25 | return objc_getAssociatedObject(self, _cmd);
26 | }
27 |
28 | @end
29 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/LightWeightPlist/LightWeightPlist+FilePath.h:
--------------------------------------------------------------------------------
1 | //
2 | // LightWeightPlist+FilePath.h
3 | // LightWeightPlist
4 | //
5 | // Created by 啟倫 陳 on 2014/3/4.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import "LightWeightPlist.h"
10 |
11 | #define lwpResourceFile(fmt) [LightWeightPlist resourceFolderPathWithFilename:fmt]
12 | #define lwpDocumentFile(fmt) [LightWeightPlist documentFolderPathWithFilename:fmt]
13 |
14 | @interface LightWeightPlist (FilePath)
15 |
16 | + (NSString *)resourceFolderPathWithFilename:(NSString *)filename;
17 | + (NSString *)documentFolderPathWithFilename:(NSString *)filename;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/LightWeightPlist/LightWeightPlist+FilePath.m:
--------------------------------------------------------------------------------
1 | //
2 | // LightWeightPlist+FilePath.m
3 | // LightWeightPlist
4 | //
5 | // Created by 啟倫 陳 on 2014/3/4.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import "LightWeightPlist+FilePath.h"
10 |
11 | #import "LightWeightPlist+AccessObject.h"
12 |
13 | @implementation LightWeightPlist (FilePath)
14 |
15 | #pragma mark - class method
16 |
17 | + (NSString *)resourceFolderPathWithFilename:(NSString *)filename
18 | {
19 | return [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.plist", filename]];
20 | }
21 |
22 | + (NSString *)documentFolderPathWithFilename:(NSString *)filename
23 | {
24 | NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
25 | NSString *documentsDirectory = [paths objectAtIndex:0];
26 | return [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.plist", filename]];
27 | }
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/LightWeightPlist/LightWeightPlist+HandleCache.h:
--------------------------------------------------------------------------------
1 | //
2 | // LightWeightPlist+HandleCache.h
3 | // LightWeightPlist
4 | //
5 | // Created by 啟倫 陳 on 2014/3/20.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import "LightWeightPlist.h"
10 |
11 | @interface LightWeightPlist (HandleCache)
12 |
13 | + (BOOL)setObjectToCache:(id)object withKey:(NSString *)key;
14 | + (id)objectFromCache:(NSString *)key;
15 | + (void)removeObjectFromCache:(NSString *)key;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/LightWeightPlist/LightWeightPlist+HandleCache.m:
--------------------------------------------------------------------------------
1 | //
2 | // LightWeightPlist+HandleCache.m
3 | // LightWeightPlist
4 | //
5 | // Created by 啟倫 陳 on 2014/3/20.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import "LightWeightPlist+HandleCache.h"
10 |
11 | #import
12 |
13 | #import "LightWeightPlist+AccessObject.h"
14 | #import "LightWeightPlist+FilePath.h"
15 |
16 | #define lwpBridge(fmt) ((__bridge const void *)fmt)
17 |
18 | @implementation LightWeightPlist (HandleCache)
19 |
20 | #pragma mark - NSCacheDelegate
21 |
22 | + (void)cache:(NSCache *)cache willEvictObject:(id)obj {
23 | if ([lwpPointerMapping objectForKey:[self objectAddressString:obj]]) {
24 | id associatedObject = objc_getAssociatedObject(self, lwpBridge(obj));
25 | NSString *filename = [lwpPointerMapping objectForKey:[self objectAddressString:obj]];
26 | NSString *path = lwpDocumentFile(filename);
27 | [associatedObject performSelector:@selector(writeToFile:atomically:) withObject:path withObject:@YES];
28 | [lwpPointerMapping removeObjectForKey:[self objectAddressString:obj]];
29 | }
30 | }
31 |
32 | #pragma mark - class method
33 |
34 | + (BOOL)setObjectToCache:(id)object withKey:(NSString *)key
35 | {
36 | if ([self isDictionary:object] || [self isArray:object]) {
37 | NSObject *emptyObject = [NSObject new];
38 | [lwpCache setObject:emptyObject forKey:key];
39 | objc_setAssociatedObject(self, lwpBridge([lwpCache objectForKey:key]), object, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
40 | [lwpPointerMapping setObject:key forKey:[self objectAddressString:[lwpCache objectForKey:key]]];
41 | return YES;
42 | } else {
43 | return NO;
44 | }
45 | }
46 |
47 | + (id)objectFromCache:(NSString *)key
48 | {
49 | return objc_getAssociatedObject(self, lwpBridge([lwpCache objectForKey:key]));
50 | }
51 |
52 | + (void)removeObjectFromCache:(NSString *)key
53 | {
54 | if ([lwpCache objectForKey:key]) {
55 | [lwpPointerMapping removeObjectForKey:[self objectAddressString:[lwpCache objectForKey:key]]];
56 | [lwpCache removeObjectForKey:key];
57 | }
58 | }
59 |
60 | #pragma mark - private
61 |
62 | + (NSString *)objectAddressString:(NSObject *)object
63 | {
64 | return [NSString stringWithFormat:@"%p", object];
65 | }
66 |
67 | + (BOOL)isArray:(id)object
68 | {
69 | return (0 == strcmp(object_getClassName(object), "__NSArrayM") || 0 == strcmp(object_getClassName(object), "__NSCFArray"));
70 | }
71 |
72 | + (BOOL)isDictionary:(id)object
73 | {
74 | return (0 == strcmp(object_getClassName(object), "__NSDictionaryM") || 0 == strcmp(object_getClassName(object), "__NSCFDictionary"));
75 | }
76 |
77 | @end
78 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/LightWeightPlist/LightWeightPlist+SourceFromDisk.h:
--------------------------------------------------------------------------------
1 | //
2 | // LightWeightPlist+SourceFromDisk.h
3 | // LightWeightPlist
4 | //
5 | // Created by 啟倫 陳 on 2014/3/20.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import "LightWeightPlist.h"
10 |
11 | @interface LightWeightPlist (SourceFromDisk)
12 |
13 | + (NSMutableArray *)arrayInDocument:(NSString *)key;
14 | + (NSMutableArray *)arrayInResource:(NSString *)key;
15 | + (NSMutableDictionary *)dictionaryInDocument:(NSString *)key;
16 | + (NSMutableDictionary *)dictionaryInResource:(NSString *)key;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/LightWeightPlist/LightWeightPlist+SourceFromDisk.m:
--------------------------------------------------------------------------------
1 | //
2 | // LightWeightPlist+SourceFromDisk.m
3 | // LightWeightPlist
4 | //
5 | // Created by 啟倫 陳 on 2014/3/20.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import "LightWeightPlist+SourceFromDisk.h"
10 |
11 | #import "LightWeightPlist+AccessObject.h"
12 | #import "LightWeightPlist+FilePath.h"
13 |
14 | @implementation LightWeightPlist (SourceFromDisk)
15 |
16 | #pragma mark - class method
17 |
18 | + (NSMutableArray *)arrayInDocument:(NSString *)key
19 | {
20 | return [self getPlistFile:key isArray:YES inResource:NO];
21 | }
22 |
23 | + (NSMutableArray *)arrayInResource:(NSString *)key
24 | {
25 | return [self getPlistFile:key isArray:YES inResource:YES];
26 | }
27 |
28 | + (NSMutableDictionary *)dictionaryInDocument:(NSString *)key
29 | {
30 | return [self getPlistFile:key isArray:NO inResource:NO];
31 | }
32 |
33 | + (NSMutableDictionary *)dictionaryInResource:(NSString *)key
34 | {
35 | return [self getPlistFile:key isArray:NO inResource:YES];
36 | }
37 |
38 | #pragma mark - private
39 |
40 | + (id)getPlistFile:(NSString *)filename isArray:(BOOL)isArray inResource:(BOOL)inResource
41 | {
42 | NSString *path;
43 |
44 | if (inResource) {
45 | path = lwpResourceFile(filename);
46 | } else {
47 | path = lwpDocumentFile(filename);
48 | }
49 |
50 | if (![[NSFileManager defaultManager] fileExistsAtPath:path]) {
51 | return nil;
52 | } else {
53 | if (isArray) {
54 | return [NSMutableArray arrayWithContentsOfFile:path];
55 | } else {
56 | return [NSMutableDictionary dictionaryWithContentsOfFile:path];
57 | }
58 | }
59 | }
60 |
61 | @end
62 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/LightWeightPlist/LightWeightPlist.h:
--------------------------------------------------------------------------------
1 | //
2 | // LightWeightPlist.h
3 | // LightWeightPlist
4 | //
5 | // Created by 啟倫 陳 on 2014/3/4.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #define LWPArray(fmt) [LightWeightPlist lwpArray:fmt]
12 | #define LWPArrayR(fmt) [LightWeightPlist lwpArrayFromResource:fmt]
13 | #define LWPDictionary(fmt) [LightWeightPlist lwpDictionary:fmt]
14 | #define LWPDictionaryR(fmt) [LightWeightPlist lwpArrayFromResource:fmt]
15 | #define LWPDelete(fmt) [LightWeightPlist lwpDelete:fmt]
16 | #define LWPForceWrite() [LightWeightPlist lwpForceWrite]
17 |
18 | @interface LightWeightPlist : NSObject
19 |
20 | #pragma mark - Common
21 |
22 | + (void)lwpDelete:(NSString *)key;
23 | + (void)lwpForceWrite;
24 |
25 | #pragma mark - Array
26 |
27 | + (NSMutableArray *)lwpArray:(NSString *)key;
28 | + (NSMutableArray *)lwpArrayFromResource:(NSString *)key;
29 |
30 | #pragma mark - Dictionary
31 |
32 | + (NSMutableDictionary *)lwpDictionary:(NSString *)key;
33 | + (NSMutableDictionary *)lwpDictionaryFromResource:(NSString *)key;
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/LightWeightPlist/LightWeightPlist.m:
--------------------------------------------------------------------------------
1 | //
2 | // LightWeightPlist.m
3 | // LightWeightPlist
4 | //
5 | // Created by 啟倫 陳 on 2014/3/4.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import "LightWeightPlist.h"
10 |
11 | #import "LightWeightPlist+AccessObject.h"
12 | #import "LightWeightPlist+HandleCache.h"
13 | #import "LightWeightPlist+SourceFromDisk.h"
14 | #import "LightWeightPlist+FilePath.h"
15 |
16 | @implementation LightWeightPlist
17 |
18 | #pragma mark - common
19 |
20 | + (void)lwpDelete:(NSString *)key
21 | {
22 | [[NSFileManager defaultManager] removeItemAtPath:lwpDocumentFile(key) error:NULL];
23 | [self removeObjectFromCache:key];
24 | }
25 |
26 | + (void)lwpForceWrite
27 | {
28 | [lwpCache removeAllObjects];
29 | }
30 |
31 | #pragma mark - array
32 |
33 | + (NSMutableArray *)lwpArray:(NSString *)key
34 | {
35 | if (![self objectFromCache:key]) {
36 | NSMutableArray *returnObject;
37 | returnObject = [self arrayInDocument:key];
38 | if (!returnObject) {
39 | returnObject = [self arrayInResource:key];
40 | if (!returnObject) {
41 | returnObject = [NSMutableArray array];
42 | }
43 | }
44 | [self setObjectToCache:returnObject withKey:key];
45 | }
46 | return [self objectFromCache:key];
47 | }
48 |
49 | + (NSMutableArray *)lwpArrayFromResource:(NSString *)key
50 | {
51 | if (![self objectFromCache:key]) {
52 | NSMutableArray *returnObject;
53 | returnObject = [self arrayInResource:key];
54 | if (!returnObject) {
55 | returnObject = [NSMutableArray array];
56 | }
57 | [self setObjectToCache:returnObject withKey:key];
58 | }
59 | return [self objectFromCache:key];
60 | }
61 |
62 | #pragma mark - dictionary
63 |
64 | + (NSMutableDictionary *)lwpDictionary:(NSString *)key
65 | {
66 | if (![self objectFromCache:key]) {
67 | NSMutableDictionary *returnObject;
68 | returnObject = [self dictionaryInDocument:key];
69 | if (!returnObject) {
70 | returnObject = [self dictionaryInResource:key];
71 | if (!returnObject) {
72 | returnObject = [NSMutableDictionary dictionary];
73 | }
74 | }
75 | [self setObjectToCache:returnObject withKey:key];
76 | }
77 | return [self objectFromCache:key];
78 | }
79 |
80 | + (NSMutableDictionary *)lwpDictionaryFromResource:(NSString *)key
81 | {
82 | if (![self objectFromCache:key]) {
83 | NSMutableDictionary *returnObject;
84 | returnObject = [self dictionaryInResource:key];
85 | if (!returnObject) {
86 | returnObject = [NSMutableDictionary dictionary];
87 | }
88 | [self setObjectToCache:returnObject withKey:key];
89 | }
90 | return [self objectFromCache:key];
91 | }
92 |
93 | @end
94 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/LightWeightPlist/LightWeightPlistObjects.h:
--------------------------------------------------------------------------------
1 | //
2 | // LightWeightPlistObjects.h
3 | // LightWeightPlist
4 | //
5 | // Created by 啟倫 陳 on 2014/6/10.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface LightWeightPlistObjects : NSObject
12 |
13 | @property (nonatomic, strong) NSCache *dataCache;
14 | @property (nonatomic, strong) NSMutableDictionary *pointerMapping;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/LightWeightPlist/LightWeightPlistObjects.m:
--------------------------------------------------------------------------------
1 | //
2 | // LightWeightPlistObjects.m
3 | // LightWeightPlist
4 | //
5 | // Created by 啟倫 陳 on 2014/6/10.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import "LightWeightPlistObjects.h"
10 |
11 | @implementation LightWeightPlistObjects
12 |
13 | #pragma mark - life cycle
14 |
15 | - (id)init
16 | {
17 | self = [super init];
18 | if (self) {
19 | self.dataCache = [NSCache new];
20 | self.pointerMapping = [NSMutableDictionary dictionary];
21 | }
22 | return self;
23 | }
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/SDWebImage/MKAnnotationView+WebCache.h:
--------------------------------------------------------------------------------
1 | //
2 | // MKAnnotationView+WebCache.h
3 | // SDWebImage
4 | //
5 | // Created by Olivier Poitrey on 14/03/12.
6 | // Copyright (c) 2012 Dailymotion. All rights reserved.
7 | //
8 |
9 | #import "MapKit/MapKit.h"
10 | #import "SDWebImageManager.h"
11 |
12 | /**
13 | * Integrates SDWebImage async downloading and caching of remote images with MKAnnotationView.
14 | */
15 | @interface MKAnnotationView (WebCache)
16 |
17 | /**
18 | * Get the current image URL.
19 | *
20 | * Note that because of the limitations of categories this property can get out of sync
21 | * if you use sd_setImage: directly.
22 | */
23 | - (NSURL *)sd_imageURL;
24 |
25 | /**
26 | * Set the imageView `image` with an `url`.
27 | *
28 | * The download is asynchronous and cached.
29 | *
30 | * @param url The url for the image.
31 | */
32 | - (void)sd_setImageWithURL:(NSURL *)url;
33 |
34 | /**
35 | * Set the imageView `image` with an `url` and a placeholder.
36 | *
37 | * The download is asynchronous and cached.
38 | *
39 | * @param url The url for the image.
40 | * @param placeholder The image to be set initially, until the image request finishes.
41 | * @see sd_setImageWithURL:placeholderImage:options:
42 | */
43 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder;
44 |
45 | /**
46 | * Set the imageView `image` with an `url`, placeholder and custom options.
47 | *
48 | * The download is asynchronous and cached.
49 | *
50 | * @param url The url for the image.
51 | * @param placeholder The image to be set initially, until the image request finishes.
52 | * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
53 | */
54 |
55 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options;
56 |
57 | /**
58 | * Set the imageView `image` with an `url`.
59 | *
60 | * The download is asynchronous and cached.
61 | *
62 | * @param url The url for the image.
63 | * @param completedBlock A block called when operation has been completed. This block has no return value
64 | * and takes the requested UIImage as first parameter. In case of error the image parameter
65 | * is nil and the second parameter may contain an NSError. The third parameter is a Boolean
66 | * indicating if the image was retrived from the local cache or from the network.
67 | * The forth parameter is the original image url.
68 | */
69 | - (void)sd_setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock;
70 |
71 | /**
72 | * Set the imageView `image` with an `url`, placeholder.
73 | *
74 | * The download is asynchronous and cached.
75 | *
76 | * @param url The url for the image.
77 | * @param placeholder The image to be set initially, until the image request finishes.
78 | * @param completedBlock A block called when operation has been completed. This block has no return value
79 | * and takes the requested UIImage as first parameter. In case of error the image parameter
80 | * is nil and the second parameter may contain an NSError. The third parameter is a Boolean
81 | * indicating if the image was retrived from the local cache or from the network.
82 | * The forth parameter is the original image url.
83 | */
84 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock;
85 |
86 | /**
87 | * Set the imageView `image` with an `url`, placeholder and custom options.
88 | *
89 | * The download is asynchronous and cached.
90 | *
91 | * @param url The url for the image.
92 | * @param placeholder The image to be set initially, until the image request finishes.
93 | * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
94 | * @param completedBlock A block called when operation has been completed. This block has no return value
95 | * and takes the requested UIImage as first parameter. In case of error the image parameter
96 | * is nil and the second parameter may contain an NSError. The third parameter is a Boolean
97 | * indicating if the image was retrived from the local cache or from the network.
98 | * The forth parameter is the original image url.
99 | */
100 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock;
101 |
102 | /**
103 | * Cancel the current download
104 | */
105 | - (void)sd_cancelCurrentImageLoad;
106 |
107 | @end
108 |
109 |
110 | @interface MKAnnotationView (WebCacheDeprecated)
111 |
112 | - (NSURL *)imageURL __deprecated_msg("Use `sd_imageURL`");
113 |
114 | - (void)setImageWithURL:(NSURL *)url __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:`");
115 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:`");
116 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:options:`");
117 |
118 | - (void)setImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:completed:`");
119 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:completed:`");
120 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:options:completed:`");
121 |
122 | - (void)cancelCurrentImageLoad __deprecated_msg("Use `sd_cancelCurrentImageLoad`");
123 |
124 | @end
125 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/SDWebImage/MKAnnotationView+WebCache.m:
--------------------------------------------------------------------------------
1 | //
2 | // MKAnnotationView+WebCache.m
3 | // SDWebImage
4 | //
5 | // Created by Olivier Poitrey on 14/03/12.
6 | // Copyright (c) 2012 Dailymotion. All rights reserved.
7 | //
8 |
9 | #import "MKAnnotationView+WebCache.h"
10 | #import "objc/runtime.h"
11 | #import "UIView+WebCacheOperation.h"
12 |
13 | static char imageURLKey;
14 |
15 | @implementation MKAnnotationView (WebCache)
16 |
17 | - (NSURL *)sd_imageURL {
18 | return objc_getAssociatedObject(self, &imageURLKey);
19 | }
20 |
21 | - (void)sd_setImageWithURL:(NSURL *)url {
22 | [self sd_setImageWithURL:url placeholderImage:nil options:0 completed:nil];
23 | }
24 |
25 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder {
26 | [self sd_setImageWithURL:url placeholderImage:placeholder options:0 completed:nil];
27 | }
28 |
29 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options {
30 | [self sd_setImageWithURL:url placeholderImage:placeholder options:options completed:nil];
31 | }
32 |
33 | - (void)sd_setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock {
34 | [self sd_setImageWithURL:url placeholderImage:nil options:0 completed:completedBlock];
35 | }
36 |
37 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock {
38 | [self sd_setImageWithURL:url placeholderImage:placeholder options:0 completed:completedBlock];
39 | }
40 |
41 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock {
42 | [self sd_cancelCurrentImageLoad];
43 |
44 | objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
45 | self.image = placeholder;
46 |
47 | if (url) {
48 | __weak MKAnnotationView *wself = self;
49 | id operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
50 | if (!wself) return;
51 | dispatch_main_sync_safe(^{
52 | __strong MKAnnotationView *sself = wself;
53 | if (!sself) return;
54 | if (image) {
55 | sself.image = image;
56 | }
57 | if (completedBlock && finished) {
58 | completedBlock(image, error, cacheType, url);
59 | }
60 | });
61 | }];
62 | [self sd_setImageLoadOperation:operation forKey:@"MKAnnotationViewImage"];
63 | } else {
64 | dispatch_main_async_safe(^{
65 | NSError *error = [NSError errorWithDomain:@"SDWebImageErrorDomain" code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];
66 | if (completedBlock) {
67 | completedBlock(nil, error, SDImageCacheTypeNone, url);
68 | }
69 | });
70 | }
71 | }
72 |
73 | - (void)sd_cancelCurrentImageLoad {
74 | [self sd_cancelImageLoadOperationWithKey:@"MKAnnotationViewImage"];
75 | }
76 |
77 | @end
78 |
79 |
80 | @implementation MKAnnotationView (WebCacheDeprecated)
81 |
82 | - (NSURL *)imageURL {
83 | return [self sd_imageURL];
84 | }
85 |
86 | - (void)setImageWithURL:(NSURL *)url {
87 | [self sd_setImageWithURL:url placeholderImage:nil options:0 completed:nil];
88 | }
89 |
90 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder {
91 | [self sd_setImageWithURL:url placeholderImage:placeholder options:0 completed:nil];
92 | }
93 |
94 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options {
95 | [self sd_setImageWithURL:url placeholderImage:placeholder options:options completed:nil];
96 | }
97 |
98 | - (void)setImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock {
99 | [self sd_setImageWithURL:url placeholderImage:nil options:0 completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
100 | if (completedBlock) {
101 | completedBlock(image, error, cacheType);
102 | }
103 | }];
104 | }
105 |
106 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock {
107 | [self sd_setImageWithURL:url placeholderImage:placeholder options:0 completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
108 | if (completedBlock) {
109 | completedBlock(image, error, cacheType);
110 | }
111 | }];
112 | }
113 |
114 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock {
115 | [self sd_setImageWithURL:url placeholderImage:placeholder options:options completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
116 | if (completedBlock) {
117 | completedBlock(image, error, cacheType);
118 | }
119 | }];
120 | }
121 |
122 | - (void)cancelCurrentImageLoad {
123 | [self sd_cancelCurrentImageLoad];
124 | }
125 |
126 | @end
127 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/SDWebImage/NSData+ImageContentType.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Fabrice Aneche on 06/01/14.
3 | // Copyright (c) 2014 Dailymotion. All rights reserved.
4 | //
5 |
6 | #import
7 |
8 | @interface NSData (ImageContentType)
9 |
10 | /**
11 | * Compute the content type for an image data
12 | *
13 | * @param data the input data
14 | *
15 | * @return the content type as string (i.e. image/jpeg, image/gif)
16 | */
17 | + (NSString *)sd_contentTypeForImageData:(NSData *)data;
18 |
19 | @end
20 |
21 |
22 | @interface NSData (ImageContentTypeDeprecated)
23 |
24 | + (NSString *)contentTypeForImageData:(NSData *)data __deprecated_msg("Use `sd_contentTypeForImageData:`");
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/SDWebImage/NSData+ImageContentType.m:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Fabrice Aneche on 06/01/14.
3 | // Copyright (c) 2014 Dailymotion. All rights reserved.
4 | //
5 |
6 | #import "NSData+ImageContentType.h"
7 |
8 |
9 | @implementation NSData (ImageContentType)
10 |
11 | + (NSString *)sd_contentTypeForImageData:(NSData *)data {
12 | uint8_t c;
13 | [data getBytes:&c length:1];
14 | switch (c) {
15 | case 0xFF:
16 | return @"image/jpeg";
17 | case 0x89:
18 | return @"image/png";
19 | case 0x47:
20 | return @"image/gif";
21 | case 0x49:
22 | case 0x4D:
23 | return @"image/tiff";
24 | case 0x52:
25 | // R as RIFF for WEBP
26 | if ([data length] < 12) {
27 | return nil;
28 | }
29 |
30 | NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 12)] encoding:NSASCIIStringEncoding];
31 | if ([testString hasPrefix:@"RIFF"] && [testString hasSuffix:@"WEBP"]) {
32 | return @"image/webp";
33 | }
34 |
35 | return nil;
36 | }
37 | return nil;
38 | }
39 |
40 | @end
41 |
42 |
43 | @implementation NSData (ImageContentTypeDeprecated)
44 |
45 | + (NSString *)contentTypeForImageData:(NSData *)data {
46 | return [self sd_contentTypeForImageData:data];
47 | }
48 |
49 | @end
50 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/SDWebImage/SDImageCache.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImage package.
3 | * (c) Olivier Poitrey
4 | *
5 | * For the full copyright and license information, please view the LICENSE
6 | * file that was distributed with this source code.
7 | */
8 |
9 | #import
10 | #import "SDWebImageCompat.h"
11 |
12 | typedef NS_ENUM(NSInteger, SDImageCacheType) {
13 | /**
14 | * The image wasn't available the SDWebImage caches, but was downloaded from the web.
15 | */
16 | SDImageCacheTypeNone,
17 | /**
18 | * The image was obtained from the disk cache.
19 | */
20 | SDImageCacheTypeDisk,
21 | /**
22 | * The image was obtained from the memory cache.
23 | */
24 | SDImageCacheTypeMemory
25 | };
26 |
27 | typedef void(^SDWebImageQueryCompletedBlock)(UIImage *image, SDImageCacheType cacheType);
28 |
29 | typedef void(^SDWebImageCheckCacheCompletionBlock)(BOOL isInCache);
30 |
31 | typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger totalSize);
32 |
33 | /**
34 | * SDImageCache maintains a memory cache and an optional disk cache. Disk cache write operations are performed
35 | * asynchronous so it doesn’t add unnecessary latency to the UI.
36 | */
37 | @interface SDImageCache : NSObject
38 |
39 | /**
40 | * The maximum "total cost" of the in-memory image cache. The cost function is the number of pixels held in memory.
41 | */
42 | @property (assign, nonatomic) NSUInteger maxMemoryCost;
43 |
44 | /**
45 | * The maximum length of time to keep an image in the cache, in seconds
46 | */
47 | @property (assign, nonatomic) NSInteger maxCacheAge;
48 |
49 | /**
50 | * The maximum size of the cache, in bytes.
51 | */
52 | @property (assign, nonatomic) NSUInteger maxCacheSize;
53 |
54 | /**
55 | * Returns global shared cache instance
56 | *
57 | * @return SDImageCache global instance
58 | */
59 | + (SDImageCache *)sharedImageCache;
60 |
61 | /**
62 | * Init a new cache store with a specific namespace
63 | *
64 | * @param ns The namespace to use for this cache store
65 | */
66 | - (id)initWithNamespace:(NSString *)ns;
67 |
68 | /**
69 | * Add a read-only cache path to search for images pre-cached by SDImageCache
70 | * Useful if you want to bundle pre-loaded images with your app
71 | *
72 | * @param path The path to use for this read-only cache path
73 | */
74 | - (void)addReadOnlyCachePath:(NSString *)path;
75 |
76 | /**
77 | * Store an image into memory and disk cache at the given key.
78 | *
79 | * @param image The image to store
80 | * @param key The unique image cache key, usually it's image absolute URL
81 | */
82 | - (void)storeImage:(UIImage *)image forKey:(NSString *)key;
83 |
84 | /**
85 | * Store an image into memory and optionally disk cache at the given key.
86 | *
87 | * @param image The image to store
88 | * @param key The unique image cache key, usually it's image absolute URL
89 | * @param toDisk Store the image to disk cache if YES
90 | */
91 | - (void)storeImage:(UIImage *)image forKey:(NSString *)key toDisk:(BOOL)toDisk;
92 |
93 | /**
94 | * Store an image into memory and optionally disk cache at the given key.
95 | *
96 | * @param image The image to store
97 | * @param recalculate BOOL indicates if imageData can be used or a new data should be constructed from the UIImage
98 | * @param imageData The image data as returned by the server, this representation will be used for disk storage
99 | * instead of converting the given image object into a storable/compressed image format in order
100 | * to save quality and CPU
101 | * @param key The unique image cache key, usually it's image absolute URL
102 | * @param toDisk Store the image to disk cache if YES
103 | */
104 | - (void)storeImage:(UIImage *)image recalculateFromImage:(BOOL)recalculate imageData:(NSData *)imageData forKey:(NSString *)key toDisk:(BOOL)toDisk;
105 |
106 | /**
107 | * Query the disk cache asynchronously.
108 | *
109 | * @param key The unique key used to store the wanted image
110 | */
111 | - (NSOperation *)queryDiskCacheForKey:(NSString *)key done:(SDWebImageQueryCompletedBlock)doneBlock;
112 |
113 | /**
114 | * Query the memory cache synchronously.
115 | *
116 | * @param key The unique key used to store the wanted image
117 | */
118 | - (UIImage *)imageFromMemoryCacheForKey:(NSString *)key;
119 |
120 | /**
121 | * Query the disk cache synchronously after checking the memory cache.
122 | *
123 | * @param key The unique key used to store the wanted image
124 | */
125 | - (UIImage *)imageFromDiskCacheForKey:(NSString *)key;
126 |
127 | /**
128 | * Remove the image from memory and disk cache synchronously
129 | *
130 | * @param key The unique image cache key
131 | */
132 | - (void)removeImageForKey:(NSString *)key;
133 |
134 |
135 | /**
136 | * Remove the image from memory and disk cache synchronously
137 | *
138 | * @param key The unique image cache key
139 | * @param completion An block that should be executed after the image has been removed (optional)
140 | */
141 | - (void)removeImageForKey:(NSString *)key withCompletion:(SDWebImageNoParamsBlock)completion;
142 |
143 | /**
144 | * Remove the image from memory and optionally disk cache synchronously
145 | *
146 | * @param key The unique image cache key
147 | * @param fromDisk Also remove cache entry from disk if YES
148 | */
149 | - (void)removeImageForKey:(NSString *)key fromDisk:(BOOL)fromDisk;
150 |
151 | /**
152 | * Remove the image from memory and optionally disk cache synchronously
153 | *
154 | * @param key The unique image cache key
155 | * @param fromDisk Also remove cache entry from disk if YES
156 | * @param completion An block that should be executed after the image has been removed (optional)
157 | */
158 | - (void)removeImageForKey:(NSString *)key fromDisk:(BOOL)fromDisk withCompletion:(SDWebImageNoParamsBlock)completion;
159 |
160 | /**
161 | * Clear all memory cached images
162 | */
163 | - (void)clearMemory;
164 |
165 | /**
166 | * Clear all disk cached images. Non-blocking method - returns immediately.
167 | * @param completion An block that should be executed after cache expiration completes (optional)
168 | */
169 | - (void)clearDiskOnCompletion:(SDWebImageNoParamsBlock)completion;
170 |
171 | /**
172 | * Clear all disk cached images
173 | * @see clearDiskOnCompletion:
174 | */
175 | - (void)clearDisk;
176 |
177 | /**
178 | * Remove all expired cached image from disk. Non-blocking method - returns immediately.
179 | * @param completionBlock An block that should be executed after cache expiration completes (optional)
180 | */
181 | - (void)cleanDiskWithCompletionBlock:(SDWebImageNoParamsBlock)completionBlock;
182 |
183 | /**
184 | * Remove all expired cached image from disk
185 | * @see cleanDiskWithCompletionBlock:
186 | */
187 | - (void)cleanDisk;
188 |
189 | /**
190 | * Get the size used by the disk cache
191 | */
192 | - (NSUInteger)getSize;
193 |
194 | /**
195 | * Get the number of images in the disk cache
196 | */
197 | - (NSUInteger)getDiskCount;
198 |
199 | /**
200 | * Asynchronously calculate the disk cache's size.
201 | */
202 | - (void)calculateSizeWithCompletionBlock:(SDWebImageCalculateSizeBlock)completionBlock;
203 |
204 | /**
205 | * Async check if image exists in disk cache already (does not load the image)
206 | *
207 | * @param key the key describing the url
208 | * @param completionBlock the block to be executed when the check is done.
209 | * @note the completion block will be always executed on the main queue
210 | */
211 | - (void)diskImageExistsWithKey:(NSString *)key completion:(SDWebImageCheckCacheCompletionBlock)completionBlock;
212 |
213 | /**
214 | * Check if image exists in disk cache already (does not load the image)
215 | *
216 | * @param key the key describing the url
217 | *
218 | * @return YES if an image exists for the given key
219 | */
220 | - (BOOL)diskImageExistsWithKey:(NSString *)key;
221 |
222 | /**
223 | * Get the cache path for a certain key (needs the cache path root folder)
224 | *
225 | * @param key the key (can be obtained from url using cacheKeyForURL)
226 | * @param path the cach path root folder
227 | *
228 | * @return the cache path
229 | */
230 | - (NSString *)cachePathForKey:(NSString *)key inPath:(NSString *)path;
231 |
232 | /**
233 | * Get the default cache path for a certain key
234 | *
235 | * @param key the key (can be obtained from url using cacheKeyForURL)
236 | *
237 | * @return the default cache path
238 | */
239 | - (NSString *)defaultCachePathForKey:(NSString *)key;
240 |
241 | @end
242 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/SDWebImage/SDWebImageCompat.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImage package.
3 | * (c) Olivier Poitrey
4 | * (c) Jamie Pinkham
5 | *
6 | * For the full copyright and license information, please view the LICENSE
7 | * file that was distributed with this source code.
8 | */
9 |
10 | #import
11 |
12 | #ifdef __OBJC_GC__
13 | #error SDWebImage does not support Objective-C Garbage Collection
14 | #endif
15 |
16 | #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_5_0
17 | #error SDWebImage doesn't support Deployement Target version < 5.0
18 | #endif
19 |
20 | #if !TARGET_OS_IPHONE
21 | #import
22 | #ifndef UIImage
23 | #define UIImage NSImage
24 | #endif
25 | #ifndef UIImageView
26 | #define UIImageView NSImageView
27 | #endif
28 | #else
29 |
30 | #import
31 |
32 | #endif
33 |
34 | #ifndef NS_ENUM
35 | #define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
36 | #endif
37 |
38 | #ifndef NS_OPTIONS
39 | #define NS_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type
40 | #endif
41 |
42 | #if OS_OBJECT_USE_OBJC
43 | #undef SDDispatchQueueRelease
44 | #undef SDDispatchQueueSetterSementics
45 | #define SDDispatchQueueRelease(q)
46 | #define SDDispatchQueueSetterSementics strong
47 | #else
48 | #undef SDDispatchQueueRelease
49 | #undef SDDispatchQueueSetterSementics
50 | #define SDDispatchQueueRelease(q) (dispatch_release(q))
51 | #define SDDispatchQueueSetterSementics assign
52 | #endif
53 |
54 | extern UIImage *SDScaledImageForKey(NSString *key, UIImage *image);
55 |
56 | typedef void(^SDWebImageNoParamsBlock)();
57 |
58 | #define dispatch_main_sync_safe(block)\
59 | if ([NSThread isMainThread]) {\
60 | block();\
61 | } else {\
62 | dispatch_sync(dispatch_get_main_queue(), block);\
63 | }
64 |
65 | #define dispatch_main_async_safe(block)\
66 | if ([NSThread isMainThread]) {\
67 | block();\
68 | } else {\
69 | dispatch_async(dispatch_get_main_queue(), block);\
70 | }
71 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/SDWebImage/SDWebImageCompat.m:
--------------------------------------------------------------------------------
1 | //
2 | // SDWebImageCompat.m
3 | // SDWebImage
4 | //
5 | // Created by Olivier Poitrey on 11/12/12.
6 | // Copyright (c) 2012 Dailymotion. All rights reserved.
7 | //
8 |
9 | #import "SDWebImageCompat.h"
10 |
11 | #if !__has_feature(objc_arc)
12 | #error SDWebImage is ARC only. Either turn on ARC for the project or use -fobjc-arc flag
13 | #endif
14 |
15 | inline UIImage *SDScaledImageForKey(NSString *key, UIImage *image) {
16 | if (!image) {
17 | return nil;
18 | }
19 |
20 | if ([image.images count] > 0) {
21 | NSMutableArray *scaledImages = [NSMutableArray array];
22 |
23 | for (UIImage *tempImage in image.images) {
24 | [scaledImages addObject:SDScaledImageForKey(key, tempImage)];
25 | }
26 |
27 | return [UIImage animatedImageWithImages:scaledImages duration:image.duration];
28 | }
29 | else {
30 | if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
31 | CGFloat scale = 1.0;
32 | if (key.length >= 8) {
33 | // Search @2x. at the end of the string, before a 3 to 4 extension length (only if key len is 8 or more @2x. + 4 len ext)
34 | NSRange range = [key rangeOfString:@"@2x." options:0 range:NSMakeRange(key.length - 8, 5)];
35 | if (range.location != NSNotFound) {
36 | scale = 2.0;
37 | }
38 | }
39 |
40 | UIImage *scaledImage = [[UIImage alloc] initWithCGImage:image.CGImage scale:scale orientation:image.imageOrientation];
41 | image = scaledImage;
42 | }
43 | return image;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/SDWebImage/SDWebImageDecoder.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImage package.
3 | * (c) Olivier Poitrey
4 | *
5 | * Created by james on 9/28/11.
6 | *
7 | * For the full copyright and license information, please view the LICENSE
8 | * file that was distributed with this source code.
9 | */
10 |
11 | #import
12 | #import "SDWebImageCompat.h"
13 |
14 | @interface UIImage (ForceDecode)
15 |
16 | + (UIImage *)decodedImageWithImage:(UIImage *)image;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/SDWebImage/SDWebImageDecoder.m:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImage package.
3 | * (c) Olivier Poitrey
4 | *
5 | * Created by james on 9/28/11.
6 | *
7 | * For the full copyright and license information, please view the LICENSE
8 | * file that was distributed with this source code.
9 | */
10 |
11 | #import "SDWebImageDecoder.h"
12 |
13 | @implementation UIImage (ForceDecode)
14 |
15 | + (UIImage *)decodedImageWithImage:(UIImage *)image {
16 | if (image.images) {
17 | // Do not decode animated images
18 | return image;
19 | }
20 |
21 | CGImageRef imageRef = image.CGImage;
22 | CGSize imageSize = CGSizeMake(CGImageGetWidth(imageRef), CGImageGetHeight(imageRef));
23 | CGRect imageRect = (CGRect){.origin = CGPointZero, .size = imageSize};
24 |
25 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
26 | CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);
27 |
28 | int infoMask = (bitmapInfo & kCGBitmapAlphaInfoMask);
29 | BOOL anyNonAlpha = (infoMask == kCGImageAlphaNone ||
30 | infoMask == kCGImageAlphaNoneSkipFirst ||
31 | infoMask == kCGImageAlphaNoneSkipLast);
32 |
33 | // CGBitmapContextCreate doesn't support kCGImageAlphaNone with RGB.
34 | // https://developer.apple.com/library/mac/#qa/qa1037/_index.html
35 | if (infoMask == kCGImageAlphaNone && CGColorSpaceGetNumberOfComponents(colorSpace) > 1) {
36 | // Unset the old alpha info.
37 | bitmapInfo &= ~kCGBitmapAlphaInfoMask;
38 |
39 | // Set noneSkipFirst.
40 | bitmapInfo |= kCGImageAlphaNoneSkipFirst;
41 | }
42 | // Some PNGs tell us they have alpha but only 3 components. Odd.
43 | else if (!anyNonAlpha && CGColorSpaceGetNumberOfComponents(colorSpace) == 3) {
44 | // Unset the old alpha info.
45 | bitmapInfo &= ~kCGBitmapAlphaInfoMask;
46 | bitmapInfo |= kCGImageAlphaPremultipliedFirst;
47 | }
48 |
49 | // It calculates the bytes-per-row based on the bitsPerComponent and width arguments.
50 | CGContextRef context = CGBitmapContextCreate(NULL,
51 | imageSize.width,
52 | imageSize.height,
53 | CGImageGetBitsPerComponent(imageRef),
54 | 0,
55 | colorSpace,
56 | bitmapInfo);
57 | CGColorSpaceRelease(colorSpace);
58 |
59 | // If failed, return undecompressed image
60 | if (!context) return image;
61 |
62 | CGContextDrawImage(context, imageRect, imageRef);
63 | CGImageRef decompressedImageRef = CGBitmapContextCreateImage(context);
64 |
65 | CGContextRelease(context);
66 |
67 | UIImage *decompressedImage = [UIImage imageWithCGImage:decompressedImageRef scale:image.scale orientation:image.imageOrientation];
68 | CGImageRelease(decompressedImageRef);
69 | return decompressedImage;
70 | }
71 |
72 | @end
73 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/SDWebImage/SDWebImageDownloader.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImage package.
3 | * (c) Olivier Poitrey
4 | *
5 | * For the full copyright and license information, please view the LICENSE
6 | * file that was distributed with this source code.
7 | */
8 |
9 | #import
10 | #import "SDWebImageCompat.h"
11 | #import "SDWebImageOperation.h"
12 |
13 | typedef NS_OPTIONS(NSUInteger, SDWebImageDownloaderOptions) {
14 | SDWebImageDownloaderLowPriority = 1 << 0,
15 | SDWebImageDownloaderProgressiveDownload = 1 << 1,
16 |
17 | /**
18 | * By default, request prevent the of NSURLCache. With this flag, NSURLCache
19 | * is used with default policies.
20 | */
21 | SDWebImageDownloaderUseNSURLCache = 1 << 2,
22 |
23 | /**
24 | * Call completion block with nil image/imageData if the image was read from NSURLCache
25 | * (to be combined with `SDWebImageDownloaderUseNSURLCache`).
26 | */
27 |
28 | SDWebImageDownloaderIgnoreCachedResponse = 1 << 3,
29 | /**
30 | * In iOS 4+, continue the download of the image if the app goes to background. This is achieved by asking the system for
31 | * extra time in background to let the request finish. If the background task expires the operation will be cancelled.
32 | */
33 |
34 | SDWebImageDownloaderContinueInBackground = 1 << 4,
35 |
36 | /**
37 | * Handles cookies stored in NSHTTPCookieStore by setting
38 | * NSMutableURLRequest.HTTPShouldHandleCookies = YES;
39 | */
40 | SDWebImageDownloaderHandleCookies = 1 << 5,
41 |
42 | /**
43 | * Enable to allow untrusted SSL ceriticates.
44 | * Useful for testing purposes. Use with caution in production.
45 | */
46 | SDWebImageDownloaderAllowInvalidSSLCertificates = 1 << 6,
47 |
48 | /**
49 | * Put the image in the high priority queue.
50 | */
51 | SDWebImageDownloaderHighPriority = 1 << 7,
52 |
53 |
54 | };
55 |
56 | typedef NS_ENUM(NSInteger, SDWebImageDownloaderExecutionOrder) {
57 | /**
58 | * Default value. All download operations will execute in queue style (first-in-first-out).
59 | */
60 | SDWebImageDownloaderFIFOExecutionOrder,
61 |
62 | /**
63 | * All download operations will execute in stack style (last-in-first-out).
64 | */
65 | SDWebImageDownloaderLIFOExecutionOrder
66 | };
67 |
68 | extern NSString *const SDWebImageDownloadStartNotification;
69 | extern NSString *const SDWebImageDownloadStopNotification;
70 |
71 | typedef void(^SDWebImageDownloaderProgressBlock)(NSInteger receivedSize, NSInteger expectedSize);
72 |
73 | typedef void(^SDWebImageDownloaderCompletedBlock)(UIImage *image, NSData *data, NSError *error, BOOL finished);
74 |
75 | typedef NSDictionary *(^SDWebImageDownloaderHeadersFilterBlock)(NSURL *url, NSDictionary *headers);
76 |
77 | /**
78 | * Asynchronous downloader dedicated and optimized for image loading.
79 | */
80 | @interface SDWebImageDownloader : NSObject
81 |
82 | @property (assign, nonatomic) NSInteger maxConcurrentDownloads;
83 |
84 | /**
85 | * Shows the current amount of downloads that still need to be downloaded
86 | */
87 |
88 | @property (readonly, nonatomic) NSUInteger currentDownloadCount;
89 |
90 |
91 | /**
92 | * The timeout value (in seconds) for the download operation. Default: 15.0.
93 | */
94 | @property (assign, nonatomic) NSTimeInterval downloadTimeout;
95 |
96 |
97 | /**
98 | * Changes download operations execution order. Default value is `SDWebImageDownloaderFIFOExecutionOrder`.
99 | */
100 | @property (assign, nonatomic) SDWebImageDownloaderExecutionOrder executionOrder;
101 |
102 | /**
103 | * Singleton method, returns the shared instance
104 | *
105 | * @return global shared instance of downloader class
106 | */
107 | + (SDWebImageDownloader *)sharedDownloader;
108 |
109 | /**
110 | * Set username
111 | */
112 | @property (strong, nonatomic) NSString *username;
113 |
114 | /**
115 | * Set password
116 | */
117 | @property (strong, nonatomic) NSString *password;
118 |
119 | /**
120 | * Set filter to pick headers for downloading image HTTP request.
121 | *
122 | * This block will be invoked for each downloading image request, returned
123 | * NSDictionary will be used as headers in corresponding HTTP request.
124 | */
125 | @property (nonatomic, copy) SDWebImageDownloaderHeadersFilterBlock headersFilter;
126 |
127 | /**
128 | * Set a value for a HTTP header to be appended to each download HTTP request.
129 | *
130 | * @param value The value for the header field. Use `nil` value to remove the header.
131 | * @param field The name of the header field to set.
132 | */
133 | - (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field;
134 |
135 | /**
136 | * Returns the value of the specified HTTP header field.
137 | *
138 | * @return The value associated with the header field field, or `nil` if there is no corresponding header field.
139 | */
140 | - (NSString *)valueForHTTPHeaderField:(NSString *)field;
141 |
142 | /**
143 | * Creates a SDWebImageDownloader async downloader instance with a given URL
144 | *
145 | * The delegate will be informed when the image is finish downloaded or an error has happen.
146 | *
147 | * @see SDWebImageDownloaderDelegate
148 | *
149 | * @param url The URL to the image to download
150 | * @param options The options to be used for this download
151 | * @param progressBlock A block called repeatedly while the image is downloading
152 | * @param completedBlock A block called once the download is completed.
153 | * If the download succeeded, the image parameter is set, in case of error,
154 | * error parameter is set with the error. The last parameter is always YES
155 | * if SDWebImageDownloaderProgressiveDownload isn't use. With the
156 | * SDWebImageDownloaderProgressiveDownload option, this block is called
157 | * repeatedly with the partial image object and the finished argument set to NO
158 | * before to be called a last time with the full image and finished argument
159 | * set to YES. In case of error, the finished argument is always YES.
160 | *
161 | * @return A cancellable SDWebImageOperation
162 | */
163 | - (id )downloadImageWithURL:(NSURL *)url
164 | options:(SDWebImageDownloaderOptions)options
165 | progress:(SDWebImageDownloaderProgressBlock)progressBlock
166 | completed:(SDWebImageDownloaderCompletedBlock)completedBlock;
167 |
168 | /**
169 | * Sets the download queue suspension state
170 | */
171 | - (void)setSuspended:(BOOL)suspended;
172 |
173 | @end
174 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/SDWebImage/SDWebImageDownloaderOperation.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImage package.
3 | * (c) Olivier Poitrey
4 | *
5 | * For the full copyright and license information, please view the LICENSE
6 | * file that was distributed with this source code.
7 | */
8 |
9 | #import
10 | #import "SDWebImageDownloader.h"
11 | #import "SDWebImageOperation.h"
12 |
13 | @interface SDWebImageDownloaderOperation : NSOperation
14 |
15 | /**
16 | * The request used by the operation's connection.
17 | */
18 | @property (strong, nonatomic, readonly) NSURLRequest *request;
19 |
20 | /**
21 | * Whether the URL connection should consult the credential storage for authenticating the connection. `YES` by default.
22 | *
23 | * This is the value that is returned in the `NSURLConnectionDelegate` method `-connectionShouldUseCredentialStorage:`.
24 | */
25 | @property (nonatomic, assign) BOOL shouldUseCredentialStorage;
26 |
27 | /**
28 | * The credential used for authentication challenges in `-connection:didReceiveAuthenticationChallenge:`.
29 | *
30 | * This will be overridden by any shared credentials that exist for the username or password of the request URL, if present.
31 | */
32 | @property (nonatomic, strong) NSURLCredential *credential;
33 |
34 | /**
35 | * The SDWebImageDownloaderOptions for the receiver.
36 | */
37 | @property (assign, nonatomic, readonly) SDWebImageDownloaderOptions options;
38 |
39 | /**
40 | * Initializes a `SDWebImageDownloaderOperation` object
41 | *
42 | * @see SDWebImageDownloaderOperation
43 | *
44 | * @param request the URL request
45 | * @param options downloader options
46 | * @param progressBlock the block executed when a new chunk of data arrives.
47 | * @note the progress block is executed on a background queue
48 | * @param completedBlock the block executed when the download is done.
49 | * @note the completed block is executed on the main queue for success. If errors are found, there is a chance the block will be executed on a background queue
50 | * @param cancelBlock the block executed if the download (operation) is cancelled
51 | *
52 | * @return the initialized instance
53 | */
54 | - (id)initWithRequest:(NSURLRequest *)request
55 | options:(SDWebImageDownloaderOptions)options
56 | progress:(SDWebImageDownloaderProgressBlock)progressBlock
57 | completed:(SDWebImageDownloaderCompletedBlock)completedBlock
58 | cancelled:(SDWebImageNoParamsBlock)cancelBlock;
59 |
60 | @end
61 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/SDWebImage/SDWebImageOperation.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImage package.
3 | * (c) Olivier Poitrey
4 | *
5 | * For the full copyright and license information, please view the LICENSE
6 | * file that was distributed with this source code.
7 | */
8 |
9 | #import
10 |
11 | @protocol SDWebImageOperation
12 |
13 | - (void)cancel;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/SDWebImage/SDWebImagePrefetcher.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImage package.
3 | * (c) Olivier Poitrey
4 | *
5 | * For the full copyright and license information, please view the LICENSE
6 | * file that was distributed with this source code.
7 | */
8 |
9 | #import
10 | #import "SDWebImageManager.h"
11 |
12 | @class SDWebImagePrefetcher;
13 |
14 | @protocol SDWebImagePrefetcherDelegate
15 |
16 | @optional
17 |
18 | /**
19 | * Called when an image was prefetched.
20 | *
21 | * @param imagePrefetcher The current image prefetcher
22 | * @param imageURL The image url that was prefetched
23 | * @param finishedCount The total number of images that were prefetched (successful or not)
24 | * @param totalCount The total number of images that were to be prefetched
25 | */
26 | - (void)imagePrefetcher:(SDWebImagePrefetcher *)imagePrefetcher didPrefetchURL:(NSURL *)imageURL finishedCount:(NSUInteger)finishedCount totalCount:(NSUInteger)totalCount;
27 |
28 | /**
29 | * Called when all images are prefetched.
30 | * @param imagePrefetcher The current image prefetcher
31 | * @param totalCount The total number of images that were prefetched (whether successful or not)
32 | * @param skippedCount The total number of images that were skipped
33 | */
34 | - (void)imagePrefetcher:(SDWebImagePrefetcher *)imagePrefetcher didFinishWithTotalCount:(NSUInteger)totalCount skippedCount:(NSUInteger)skippedCount;
35 |
36 | @end
37 |
38 | typedef void(^SDWebImagePrefetcherProgressBlock)(NSUInteger noOfFinishedUrls, NSUInteger noOfTotalUrls);
39 | typedef void(^SDWebImagePrefetcherCompletionBlock)(NSUInteger noOfFinishedUrls, NSUInteger noOfSkippedUrls);
40 |
41 | /**
42 | * Prefetch some URLs in the cache for future use. Images are downloaded in low priority.
43 | */
44 | @interface SDWebImagePrefetcher : NSObject
45 |
46 | /**
47 | * The web image manager
48 | */
49 | @property (strong, nonatomic, readonly) SDWebImageManager *manager;
50 |
51 | /**
52 | * Maximum number of URLs to prefetch at the same time. Defaults to 3.
53 | */
54 | @property (nonatomic, assign) NSUInteger maxConcurrentDownloads;
55 |
56 | /**
57 | * SDWebImageOptions for prefetcher. Defaults to SDWebImageLowPriority.
58 | */
59 | @property (nonatomic, assign) SDWebImageOptions options;
60 |
61 | @property (weak, nonatomic) id delegate;
62 |
63 | /**
64 | * Return the global image prefetcher instance.
65 | */
66 | + (SDWebImagePrefetcher *)sharedImagePrefetcher;
67 |
68 | /**
69 | * Assign list of URLs to let SDWebImagePrefetcher to queue the prefetching,
70 | * currently one image is downloaded at a time,
71 | * and skips images for failed downloads and proceed to the next image in the list
72 | *
73 | * @param urls list of URLs to prefetch
74 | */
75 | - (void)prefetchURLs:(NSArray *)urls;
76 |
77 | /**
78 | * Assign list of URLs to let SDWebImagePrefetcher to queue the prefetching,
79 | * currently one image is downloaded at a time,
80 | * and skips images for failed downloads and proceed to the next image in the list
81 | *
82 | * @param urls list of URLs to prefetch
83 | * @param progressBlock block to be called when progress updates;
84 | * first parameter is the number of completed (successful or not) requests,
85 | * second parameter is the total number of images originally requested to be prefetched
86 | * @param completionBlock block to be called when prefetching is completed
87 | * first param is the number of completed (successful or not) requests,
88 | * second parameter is the number of skipped requests
89 | */
90 | - (void)prefetchURLs:(NSArray *)urls progress:(SDWebImagePrefetcherProgressBlock)progressBlock completed:(SDWebImagePrefetcherCompletionBlock)completionBlock;
91 |
92 | /**
93 | * Remove and cancel queued list
94 | */
95 | - (void)cancelPrefetching;
96 |
97 |
98 | @end
99 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/SDWebImage/SDWebImagePrefetcher.m:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImage package.
3 | * (c) Olivier Poitrey
4 | *
5 | * For the full copyright and license information, please view the LICENSE
6 | * file that was distributed with this source code.
7 | */
8 |
9 | #import "SDWebImagePrefetcher.h"
10 |
11 | #if !defined(DEBUG) && !defined (SD_VERBOSE)
12 | #define NSLog(...)
13 | #endif
14 |
15 | @interface SDWebImagePrefetcher ()
16 |
17 | @property (strong, nonatomic) SDWebImageManager *manager;
18 | @property (strong, nonatomic) NSArray *prefetchURLs;
19 | @property (assign, nonatomic) NSUInteger requestedCount;
20 | @property (assign, nonatomic) NSUInteger skippedCount;
21 | @property (assign, nonatomic) NSUInteger finishedCount;
22 | @property (assign, nonatomic) NSTimeInterval startedTime;
23 | @property (copy, nonatomic) SDWebImagePrefetcherCompletionBlock completionBlock;
24 | @property (copy, nonatomic) SDWebImagePrefetcherProgressBlock progressBlock;
25 |
26 | @end
27 |
28 | @implementation SDWebImagePrefetcher
29 |
30 | + (SDWebImagePrefetcher *)sharedImagePrefetcher {
31 | static dispatch_once_t once;
32 | static id instance;
33 | dispatch_once(&once, ^{
34 | instance = [self new];
35 | });
36 | return instance;
37 | }
38 |
39 | - (id)init {
40 | if ((self = [super init])) {
41 | _manager = [SDWebImageManager new];
42 | _options = SDWebImageLowPriority;
43 | self.maxConcurrentDownloads = 3;
44 | }
45 | return self;
46 | }
47 |
48 | - (void)setMaxConcurrentDownloads:(NSUInteger)maxConcurrentDownloads {
49 | self.manager.imageDownloader.maxConcurrentDownloads = maxConcurrentDownloads;
50 | }
51 |
52 | - (NSUInteger)maxConcurrentDownloads {
53 | return self.manager.imageDownloader.maxConcurrentDownloads;
54 | }
55 |
56 | - (void)startPrefetchingAtIndex:(NSUInteger)index {
57 | if (index >= self.prefetchURLs.count) return;
58 | self.requestedCount++;
59 | [self.manager downloadImageWithURL:self.prefetchURLs[index] options:self.options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
60 | if (!finished) return;
61 | self.finishedCount++;
62 |
63 | if (image) {
64 | if (self.progressBlock) {
65 | self.progressBlock(self.finishedCount,[self.prefetchURLs count]);
66 | }
67 | NSLog(@"Prefetched %@ out of %@", @(self.finishedCount), @(self.prefetchURLs.count));
68 | }
69 | else {
70 | if (self.progressBlock) {
71 | self.progressBlock(self.finishedCount,[self.prefetchURLs count]);
72 | }
73 | NSLog(@"Prefetched %@ out of %@ (Failed)", @(self.finishedCount), @(self.prefetchURLs.count));
74 |
75 | // Add last failed
76 | self.skippedCount++;
77 | }
78 | if ([self.delegate respondsToSelector:@selector(imagePrefetcher:didPrefetchURL:finishedCount:totalCount:)]) {
79 | [self.delegate imagePrefetcher:self
80 | didPrefetchURL:self.prefetchURLs[index]
81 | finishedCount:self.finishedCount
82 | totalCount:self.prefetchURLs.count
83 | ];
84 | }
85 |
86 | if (self.prefetchURLs.count > self.requestedCount) {
87 | dispatch_async(dispatch_get_main_queue(), ^{
88 | [self startPrefetchingAtIndex:self.requestedCount];
89 | });
90 | }
91 | else if (self.finishedCount == self.requestedCount) {
92 | [self reportStatus];
93 | if (self.completionBlock) {
94 | self.completionBlock(self.finishedCount, self.skippedCount);
95 | self.completionBlock = nil;
96 | }
97 | }
98 | }];
99 | }
100 |
101 | - (void)reportStatus {
102 | NSUInteger total = [self.prefetchURLs count];
103 | NSLog(@"Finished prefetching (%@ successful, %@ skipped, timeElasped %.2f)", @(total - self.skippedCount), @(self.skippedCount), CFAbsoluteTimeGetCurrent() - self.startedTime);
104 | if ([self.delegate respondsToSelector:@selector(imagePrefetcher:didFinishWithTotalCount:skippedCount:)]) {
105 | [self.delegate imagePrefetcher:self
106 | didFinishWithTotalCount:(total - self.skippedCount)
107 | skippedCount:self.skippedCount
108 | ];
109 | }
110 | }
111 |
112 | - (void)prefetchURLs:(NSArray *)urls {
113 | [self prefetchURLs:urls progress:nil completed:nil];
114 | }
115 |
116 | - (void)prefetchURLs:(NSArray *)urls progress:(SDWebImagePrefetcherProgressBlock)progressBlock completed:(SDWebImagePrefetcherCompletionBlock)completionBlock {
117 | [self cancelPrefetching]; // Prevent duplicate prefetch request
118 | self.startedTime = CFAbsoluteTimeGetCurrent();
119 | self.prefetchURLs = urls;
120 | self.completionBlock = completionBlock;
121 | self.progressBlock = progressBlock;
122 |
123 | // Starts prefetching from the very first image on the list with the max allowed concurrency
124 | NSUInteger listCount = self.prefetchURLs.count;
125 | for (NSUInteger i = 0; i < self.maxConcurrentDownloads && self.requestedCount < listCount; i++) {
126 | [self startPrefetchingAtIndex:i];
127 | }
128 | }
129 |
130 | - (void)cancelPrefetching {
131 | self.prefetchURLs = nil;
132 | self.skippedCount = 0;
133 | self.requestedCount = 0;
134 | self.finishedCount = 0;
135 | [self.manager cancelAll];
136 | }
137 |
138 | @end
139 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/SDWebImage/UIImage+GIF.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+GIF.h
3 | // LBGIFImage
4 | //
5 | // Created by Laurin Brandner on 06.01.12.
6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface UIImage (GIF)
12 |
13 | + (UIImage *)sd_animatedGIFNamed:(NSString *)name;
14 |
15 | + (UIImage *)sd_animatedGIFWithData:(NSData *)data;
16 |
17 | - (UIImage *)sd_animatedImageByScalingAndCroppingToSize:(CGSize)size;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/SDWebImage/UIImage+GIF.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+GIF.m
3 | // LBGIFImage
4 | //
5 | // Created by Laurin Brandner on 06.01.12.
6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved.
7 | //
8 |
9 | #import "UIImage+GIF.h"
10 | #import
11 |
12 | @implementation UIImage (GIF)
13 |
14 | + (UIImage *)sd_animatedGIFWithData:(NSData *)data {
15 | if (!data) {
16 | return nil;
17 | }
18 |
19 | CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
20 |
21 | size_t count = CGImageSourceGetCount(source);
22 |
23 | UIImage *animatedImage;
24 |
25 | if (count <= 1) {
26 | animatedImage = [[UIImage alloc] initWithData:data];
27 | }
28 | else {
29 | NSMutableArray *images = [NSMutableArray array];
30 |
31 | NSTimeInterval duration = 0.0f;
32 |
33 | for (size_t i = 0; i < count; i++) {
34 | CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL);
35 |
36 | duration += [self sd_frameDurationAtIndex:i source:source];
37 |
38 | [images addObject:[UIImage imageWithCGImage:image scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp]];
39 |
40 | CGImageRelease(image);
41 | }
42 |
43 | if (!duration) {
44 | duration = (1.0f / 10.0f) * count;
45 | }
46 |
47 | animatedImage = [UIImage animatedImageWithImages:images duration:duration];
48 | }
49 |
50 | CFRelease(source);
51 |
52 | return animatedImage;
53 | }
54 |
55 | + (float)sd_frameDurationAtIndex:(NSUInteger)index source:(CGImageSourceRef)source {
56 | float frameDuration = 0.1f;
57 | CFDictionaryRef cfFrameProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil);
58 | NSDictionary *frameProperties = (__bridge NSDictionary *)cfFrameProperties;
59 | NSDictionary *gifProperties = frameProperties[(NSString *)kCGImagePropertyGIFDictionary];
60 |
61 | NSNumber *delayTimeUnclampedProp = gifProperties[(NSString *)kCGImagePropertyGIFUnclampedDelayTime];
62 | if (delayTimeUnclampedProp) {
63 | frameDuration = [delayTimeUnclampedProp floatValue];
64 | }
65 | else {
66 |
67 | NSNumber *delayTimeProp = gifProperties[(NSString *)kCGImagePropertyGIFDelayTime];
68 | if (delayTimeProp) {
69 | frameDuration = [delayTimeProp floatValue];
70 | }
71 | }
72 |
73 | // Many annoying ads specify a 0 duration to make an image flash as quickly as possible.
74 | // We follow Firefox's behavior and use a duration of 100 ms for any frames that specify
75 | // a duration of <= 10 ms. See and
76 | // for more information.
77 |
78 | if (frameDuration < 0.011f) {
79 | frameDuration = 0.100f;
80 | }
81 |
82 | CFRelease(cfFrameProperties);
83 | return frameDuration;
84 | }
85 |
86 | + (UIImage *)sd_animatedGIFNamed:(NSString *)name {
87 | CGFloat scale = [UIScreen mainScreen].scale;
88 |
89 | if (scale > 1.0f) {
90 | NSString *retinaPath = [[NSBundle mainBundle] pathForResource:[name stringByAppendingString:@"@2x"] ofType:@"gif"];
91 |
92 | NSData *data = [NSData dataWithContentsOfFile:retinaPath];
93 |
94 | if (data) {
95 | return [UIImage sd_animatedGIFWithData:data];
96 | }
97 |
98 | NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:@"gif"];
99 |
100 | data = [NSData dataWithContentsOfFile:path];
101 |
102 | if (data) {
103 | return [UIImage sd_animatedGIFWithData:data];
104 | }
105 |
106 | return [UIImage imageNamed:name];
107 | }
108 | else {
109 | NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:@"gif"];
110 |
111 | NSData *data = [NSData dataWithContentsOfFile:path];
112 |
113 | if (data) {
114 | return [UIImage sd_animatedGIFWithData:data];
115 | }
116 |
117 | return [UIImage imageNamed:name];
118 | }
119 | }
120 |
121 | - (UIImage *)sd_animatedImageByScalingAndCroppingToSize:(CGSize)size {
122 | if (CGSizeEqualToSize(self.size, size) || CGSizeEqualToSize(size, CGSizeZero)) {
123 | return self;
124 | }
125 |
126 | CGSize scaledSize = size;
127 | CGPoint thumbnailPoint = CGPointZero;
128 |
129 | CGFloat widthFactor = size.width / self.size.width;
130 | CGFloat heightFactor = size.height / self.size.height;
131 | CGFloat scaleFactor = (widthFactor > heightFactor) ? widthFactor : heightFactor;
132 | scaledSize.width = self.size.width * scaleFactor;
133 | scaledSize.height = self.size.height * scaleFactor;
134 |
135 | if (widthFactor > heightFactor) {
136 | thumbnailPoint.y = (size.height - scaledSize.height) * 0.5;
137 | }
138 | else if (widthFactor < heightFactor) {
139 | thumbnailPoint.x = (size.width - scaledSize.width) * 0.5;
140 | }
141 |
142 | NSMutableArray *scaledImages = [NSMutableArray array];
143 |
144 | UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
145 |
146 | for (UIImage *image in self.images) {
147 | [image drawInRect:CGRectMake(thumbnailPoint.x, thumbnailPoint.y, scaledSize.width, scaledSize.height)];
148 | UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
149 |
150 | [scaledImages addObject:newImage];
151 | }
152 |
153 | UIGraphicsEndImageContext();
154 |
155 | return [UIImage animatedImageWithImages:scaledImages duration:self.duration];
156 | }
157 |
158 | @end
159 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/SDWebImage/UIImage+MultiFormat.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+MultiFormat.h
3 | // SDWebImage
4 | //
5 | // Created by Olivier Poitrey on 07/06/13.
6 | // Copyright (c) 2013 Dailymotion. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface UIImage (MultiFormat)
12 |
13 | + (UIImage *)sd_imageWithData:(NSData *)data;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/SDWebImage/UIImage+MultiFormat.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+MultiFormat.m
3 | // SDWebImage
4 | //
5 | // Created by Olivier Poitrey on 07/06/13.
6 | // Copyright (c) 2013 Dailymotion. All rights reserved.
7 | //
8 |
9 | #import "UIImage+MultiFormat.h"
10 | #import "UIImage+GIF.h"
11 | #import "NSData+ImageContentType.h"
12 | #import
13 |
14 | #ifdef SD_WEBP
15 | #import "UIImage+WebP.h"
16 | #endif
17 |
18 | @implementation UIImage (MultiFormat)
19 |
20 | + (UIImage *)sd_imageWithData:(NSData *)data {
21 | UIImage *image;
22 | NSString *imageContentType = [NSData sd_contentTypeForImageData:data];
23 | if ([imageContentType isEqualToString:@"image/gif"]) {
24 | image = [UIImage sd_animatedGIFWithData:data];
25 | }
26 | #ifdef SD_WEBP
27 | else if ([imageContentType isEqualToString:@"image/webp"])
28 | {
29 | image = [UIImage sd_imageWithWebPData:data];
30 | }
31 | #endif
32 | else {
33 | image = [[UIImage alloc] initWithData:data];
34 | UIImageOrientation orientation = [self sd_imageOrientationFromImageData:data];
35 | if (orientation != UIImageOrientationUp) {
36 | image = [UIImage imageWithCGImage:image.CGImage
37 | scale:image.scale
38 | orientation:orientation];
39 | }
40 | }
41 |
42 |
43 | return image;
44 | }
45 |
46 |
47 | +(UIImageOrientation)sd_imageOrientationFromImageData:(NSData *)imageData {
48 | UIImageOrientation result = UIImageOrientationUp;
49 | CGImageSourceRef imageSource = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL);
50 | if (imageSource) {
51 | CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, NULL);
52 | if (properties) {
53 | CFTypeRef val;
54 | int exifOrientation;
55 | val = CFDictionaryGetValue(properties, kCGImagePropertyOrientation);
56 | if (val) {
57 | CFNumberGetValue(val, kCFNumberIntType, &exifOrientation);
58 | result = [self sd_exifOrientationToiOSOrientation:exifOrientation];
59 | } // else - if it's not set it remains at up
60 | CFRelease((CFTypeRef) properties);
61 | } else {
62 | //NSLog(@"NO PROPERTIES, FAIL");
63 | }
64 | CFRelease(imageSource);
65 | }
66 | return result;
67 | }
68 |
69 | #pragma mark EXIF orientation tag converter
70 | // Convert an EXIF image orientation to an iOS one.
71 | // reference see here: http://sylvana.net/jpegcrop/exif_orientation.html
72 | + (UIImageOrientation) sd_exifOrientationToiOSOrientation:(int)exifOrientation {
73 | UIImageOrientation orientation = UIImageOrientationUp;
74 | switch (exifOrientation) {
75 | case 1:
76 | orientation = UIImageOrientationUp;
77 | break;
78 |
79 | case 3:
80 | orientation = UIImageOrientationDown;
81 | break;
82 |
83 | case 8:
84 | orientation = UIImageOrientationLeft;
85 | break;
86 |
87 | case 6:
88 | orientation = UIImageOrientationRight;
89 | break;
90 |
91 | case 2:
92 | orientation = UIImageOrientationUpMirrored;
93 | break;
94 |
95 | case 4:
96 | orientation = UIImageOrientationDownMirrored;
97 | break;
98 |
99 | case 5:
100 | orientation = UIImageOrientationLeftMirrored;
101 | break;
102 |
103 | case 7:
104 | orientation = UIImageOrientationRightMirrored;
105 | break;
106 | default:
107 | break;
108 | }
109 | return orientation;
110 | }
111 |
112 |
113 |
114 | @end
115 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/SDWebImage/UIImage+WebP.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+WebP.h
3 | // SDWebImage
4 | //
5 | // Created by Olivier Poitrey on 07/06/13.
6 | // Copyright (c) 2013 Dailymotion. All rights reserved.
7 | //
8 |
9 | #ifdef SD_WEBP
10 |
11 | #import
12 |
13 | // Fix for issue #416 Undefined symbols for architecture armv7 since WebP introduction when deploying to device
14 | void WebPInitPremultiplyNEON(void);
15 |
16 | void WebPInitUpsamplersNEON(void);
17 |
18 | void VP8DspInitNEON(void);
19 |
20 | @interface UIImage (WebP)
21 |
22 | + (UIImage *)sd_imageWithWebPData:(NSData *)data;
23 |
24 | @end
25 |
26 | #endif
27 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/SDWebImage/UIImage+WebP.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+WebP.m
3 | // SDWebImage
4 | //
5 | // Created by Olivier Poitrey on 07/06/13.
6 | // Copyright (c) 2013 Dailymotion. All rights reserved.
7 | //
8 |
9 | #ifdef SD_WEBP
10 | #import "UIImage+WebP.h"
11 | #import "webp/decode.h"
12 |
13 | // Callback for CGDataProviderRelease
14 | static void FreeImageData(void *info, const void *data, size_t size)
15 | {
16 | free((void *)data);
17 | }
18 |
19 | @implementation UIImage (WebP)
20 |
21 | + (UIImage *)sd_imageWithWebPData:(NSData *)data {
22 | WebPDecoderConfig config;
23 | if (!WebPInitDecoderConfig(&config)) {
24 | return nil;
25 | }
26 |
27 | config.output.colorspace = MODE_rgbA;
28 | config.options.use_threads = 1;
29 |
30 | // Decode the WebP image data into a RGBA value array.
31 | if (WebPDecode(data.bytes, data.length, &config) != VP8_STATUS_OK) {
32 | return nil;
33 | }
34 |
35 | int width = config.input.width;
36 | int height = config.input.height;
37 | if (config.options.use_scaling) {
38 | width = config.options.scaled_width;
39 | height = config.options.scaled_height;
40 | }
41 |
42 | // Construct a UIImage from the decoded RGBA value array.
43 | CGDataProviderRef provider =
44 | CGDataProviderCreateWithData(NULL, config.output.u.RGBA.rgba, config.output.u.RGBA.size, FreeImageData);
45 | CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
46 | CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast;
47 | CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
48 | CGImageRef imageRef = CGImageCreate(width, height, 8, 32, 4 * width, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);
49 |
50 | CGColorSpaceRelease(colorSpaceRef);
51 | CGDataProviderRelease(provider);
52 |
53 | UIImage *image = [[UIImage alloc] initWithCGImage:imageRef];
54 | CGImageRelease(imageRef);
55 |
56 | return image;
57 | }
58 |
59 | @end
60 |
61 | #if !COCOAPODS
62 | // Functions to resolve some undefined symbols when using WebP and force_load flag
63 | void WebPInitPremultiplyNEON(void) {}
64 | void WebPInitUpsamplersNEON(void) {}
65 | void VP8DspInitNEON(void) {}
66 | #endif
67 |
68 | #endif
69 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/SDWebImage/UIImageView+HighlightedWebCache.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImage package.
3 | * (c) Olivier Poitrey
4 | *
5 | * For the full copyright and license information, please view the LICENSE
6 | * file that was distributed with this source code.
7 | */
8 |
9 | #import
10 | #import "SDWebImageCompat.h"
11 | #import "SDWebImageManager.h"
12 |
13 | /**
14 | * Integrates SDWebImage async downloading and caching of remote images with UIImageView for highlighted state.
15 | */
16 | @interface UIImageView (HighlightedWebCache)
17 |
18 | /**
19 | * Set the imageView `highlightedImage` with an `url`.
20 | *
21 | * The download is asynchronous and cached.
22 | *
23 | * @param url The url for the image.
24 | */
25 | - (void)sd_setHighlightedImageWithURL:(NSURL *)url;
26 |
27 | /**
28 | * Set the imageView `highlightedImage` with an `url` and custom options.
29 | *
30 | * The download is asynchronous and cached.
31 | *
32 | * @param url The url for the image.
33 | * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
34 | */
35 | - (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options;
36 |
37 | /**
38 | * Set the imageView `highlightedImage` with an `url`.
39 | *
40 | * The download is asynchronous and cached.
41 | *
42 | * @param url The url for the image.
43 | * @param completedBlock A block called when operation has been completed. This block has no return value
44 | * and takes the requested UIImage as first parameter. In case of error the image parameter
45 | * is nil and the second parameter may contain an NSError. The third parameter is a Boolean
46 | * indicating if the image was retrived from the local cache or from the network.
47 | * The forth parameter is the original image url.
48 | */
49 | - (void)sd_setHighlightedImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock;
50 |
51 | /**
52 | * Set the imageView `highlightedImage` with an `url` and custom options.
53 | *
54 | * The download is asynchronous and cached.
55 | *
56 | * @param url The url for the image.
57 | * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
58 | * @param completedBlock A block called when operation has been completed. This block has no return value
59 | * and takes the requested UIImage as first parameter. In case of error the image parameter
60 | * is nil and the second parameter may contain an NSError. The third parameter is a Boolean
61 | * indicating if the image was retrived from the local cache or from the network.
62 | * The forth parameter is the original image url.
63 | */
64 | - (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock;
65 |
66 | /**
67 | * Set the imageView `highlightedImage` with an `url` and custom options.
68 | *
69 | * The download is asynchronous and cached.
70 | *
71 | * @param url The url for the image.
72 | * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
73 | * @param progressBlock A block called while image is downloading
74 | * @param completedBlock A block called when operation has been completed. This block has no return value
75 | * and takes the requested UIImage as first parameter. In case of error the image parameter
76 | * is nil and the second parameter may contain an NSError. The third parameter is a Boolean
77 | * indicating if the image was retrived from the local cache or from the network.
78 | * The forth parameter is the original image url.
79 | */
80 | - (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock;
81 |
82 | /**
83 | * Cancel the current download
84 | */
85 | - (void)sd_cancelCurrentHighlightedImageLoad;
86 |
87 | @end
88 |
89 |
90 | @interface UIImageView (HighlightedWebCacheDeprecated)
91 |
92 | - (void)setHighlightedImageWithURL:(NSURL *)url __deprecated_msg("Method deprecated. Use `sd_setHighlightedImageWithURL:`");
93 | - (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options __deprecated_msg("Method deprecated. Use `sd_setHighlightedImageWithURL:options:`");
94 | - (void)setHighlightedImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setHighlightedImageWithURL:completed:`");
95 | - (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setHighlightedImageWithURL:options:completed:`");
96 | - (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setHighlightedImageWithURL:options:progress:completed:`");
97 |
98 | - (void)cancelCurrentHighlightedImageLoad __deprecated_msg("Use `sd_cancelCurrentHighlightedImageLoad`");
99 |
100 | @end
101 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/SDWebImage/UIImageView+HighlightedWebCache.m:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImage package.
3 | * (c) Olivier Poitrey
4 | *
5 | * For the full copyright and license information, please view the LICENSE
6 | * file that was distributed with this source code.
7 | */
8 |
9 | #import "UIImageView+HighlightedWebCache.h"
10 | #import "UIView+WebCacheOperation.h"
11 |
12 | #define UIImageViewHighlightedWebCacheOperationKey @"highlightedImage"
13 |
14 | @implementation UIImageView (HighlightedWebCache)
15 |
16 | - (void)sd_setHighlightedImageWithURL:(NSURL *)url {
17 | [self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:nil];
18 | }
19 |
20 | - (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options {
21 | [self sd_setHighlightedImageWithURL:url options:options progress:nil completed:nil];
22 | }
23 |
24 | - (void)sd_setHighlightedImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock {
25 | [self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:completedBlock];
26 | }
27 |
28 | - (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock {
29 | [self sd_setHighlightedImageWithURL:url options:options progress:nil completed:completedBlock];
30 | }
31 |
32 | - (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock {
33 | [self sd_cancelCurrentHighlightedImageLoad];
34 |
35 | if (url) {
36 | __weak UIImageView *wself = self;
37 | id operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
38 | if (!wself) return;
39 | dispatch_main_sync_safe (^
40 | {
41 | if (!wself) return;
42 | if (image) {
43 | wself.highlightedImage = image;
44 | [wself setNeedsLayout];
45 | }
46 | if (completedBlock && finished) {
47 | completedBlock(image, error, cacheType, url);
48 | }
49 | });
50 | }];
51 | [self sd_setImageLoadOperation:operation forKey:UIImageViewHighlightedWebCacheOperationKey];
52 | } else {
53 | dispatch_main_async_safe(^{
54 | NSError *error = [NSError errorWithDomain:@"SDWebImageErrorDomain" code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];
55 | if (completedBlock) {
56 | completedBlock(nil, error, SDImageCacheTypeNone, url);
57 | }
58 | });
59 | }
60 | }
61 |
62 | - (void)sd_cancelCurrentHighlightedImageLoad {
63 | [self sd_cancelImageLoadOperationWithKey:UIImageViewHighlightedWebCacheOperationKey];
64 | }
65 |
66 | @end
67 |
68 |
69 | @implementation UIImageView (HighlightedWebCacheDeprecated)
70 |
71 | - (void)setHighlightedImageWithURL:(NSURL *)url {
72 | [self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:nil];
73 | }
74 |
75 | - (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options {
76 | [self sd_setHighlightedImageWithURL:url options:options progress:nil completed:nil];
77 | }
78 |
79 | - (void)setHighlightedImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock {
80 | [self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
81 | if (completedBlock) {
82 | completedBlock(image, error, cacheType);
83 | }
84 | }];
85 | }
86 |
87 | - (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock {
88 | [self sd_setHighlightedImageWithURL:url options:options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
89 | if (completedBlock) {
90 | completedBlock(image, error, cacheType);
91 | }
92 | }];
93 | }
94 |
95 | - (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedBlock)completedBlock {
96 | [self sd_setHighlightedImageWithURL:url options:0 progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
97 | if (completedBlock) {
98 | completedBlock(image, error, cacheType);
99 | }
100 | }];
101 | }
102 |
103 | - (void)cancelCurrentHighlightedImageLoad {
104 | [self sd_cancelCurrentHighlightedImageLoad];
105 | }
106 |
107 | @end
108 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/SDWebImage/UIImageView+WebCache.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImage package.
3 | * (c) Olivier Poitrey
4 | *
5 | * For the full copyright and license information, please view the LICENSE
6 | * file that was distributed with this source code.
7 | */
8 |
9 | #import "SDWebImageCompat.h"
10 | #import "SDWebImageManager.h"
11 |
12 | /**
13 | * Integrates SDWebImage async downloading and caching of remote images with UIImageView.
14 | *
15 | * Usage with a UITableViewCell sub-class:
16 | *
17 | * @code
18 |
19 | #import
20 |
21 | ...
22 |
23 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
24 | {
25 | static NSString *MyIdentifier = @"MyIdentifier";
26 |
27 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
28 |
29 | if (cell == nil) {
30 | cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier]
31 | autorelease];
32 | }
33 |
34 | // Here we use the provided sd_setImageWithURL: method to load the web image
35 | // Ensure you use a placeholder image otherwise cells will be initialized with no image
36 | [cell.imageView sd_setImageWithURL:[NSURL URLWithString:@"http://example.com/image.jpg"]
37 | placeholderImage:[UIImage imageNamed:@"placeholder"]];
38 |
39 | cell.textLabel.text = @"My Text";
40 | return cell;
41 | }
42 |
43 | * @endcode
44 | */
45 | @interface UIImageView (WebCache)
46 |
47 | /**
48 | * Get the current image URL.
49 | *
50 | * Note that because of the limitations of categories this property can get out of sync
51 | * if you use sd_setImage: directly.
52 | */
53 | - (NSURL *)sd_imageURL;
54 |
55 | /**
56 | * Set the imageView `image` with an `url`.
57 | *
58 | * The download is asynchronous and cached.
59 | *
60 | * @param url The url for the image.
61 | */
62 | - (void)sd_setImageWithURL:(NSURL *)url;
63 |
64 | /**
65 | * Set the imageView `image` with an `url` and a placeholder.
66 | *
67 | * The download is asynchronous and cached.
68 | *
69 | * @param url The url for the image.
70 | * @param placeholder The image to be set initially, until the image request finishes.
71 | * @see sd_setImageWithURL:placeholderImage:options:
72 | */
73 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder;
74 |
75 | /**
76 | * Set the imageView `image` with an `url`, placeholder and custom options.
77 | *
78 | * The download is asynchronous and cached.
79 | *
80 | * @param url The url for the image.
81 | * @param placeholder The image to be set initially, until the image request finishes.
82 | * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
83 | */
84 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options;
85 |
86 | /**
87 | * Set the imageView `image` with an `url`.
88 | *
89 | * The download is asynchronous and cached.
90 | *
91 | * @param url The url for the image.
92 | * @param completedBlock A block called when operation has been completed. This block has no return value
93 | * and takes the requested UIImage as first parameter. In case of error the image parameter
94 | * is nil and the second parameter may contain an NSError. The third parameter is a Boolean
95 | * indicating if the image was retrived from the local cache or from the network.
96 | * The forth parameter is the original image url.
97 | */
98 | - (void)sd_setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock;
99 |
100 | /**
101 | * Set the imageView `image` with an `url`, placeholder.
102 | *
103 | * The download is asynchronous and cached.
104 | *
105 | * @param url The url for the image.
106 | * @param placeholder The image to be set initially, until the image request finishes.
107 | * @param completedBlock A block called when operation has been completed. This block has no return value
108 | * and takes the requested UIImage as first parameter. In case of error the image parameter
109 | * is nil and the second parameter may contain an NSError. The third parameter is a Boolean
110 | * indicating if the image was retrived from the local cache or from the network.
111 | * The forth parameter is the original image url.
112 | */
113 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock;
114 |
115 | /**
116 | * Set the imageView `image` with an `url`, placeholder and custom options.
117 | *
118 | * The download is asynchronous and cached.
119 | *
120 | * @param url The url for the image.
121 | * @param placeholder The image to be set initially, until the image request finishes.
122 | * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
123 | * @param completedBlock A block called when operation has been completed. This block has no return value
124 | * and takes the requested UIImage as first parameter. In case of error the image parameter
125 | * is nil and the second parameter may contain an NSError. The third parameter is a Boolean
126 | * indicating if the image was retrived from the local cache or from the network.
127 | * The forth parameter is the original image url.
128 | */
129 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock;
130 |
131 | /**
132 | * Set the imageView `image` with an `url`, placeholder and custom options.
133 | *
134 | * The download is asynchronous and cached.
135 | *
136 | * @param url The url for the image.
137 | * @param placeholder The image to be set initially, until the image request finishes.
138 | * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
139 | * @param progressBlock A block called while image is downloading
140 | * @param completedBlock A block called when operation has been completed. This block has no return value
141 | * and takes the requested UIImage as first parameter. In case of error the image parameter
142 | * is nil and the second parameter may contain an NSError. The third parameter is a Boolean
143 | * indicating if the image was retrived from the local cache or from the network.
144 | * The forth parameter is the original image url.
145 | */
146 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock;
147 |
148 | /**
149 | * Set the imageView `image` with an `url` and a optionaly placeholder image.
150 | *
151 | * The download is asynchronous and cached.
152 | *
153 | * @param url The url for the image.
154 | * @param placeholder The image to be set initially, until the image request finishes.
155 | * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
156 | * @param progressBlock A block called while image is downloading
157 | * @param completedBlock A block called when operation has been completed. This block has no return value
158 | * and takes the requested UIImage as first parameter. In case of error the image parameter
159 | * is nil and the second parameter may contain an NSError. The third parameter is a Boolean
160 | * indicating if the image was retrived from the local cache or from the network.
161 | * The forth parameter is the original image url.
162 | */
163 | - (void)sd_setImageWithPreviousCachedImageWithURL:(NSURL *)url andPlaceholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock;
164 |
165 | /**
166 | * Download an array of images and starts them in an animation loop
167 | *
168 | * @param arrayOfURLs An array of NSURL
169 | */
170 | - (void)sd_setAnimationImagesWithURLs:(NSArray *)arrayOfURLs;
171 |
172 | /**
173 | * Cancel the current download
174 | */
175 | - (void)sd_cancelCurrentImageLoad;
176 |
177 | - (void)sd_cancelCurrentAnimationImagesLoad;
178 |
179 | @end
180 |
181 |
182 | @interface UIImageView (WebCacheDeprecated)
183 |
184 | - (NSURL *)imageURL __deprecated_msg("Use `sd_imageURL`");
185 |
186 | - (void)setImageWithURL:(NSURL *)url __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:`");
187 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:`");
188 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:options`");
189 |
190 | - (void)setImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:completed:`");
191 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:completed:`");
192 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:options:completed:`");
193 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:options:progress:completed:`");
194 |
195 | - (void)setAnimationImagesWithURLs:(NSArray *)arrayOfURLs __deprecated_msg("Use `sd_setAnimationImagesWithURLs:`");
196 |
197 | - (void)cancelCurrentArrayLoad __deprecated_msg("Use `sd_cancelCurrentAnimationImagesLoad`");
198 |
199 | - (void)cancelCurrentImageLoad __deprecated_msg("Use `sd_cancelCurrentImageLoad`");
200 |
201 | @end
202 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/SDWebImage/UIImageView+WebCache.m:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImage package.
3 | * (c) Olivier Poitrey
4 | *
5 | * For the full copyright and license information, please view the LICENSE
6 | * file that was distributed with this source code.
7 | */
8 |
9 | #import "UIImageView+WebCache.h"
10 | #import "objc/runtime.h"
11 | #import "UIView+WebCacheOperation.h"
12 |
13 | static char imageURLKey;
14 |
15 | @implementation UIImageView (WebCache)
16 |
17 | - (void)sd_setImageWithURL:(NSURL *)url {
18 | [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil];
19 | }
20 |
21 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder {
22 | [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil];
23 | }
24 |
25 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options {
26 | [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil];
27 | }
28 |
29 | - (void)sd_setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock {
30 | [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock];
31 | }
32 |
33 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock {
34 | [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:completedBlock];
35 | }
36 |
37 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock {
38 | [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:completedBlock];
39 | }
40 |
41 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock {
42 | [self sd_cancelCurrentImageLoad];
43 | objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
44 |
45 | if (!(options & SDWebImageDelayPlaceholder)) {
46 | self.image = placeholder;
47 | }
48 |
49 | if (url) {
50 | __weak UIImageView *wself = self;
51 | id operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
52 | if (!wself) return;
53 | dispatch_main_sync_safe(^{
54 | if (!wself) return;
55 | if (image) {
56 | wself.image = image;
57 | [wself setNeedsLayout];
58 | } else {
59 | if ((options & SDWebImageDelayPlaceholder)) {
60 | wself.image = placeholder;
61 | [wself setNeedsLayout];
62 | }
63 | }
64 | if (completedBlock && finished) {
65 | completedBlock(image, error, cacheType, url);
66 | }
67 | });
68 | }];
69 | [self sd_setImageLoadOperation:operation forKey:@"UIImageViewImageLoad"];
70 | } else {
71 | dispatch_main_async_safe(^{
72 | NSError *error = [NSError errorWithDomain:@"SDWebImageErrorDomain" code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];
73 | if (completedBlock) {
74 | completedBlock(nil, error, SDImageCacheTypeNone, url);
75 | }
76 | });
77 | }
78 | }
79 |
80 | - (void)sd_setImageWithPreviousCachedImageWithURL:(NSURL *)url andPlaceholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock {
81 | NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:url];
82 | UIImage *lastPreviousCachedImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:key];
83 |
84 | [self sd_setImageWithURL:url placeholderImage:lastPreviousCachedImage ?: placeholder options:options progress:progressBlock completed:completedBlock];
85 | }
86 |
87 | - (NSURL *)sd_imageURL {
88 | return objc_getAssociatedObject(self, &imageURLKey);
89 | }
90 |
91 | - (void)sd_setAnimationImagesWithURLs:(NSArray *)arrayOfURLs {
92 | [self sd_cancelCurrentAnimationImagesLoad];
93 | __weak UIImageView *wself = self;
94 |
95 | NSMutableArray *operationsArray = [[NSMutableArray alloc] init];
96 |
97 | for (NSURL *logoImageURL in arrayOfURLs) {
98 | id operation = [SDWebImageManager.sharedManager downloadImageWithURL:logoImageURL options:0 progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
99 | if (!wself) return;
100 | dispatch_main_sync_safe(^{
101 | __strong UIImageView *sself = wself;
102 | [sself stopAnimating];
103 | if (sself && image) {
104 | NSMutableArray *currentImages = [[sself animationImages] mutableCopy];
105 | if (!currentImages) {
106 | currentImages = [[NSMutableArray alloc] init];
107 | }
108 | [currentImages addObject:image];
109 |
110 | sself.animationImages = currentImages;
111 | [sself setNeedsLayout];
112 | }
113 | [sself startAnimating];
114 | });
115 | }];
116 | [operationsArray addObject:operation];
117 | }
118 |
119 | [self sd_setImageLoadOperation:[NSArray arrayWithArray:operationsArray] forKey:@"UIImageViewAnimationImages"];
120 | }
121 |
122 | - (void)sd_cancelCurrentImageLoad {
123 | [self sd_cancelImageLoadOperationWithKey:@"UIImageViewImageLoad"];
124 | }
125 |
126 | - (void)sd_cancelCurrentAnimationImagesLoad {
127 | [self sd_cancelImageLoadOperationWithKey:@"UIImageViewAnimationImages"];
128 | }
129 |
130 | @end
131 |
132 |
133 | @implementation UIImageView (WebCacheDeprecated)
134 |
135 | - (NSURL *)imageURL {
136 | return [self sd_imageURL];
137 | }
138 |
139 | - (void)setImageWithURL:(NSURL *)url {
140 | [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil];
141 | }
142 |
143 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder {
144 | [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil];
145 | }
146 |
147 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options {
148 | [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil];
149 | }
150 |
151 | - (void)setImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock {
152 | [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
153 | if (completedBlock) {
154 | completedBlock(image, error, cacheType);
155 | }
156 | }];
157 | }
158 |
159 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock {
160 | [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
161 | if (completedBlock) {
162 | completedBlock(image, error, cacheType);
163 | }
164 | }];
165 | }
166 |
167 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock {
168 | [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
169 | if (completedBlock) {
170 | completedBlock(image, error, cacheType);
171 | }
172 | }];
173 | }
174 |
175 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedBlock)completedBlock {
176 | [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
177 | if (completedBlock) {
178 | completedBlock(image, error, cacheType);
179 | }
180 | }];
181 | }
182 |
183 | - (void)cancelCurrentArrayLoad {
184 | [self sd_cancelCurrentAnimationImagesLoad];
185 | }
186 |
187 | - (void)cancelCurrentImageLoad {
188 | [self sd_cancelCurrentImageLoad];
189 | }
190 |
191 | - (void)setAnimationImagesWithURLs:(NSArray *)arrayOfURLs {
192 | [self sd_setAnimationImagesWithURLs:arrayOfURLs];
193 | }
194 |
195 | @end
196 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/SDWebImage/UIView+WebCacheOperation.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImage package.
3 | * (c) Olivier Poitrey
4 | *
5 | * For the full copyright and license information, please view the LICENSE
6 | * file that was distributed with this source code.
7 | */
8 |
9 | #import
10 | #import "SDWebImageManager.h"
11 |
12 | @interface UIView (WebCacheOperation)
13 |
14 | /**
15 | * Set the image load operation (storage in a UIView based dictionary)
16 | *
17 | * @param operation the operation
18 | * @param key key for storing the operation
19 | */
20 | - (void)sd_setImageLoadOperation:(id)operation forKey:(NSString *)key;
21 |
22 | /**
23 | * Cancel all operations for the current UIView and key
24 | *
25 | * @param key key for identifying the operations
26 | */
27 | - (void)sd_cancelImageLoadOperationWithKey:(NSString *)key;
28 |
29 | /**
30 | * Just remove the operations corresponding to the current UIView and key without cancelling them
31 | *
32 | * @param key key for identifying the operations
33 | */
34 | - (void)sd_removeImageLoadOperationWithKey:(NSString *)key;
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/SDWebImage/UIView+WebCacheOperation.m:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImage package.
3 | * (c) Olivier Poitrey
4 | *
5 | * For the full copyright and license information, please view the LICENSE
6 | * file that was distributed with this source code.
7 | */
8 |
9 | #import "UIView+WebCacheOperation.h"
10 | #import "objc/runtime.h"
11 |
12 | static char loadOperationKey;
13 |
14 | @implementation UIView (WebCacheOperation)
15 |
16 | - (NSMutableDictionary *)operationDictionary {
17 | NSMutableDictionary *operations = objc_getAssociatedObject(self, &loadOperationKey);
18 | if (operations) {
19 | return operations;
20 | }
21 | operations = [NSMutableDictionary dictionary];
22 | objc_setAssociatedObject(self, &loadOperationKey, operations, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
23 | return operations;
24 | }
25 |
26 | - (void)sd_setImageLoadOperation:(id)operation forKey:(NSString *)key {
27 | [self sd_cancelImageLoadOperationWithKey:key];
28 | NSMutableDictionary *operationDictionary = [self operationDictionary];
29 | [operationDictionary setObject:operation forKey:key];
30 | }
31 |
32 | - (void)sd_cancelImageLoadOperationWithKey:(NSString *)key {
33 | // Cancel in progress downloader from queue
34 | NSMutableDictionary *operationDictionary = [self operationDictionary];
35 | id operations = [operationDictionary objectForKey:key];
36 | if (operations) {
37 | if ([operations isKindOfClass:[NSArray class]]) {
38 | for (id operation in operations) {
39 | if (operation) {
40 | [operation cancel];
41 | }
42 | }
43 | } else if ([operations conformsToProtocol:@protocol(SDWebImageOperation)]){
44 | [(id) operations cancel];
45 | }
46 | [operationDictionary removeObjectForKey:key];
47 | }
48 | }
49 |
50 | - (void)sd_removeImageLoadOperationWithKey:(NSString *)key {
51 | NSMutableDictionary *operationDictionary = [self operationDictionary];
52 | [operationDictionary removeObjectForKey:key];
53 | }
54 |
55 | @end
56 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/SVProgressHUD/SVProgressHUD-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header for all source files of the 'SVProgressHUD' target in the 'SVProgressHUD' project
3 | //
4 |
5 | #ifdef __OBJC__
6 | #import
7 | #endif
8 |
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/SVProgressHUD/SVProgressHUD.bundle/angle-mask@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/2DimensionLovers/e-Hentai/36f15e7874bc06b631767f07a2c18aac1302190a/e-Hentai/ThirdParty/SVProgressHUD/SVProgressHUD.bundle/angle-mask@2x.png
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/SVProgressHUD/SVProgressHUD.bundle/error@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/2DimensionLovers/e-Hentai/36f15e7874bc06b631767f07a2c18aac1302190a/e-Hentai/ThirdParty/SVProgressHUD/SVProgressHUD.bundle/error@2x.png
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/SVProgressHUD/SVProgressHUD.bundle/success@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/2DimensionLovers/e-Hentai/36f15e7874bc06b631767f07a2c18aac1302190a/e-Hentai/ThirdParty/SVProgressHUD/SVProgressHUD.bundle/success@2x.png
--------------------------------------------------------------------------------
/e-Hentai/ThirdParty/SVProgressHUD/SVProgressHUD.h:
--------------------------------------------------------------------------------
1 | //
2 | // SVProgressHUD.h
3 | //
4 | // Created by Sam Vermette on 27.03.11.
5 | // Copyright 2011 Sam Vermette. All rights reserved.
6 | //
7 | // https://github.com/samvermette/SVProgressHUD
8 | //
9 |
10 | #import
11 | #import
12 |
13 | extern NSString * const SVProgressHUDDidReceiveTouchEventNotification;
14 | extern NSString * const SVProgressHUDWillDisappearNotification;
15 | extern NSString * const SVProgressHUDDidDisappearNotification;
16 | extern NSString * const SVProgressHUDWillAppearNotification;
17 | extern NSString * const SVProgressHUDDidAppearNotification;
18 |
19 | extern NSString * const SVProgressHUDStatusUserInfoKey;
20 |
21 | enum {
22 | SVProgressHUDMaskTypeNone = 1, // allow user interactions while HUD is displayed
23 | SVProgressHUDMaskTypeClear, // don't allow
24 | SVProgressHUDMaskTypeBlack, // don't allow and dim the UI in the back of the HUD
25 | SVProgressHUDMaskTypeGradient // don't allow and dim the UI with a a-la-alert-view bg gradient
26 | };
27 |
28 | typedef NSUInteger SVProgressHUDMaskType;
29 |
30 | @interface SVProgressHUD : UIView
31 |
32 | #pragma mark - Customization
33 |
34 | + (void)setBackgroundColor:(UIColor*)color; // default is [UIColor whiteColor]
35 | + (void)setForegroundColor:(UIColor*)color; // default is [UIColor blackColor]
36 | + (void)setRingThickness:(CGFloat)width; // default is 4 pt
37 | + (void)setFont:(UIFont*)font; // default is [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline]
38 | + (void)setSuccessImage:(UIImage*)image; // default is bundled success image from Glyphish
39 | + (void)setErrorImage:(UIImage*)image; // default is bundled error image from Glyphish
40 |
41 | #pragma mark - Show Methods
42 |
43 | + (void)show;
44 | + (void)showWithMaskType:(SVProgressHUDMaskType)maskType;
45 | + (void)showWithStatus:(NSString*)status;
46 | + (void)showWithStatus:(NSString*)status maskType:(SVProgressHUDMaskType)maskType;
47 |
48 | + (void)showProgress:(float)progress;
49 | + (void)showProgress:(float)progress status:(NSString*)status;
50 | + (void)showProgress:(float)progress status:(NSString*)status maskType:(SVProgressHUDMaskType)maskType;
51 |
52 | + (void)setStatus:(NSString*)string; // change the HUD loading status while it's showing
53 |
54 | // stops the activity indicator, shows a glyph + status, and dismisses HUD 1s later
55 | + (void)showSuccessWithStatus:(NSString*)string;
56 | + (void)showErrorWithStatus:(NSString *)string;
57 | + (void)showImage:(UIImage*)image status:(NSString*)status; // use 28x28 white pngs
58 |
59 | + (void)setOffsetFromCenter:(UIOffset)offset;
60 | + (void)resetOffsetFromCenter;
61 |
62 | + (void)popActivity;
63 | + (void)dismiss;
64 |
65 | + (BOOL)isVisible;
66 |
67 | @end
68 |
69 |
70 | @interface SVIndefiniteAnimatedView : UIView
71 |
72 | @property (nonatomic, assign) CGFloat strokeThickness;
73 | @property (nonatomic, assign) CGFloat radius;
74 | @property (nonatomic, strong) UIColor *strokeColor;
75 |
76 | @end
--------------------------------------------------------------------------------
/e-Hentai/e-Hentai-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIdentifier
12 | tw.tyche.${PRODUCT_NAME:rfc1034identifier}
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.0
25 | LSRequiresIPhoneOS
26 |
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/e-Hentai/e-Hentai-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header
3 | //
4 | // The contents of this file are implicitly included at the beginning of every source file.
5 | //
6 |
7 | #import
8 |
9 | #ifndef __IPHONE_5_0
10 | #warning "This project uses features only available in iOS SDK 5.0 and later."
11 | #endif
12 |
13 | #ifdef __OBJC__
14 | #import
15 | #import
16 |
17 | //from project
18 | #import "SVProgressHUD.h"
19 | #import "TFHpple.h"
20 | #import "UIImageView+WebCache.h"
21 | #import "HentaiParser.h"
22 | #import "FilesManager.h"
23 | #import "LightWeightPlist.h"
24 | #import "HentaiDownloadCenter.h"
25 |
26 | //LightWeightPlist
27 | #define HentaiCacheLibraryDictionary LWPDictionary(@"HentaiCacheLibrary")
28 | #define HentaiSaveLibraryArray LWPArray(@"HentaiSaveLibrary")
29 |
30 | #endif
31 |
--------------------------------------------------------------------------------
/e-Hentai/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/e-Hentai/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // e-Hentai
4 | //
5 | // Created by 啟倫 陳 on 2014/8/27.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "AppDelegate.h"
12 |
13 | int main(int argc, char * argv[])
14 | {
15 | @autoreleasepool {
16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/e-HentaiTests/e-HentaiTests-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | tw.tyche.${PRODUCT_NAME:rfc1034identifier}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundlePackageType
14 | BNDL
15 | CFBundleShortVersionString
16 | 1.0
17 | CFBundleSignature
18 | ????
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/e-HentaiTests/e_HentaiTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // e_HentaiTests.m
3 | // e-HentaiTests
4 | //
5 | // Created by 啟倫 陳 on 2014/8/27.
6 | // Copyright (c) 2014年 ChilunChen. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface e_HentaiTests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation e_HentaiTests
16 |
17 | - (void)setUp
18 | {
19 | [super setUp];
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 | }
22 |
23 | - (void)tearDown
24 | {
25 | // Put teardown code here. This method is called after the invocation of each test method in the class.
26 | [super tearDown];
27 | }
28 |
29 | - (void)testExample
30 | {
31 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__);
32 | }
33 |
34 | @end
35 |
--------------------------------------------------------------------------------
/e-HentaiTests/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------