• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

BathyScapheの中身をぐちゃぐちゃに


Commit MetaInfo

Revision2c9e3d3950c1bccb67fb54038344c2cf49739714 (tree)
Time2012-07-21 21:49:10
Authormasakih <masakih@b61f...>
Commitermasakih

Log Message

change smartboard and favorite updating mechanism.

git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/bathyscaphe/bathyscaphe/trunk@1447 b61fe662-1e22-0410-9ebe-d5d0f6be7d5c

Change Summary

Incremental Difference

--- a/application/BathyScaphe.xcodeproj/project.pbxproj
+++ b/application/BathyScaphe.xcodeproj/project.pbxproj
@@ -400,6 +400,8 @@
400400 F426B080119831AA00E169D4 /* BSWhereClauseCreator.h in Headers */ = {isa = PBXBuildFile; fileRef = F426B07E119831AA00E169D4 /* BSWhereClauseCreator.h */; };
401401 F437FD671199AF3B00D078FB /* SmartBoardItemEditor.xib in Resources */ = {isa = PBXBuildFile; fileRef = F437FD651199AF3B00D078FB /* SmartBoardItemEditor.xib */; };
402402 F440D7330C315929000458FF /* DatabaseManager-Notifications.m in Sources */ = {isa = PBXBuildFile; fileRef = F440D7310C315929000458FF /* DatabaseManager-Notifications.m */; };
403+ F4458B3615A876580096B358 /* BSSmartBoardUpdateTask.h in Headers */ = {isa = PBXBuildFile; fileRef = F4458B3415A876580096B358 /* BSSmartBoardUpdateTask.h */; };
404+ F4458B3715A876580096B358 /* BSSmartBoardUpdateTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F4458B3515A876580096B358 /* BSSmartBoardUpdateTask.m */; };
403405 F44A24D711964AE900C60F2D /* XspfMLabelField.h in Headers */ = {isa = PBXBuildFile; fileRef = F44A24C611964AE900C60F2D /* XspfMLabelField.h */; };
404406 F44A24D811964AE900C60F2D /* XspfMLabelField.m in Sources */ = {isa = PBXBuildFile; fileRef = F44A24C711964AE900C60F2D /* XspfMLabelField.m */; };
405407 F44A24D911964AE900C60F2D /* XspfMRule_NSExpressionFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = F44A24C811964AE900C60F2D /* XspfMRule_NSExpressionFunctions.m */; };
@@ -723,7 +725,6 @@
723725 F4FEF9E40AFF89A00099853B /* BSDownloadTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F41308B10A8E279300740620 /* BSDownloadTask.m */; };
724726 F4FEF9E50AFF89A10099853B /* BSThreadsListOPTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F41308B90A8E27A400740620 /* BSThreadsListOPTask.m */; };
725727 F4FEF9E60AFF89A30099853B /* BSThreadListUpdateTask.h in Headers */ = {isa = PBXBuildFile; fileRef = F411498409DABFD500DDF200 /* BSThreadListUpdateTask.h */; };
726- F4FEF9E90AFF89A60099853B /* BSBoardListItemHEADCheckTask.m in Sources */ = {isa = PBXBuildFile; fileRef = F486FC640A8F69EA00D44828 /* BSBoardListItemHEADCheckTask.m */; };
727728 F4FEF9EA0AFF89A80099853B /* DatabaseManager-DatabaseAccess.m in Sources */ = {isa = PBXBuildFile; fileRef = F47A66D70AFF808D00EB5137 /* DatabaseManager-DatabaseAccess.m */; };
728729 F4FEF9EB0AFF89A80099853B /* BoardListItem.m in Sources */ = {isa = PBXBuildFile; fileRef = F47A66C60AFF807100EB5137 /* BoardListItem.m */; };
729730 F4FEF9EC0AFF89A90099853B /* BSBoardListItemHEADCheckTask.h in Headers */ = {isa = PBXBuildFile; fileRef = F486FC630A8F69EA00D44828 /* BSBoardListItemHEADCheckTask.h */; };
@@ -1512,6 +1513,8 @@
15121513 F4369C0C0AFF7CFC005ABD68 /* libsqlite.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsqlite.a; sourceTree = BUILT_PRODUCTS_DIR; };
15131514 F437FD661199AF3B00D078FB /* Japanese */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Japanese; path = Resources/Japanese.lproj/SmartBoardItemEditor.xib; sourceTree = "<group>"; };
15141515 F440D7310C315929000458FF /* DatabaseManager-Notifications.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "DatabaseManager-Notifications.m"; sourceTree = "<group>"; };
1516+ F4458B3415A876580096B358 /* BSSmartBoardUpdateTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BSSmartBoardUpdateTask.h; sourceTree = "<group>"; };
1517+ F4458B3515A876580096B358 /* BSSmartBoardUpdateTask.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BSSmartBoardUpdateTask.m; sourceTree = "<group>"; };
15151518 F44A24C611964AE900C60F2D /* XspfMLabelField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XspfMLabelField.h; sourceTree = "<group>"; };
15161519 F44A24C711964AE900C60F2D /* XspfMLabelField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XspfMLabelField.m; sourceTree = "<group>"; };
15171520 F44A24C811964AE900C60F2D /* XspfMRule_NSExpressionFunctions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XspfMRule_NSExpressionFunctions.m; sourceTree = "<group>"; };
@@ -2221,6 +2224,8 @@
22212224 F41308B10A8E279300740620 /* BSDownloadTask.m */,
22222225 F411498409DABFD500DDF200 /* BSThreadListUpdateTask.h */,
22232226 F411498509DABFD500DDF200 /* BSThreadListUpdateTask.m */,
2227+ F4458B3415A876580096B358 /* BSSmartBoardUpdateTask.h */,
2228+ F4458B3515A876580096B358 /* BSSmartBoardUpdateTask.m */,
22242229 F324DC4804C698FA00A80005 /* CMRThreadsList.h */,
22252230 F324DC4A04C698FA00A80005 /* CMRThreadsList_p.h */,
22262231 F324DC4904C698FA00A80005 /* CMRThreadsList.m */,
@@ -3418,6 +3423,7 @@
34183423 8715AAA81477FB6A00135078 /* BSLastUpdatedHeaderCell.h in Headers */,
34193424 87F1EF001514E1C500B5FDEE /* BSThreadsListDataSource.h in Headers */,
34203425 F4C45F59154CDB9900D00D27 /* BSThreadListTask.h in Headers */,
3426+ F4458B3615A876580096B358 /* BSSmartBoardUpdateTask.h in Headers */,
34213427 );
34223428 runOnlyForDeploymentPostprocessing = 0;
34233429 };
@@ -4007,7 +4013,6 @@
40074013 F473637B0AFF8758009B6189 /* BSAsciiArtDetector.m in Sources */,
40084014 F4FEF9E40AFF89A00099853B /* BSDownloadTask.m in Sources */,
40094015 F4FEF9E50AFF89A10099853B /* BSThreadsListOPTask.m in Sources */,
4010- F4FEF9E90AFF89A60099853B /* BSBoardListItemHEADCheckTask.m in Sources */,
40114016 F4FEF9EA0AFF89A80099853B /* DatabaseManager-DatabaseAccess.m in Sources */,
40124017 F4FEF9EB0AFF89A80099853B /* BoardListItem.m in Sources */,
40134018 F4FEF9ED0AFF89AB0099853B /* FolderBoardListItem.m in Sources */,
@@ -4104,6 +4109,7 @@
41044109 87D119AC13D1D2B900D57AFC /* BSAppResetPanelController.m in Sources */,
41054110 8715AAA91477FB6A00135078 /* BSLastUpdatedHeaderCell.m in Sources */,
41064111 F4C45F5A154CDB9900D00D27 /* BSThreadListTask.m in Sources */,
4112+ F4458B3715A876580096B358 /* BSSmartBoardUpdateTask.m in Sources */,
41074113 );
41084114 runOnlyForDeploymentPostprocessing = 0;
41094115 };
--- a/application/source/bbs/BoardListItem/FavoritesBoardListItem.h
+++ b/application/source/bbs/BoardListItem/FavoritesBoardListItem.h
@@ -13,7 +13,6 @@
1313 @interface FavoritesBoardListItem : AbstractDBBoardListItem
1414 {
1515 id <SQLiteCursor> items;
16- BOOL dirty;
1716 }
1817
1918 + (id) sharedInstance;
--- a/application/source/bbs/BoardListItem/FavoritesBoardListItem.m
+++ b/application/source/bbs/BoardListItem/FavoritesBoardListItem.m
@@ -12,19 +12,12 @@
1212
1313 #import "DatabaseManager.h"
1414 #import "CMRBBSListTemplateKeys.h"
15-#import "CMRFavoritesManager.h"
1615 #import <SGAppKit/NSImage-SGExtensions.h>
1716
18-@interface FavoritesBoardListItem (BSPrivate)
19-- (void) favoritesManagerDidChange : (id) notification;
20-- (void) setDirty : (BOOL) inDirty;
21-- (BOOL) dirty;
22-- (void) registerToNotificationCenter;
23-@end
2417
2518 @implementation FavoritesBoardListItem
2619 //APP_SINGLETON_FACTORY_METHOD_IMPLEMENTATION(sharedInstance) ;
27-+ (id) sharedInstance
20++ (id)sharedInstance
2821 {
2922 static id _sharedInstance = nil;
3023
@@ -35,29 +28,28 @@
3528 return _sharedInstance;
3629 }
3730
38-- (id) init
31+- (id)init
3932 {
4033 if (self = [super init]) {
41- [self registerToNotificationCenter];
4234 NSString *query;
4335 query = [NSString stringWithFormat:@"SELECT * FROM %@ INNER JOIN %@ USING(%@, %@)",
4436 BoardThreadInfoViewName, FavoritesTableName, BoardIDColumn, ThreadIDColumn];
45- [self setQuery : query];
37+ [self setQuery:query];
4638 }
4739
4840 return self;
4941 }
5042
51-- (id) retain { return self; }
52-- (oneway void) release {}
53-- (NSUInteger) retainCount { return NSUIntegerMax; }
43+- (id)retain { return self; }
44+- (oneway void)release {}
45+- (NSUInteger)retainCount { return NSUIntegerMax; }
5446
5547 - (BOOL)isEqual:(id)other
5648 {
5749 return (self == other);
5850 }
5951
60-- (NSImage *) icon
52+- (NSImage *)icon
6153 {
6254 return [NSImage imageAppNamed:[self iconBaseName]];
6355 }
@@ -67,78 +59,25 @@
6759 return @"FavoritesItem";
6860 }
6961
70-- (NSString *) name
62+- (NSString *)name
7163 {
7264 return CMXFavoritesDirectoryName;
7365 }
74-- (void) setName : (NSString *) newName
66+- (void)setName:(NSString *)newName
7567 {
7668 //
7769 }
7870
79-- (id <SQLiteCursor>) cursorForThreadList
80-{
81- if(!items || [self dirty]) {
82- items = [super cursorForThreadList];
83- }
84-
85- return items;
86-}
87-
88-- (void) favoritesManagerDidChange : (id) notification
89-{
90- UTILAssertNotificationObject(
91- notification,
92- [CMRFavoritesManager defaultManager]);
93- [self setDirty : YES];
94-}
95-- (void) setDirty : (BOOL) inDirty
96-{
97- if((dirty && inDirty) || (!dirty && !inDirty)) return;
98-
99- dirty = inDirty;
100-}
101-- (BOOL) dirty
102-{
103- return dirty;
104-}
105-
106-#pragma mark## Notifications ##
107-- (void) registerToNotificationCenter
108-{
109- [[NSNotificationCenter defaultCenter]
110- addObserver : self
111- selector : @selector(favoritesManagerDidChange:)
112- name : CMRFavoritesManagerDidLinkFavoritesNotification
113- object : [CMRFavoritesManager defaultManager]];
114- [[NSNotificationCenter defaultCenter]
115- addObserver : self
116- selector : @selector(favoritesManagerDidChange:)
117- name : CMRFavoritesManagerDidRemoveFavoritesNotification
118- object : [CMRFavoritesManager defaultManager]];
119-}
120-- (void) removeFromNotificationCenter
121-{
122- id nc = [NSNotificationCenter defaultCenter];
123-
124- [nc removeObserver : self
125- name : CMRFavoritesManagerDidLinkFavoritesNotification
126- object : [CMRFavoritesManager defaultManager]];
127- [nc removeObserver : self
128- name : CMRFavoritesManagerDidRemoveFavoritesNotification
129- object : [CMRFavoritesManager defaultManager]];
130-}
131-
13271 #pragma mark## CMRPropertyListCoding protocol ##
133-//+ (id) objectWithPropertyListRepresentation : (id) rep
72+//+ (id)objectWithPropertyListRepresentation:(id)rep
13473 //{
135-// return [[[self alloc] initWithPropertyListRepresentation : rep] autorelease];
74+// return [[[self alloc] initWithPropertyListRepresentation:rep] autorelease];
13675 //}
137-- (id) propertyListRepresentation
76+- (id)propertyListRepresentation
13877 {
13978 return [self name];
14079 }
141-- (id) initWithPropertyListRepresentation : (id) rep
80+- (id)initWithPropertyListRepresentation:(id)rep
14281 {
14382 [self release];
14483
--- a/application/source/browser/BSDBThreadList.m
+++ b/application/source/browser/BSDBThreadList.m
@@ -15,7 +15,8 @@
1515 #import "CMRThreadSignature.h"
1616 #import "BSThreadListUpdateTask.h"
1717 #import "BSThreadsListOPTask.h"
18-#import "BSBoardListItemHEADCheckTask.h"
18+//#import "BSBoardListItemHEADCheckTask.h"
19+#import "BSSmartBoardUpdateTask.h"
1920 #import "BoardListItem.h"
2021 #import "DatabaseManager.h"
2122 #import "BSThreadListItem.h"
@@ -937,28 +938,16 @@ static NSString *labelNameForCode(NSUInteger num)
937938 }
938939 [mTaskLock unlock];
939940
941+ Class dlTaskClass = Nil;
940942 if ([self isFavorites] || [self isSmartItem]) {
941- if (forceDL) {
942- // 更新チェックの回数上限に達している場合ここでブロックする
943- NSError *error;
944- if (![[CMRFavoritesManager defaultManager] canHEADCheck:&error]) {
945- NSAlert *alert = [NSAlert alertWithError:error];
946- [alert runModal];
947- return;
948- }
949- [mTaskLock lock];
950- mTask = [[BSBoardListItemHEADCheckTask alloc] initWithThreadList:self];
951- [self pushIfCanExcute:mTask];
952- [mTaskLock unlock];
953- } else {
954- [self updateCursor];
955- }
943+ dlTaskClass = [BSSmartBoardUpdateTask class];
956944 } else {
957- [mTaskLock lock];
958- mTask = [[BSThreadsListOPTask alloc] initWithThreadList:self forceDownload:forceDL rebuild:flag];
959- [self pushIfCanExcute:mTask];
960- [mTaskLock unlock];
945+ dlTaskClass = [BSThreadsListOPTask class];
961946 }
947+ [mTaskLock lock];
948+ mTask = [[dlTaskClass alloc] initWithThreadList:self forceDownload:forceDL rebuild:flag];
949+ [self pushIfCanExcute:mTask];
950+ [mTaskLock unlock];
962951 }
963952
964953 - (void)doLoadThreadsList:(CMRThreadLayout *)worker
--- /dev/null
+++ b/application/source/browser/BSSmartBoardUpdateTask.h
@@ -0,0 +1,29 @@
1+//
2+// BSSmartBoardUpdateTask.h
3+// BathyScaphe
4+//
5+// Created by 堀 昌樹 on 12/07/07.
6+// Copyright (c) 2012年 __MyCompanyName__. All rights reserved.
7+//
8+
9+#import "BSThreadListTask.h"
10+#import "BSDBThreadList.h"
11+#import "BoardListItem.h"
12+
13+@interface BSSmartBoardUpdateTask : BSThreadListTask
14+{
15+ BSDBThreadList *_targetList;
16+ BoardListItem *_item;
17+ BOOL forceDL;
18+
19+ id <SQLiteCursor> _targetThreads;
20+
21+ NSMutableSet *_boards;
22+ NSMutableDictionary *_updateData;
23+}
24+
25+// rebuild flag is never use.
26++ (id)taskWithThreadList:(BSDBThreadList *)list forceDownload:(BOOL)forceDL rebuild:(BOOL)flag;
27+- (id)initWithThreadList:(BSDBThreadList *)list forceDownload:(BOOL)forceDL rebuild:(BOOL)flag;
28+
29+@end
--- /dev/null
+++ b/application/source/browser/BSSmartBoardUpdateTask.m
@@ -0,0 +1,295 @@
1+//
2+// BSSmartBoardUpdateTask.m
3+// BathyScaphe
4+//
5+// Created by 堀 昌樹 on 12/07/07.
6+// Copyright (c) 2012年 __MyCompanyName__. All rights reserved.
7+//
8+
9+#import "BSSmartBoardUpdateTask.h"
10+
11+#import <CocoaOniguruma/OnigRegexp.h>
12+
13+#import "AppDefaults.h"
14+#import "CMRFavoritesManager.h"
15+#import "BoardManager.h"
16+#import "CMRHostHandler.h"
17+#import "CMXTextParser.h"
18+#import "BSDownloadTask.h"
19+#import "DatabaseManager.h"
20+
21+@interface BSSmartBoardUpdateTask ()
22+@property (assign) BSDBThreadList *targetList;
23+@property (retain) BoardListItem *item;
24+@end
25+
26+@implementation BSSmartBoardUpdateTask
27+@synthesize targetList = _targetList;
28+@synthesize item = _item;
29+
30+
31++ (id)taskWithThreadList:(BSDBThreadList *)list forceDownload:(BOOL)forceDL rebuild:(BOOL)flag
32+{
33+ return [[[[self class] alloc] initWithThreadList:list forceDownload:forceDL rebuild:flag] autorelease];
34+}
35+- (id)initWithThreadList:(BSDBThreadList *)list forceDownload:(BOOL)inForceDL rebuild:(BOOL)flag
36+{
37+ self = [super init];
38+ if(self) {
39+ forceDL = inForceDL;
40+ _boards = [[NSMutableSet alloc] init];
41+ _updateData = [[NSMutableDictionary alloc] init];
42+ self.targetList = list;
43+ self.item = [list boardListItem];
44+ if(!([self.item type] & (BoardListFavoritesItem | BoardListSmartBoardItem))) {
45+ [self autorelease];
46+ return nil;
47+ }
48+
49+ [[NSNotificationCenter defaultCenter] addObserver:self
50+ selector:@selector(downloadFail:)
51+ name:BSDownloadTaskFailDownloadNotification
52+ object:nil];
53+ }
54+ return self;
55+}
56+
57+- (void)dealloc
58+{
59+ [[NSNotificationCenter defaultCenter] removeObserver:self];
60+
61+ [_boards release];
62+ [_updateData release];
63+ [_item release];
64+ [_targetThreads release];
65+
66+ [super dealloc];
67+}
68+
69++ (OnigRegexp *)regex
70+{
71+ static OnigRegexp *sRegexp = nil;
72+ if (!sRegexp) {
73+ sRegexp = [OnigRegexp compile:[NSString stringWithFormat:@"(\\d+)[^,<>]*(?:<>|,).*\\s*(?:\\(|<>|%C)(\\d+)",0xFF08]];
74+ [sRegexp retain];
75+ }
76+ return sRegexp;
77+}
78+- (OnigRegexp *)regex
79+{
80+ return [[self class] regex];
81+}
82+
83+- (void)downloadFail:(NSNotification *)notification
84+{
85+ NSError *error = [[notification userInfo] objectForKey:BSDownloadTaskErrorObjectKey];
86+ [NSApp presentError:error];
87+}
88+
89+- (void)playFinishSoundIsUpdate:(BOOL)isUpDate
90+{
91+ NSSound *finishedSound_ = nil;
92+ NSString *soundName_ = [CMRPref HEADCheckNewArrivedSound];
93+
94+ if (isUpDate && ![soundName_ isEqualToString:@""]) {
95+ finishedSound_ = [NSSound soundNamed:soundName_];
96+ } else {
97+ soundName_ = [CMRPref HEADCheckNoUpdateSound];
98+ if (![soundName_ isEqualToString:@""]) {
99+ finishedSound_ = [NSSound soundNamed:soundName_];
100+ }
101+ }
102+ [finishedSound_ play];
103+}
104+
105+
106+
107+- (void)collectTargetBoards
108+{
109+ _targetThreads = [[self.item cursorForThreadList] retain];
110+ for(NSUInteger row = 0, rowCount = [_targetThreads rowCount]; row < rowCount; row++) {
111+ if(self.isInterrupted) return;
112+
113+ id boardName = [_targetThreads valueForColumn:BoardNameColumn atRow:row];
114+ if(boardName && ![boardName isKindOfClass:[NSNull class]]) {
115+ [_boards addObject:boardName];
116+ }
117+ }
118+
119+ fprintf(stderr, "Board number are %ld\n", [_boards count]);
120+// NSLog(@"collected board names \n%@", _boards);
121+}
122+
123+static BOOL isBoardLivedoor(NSURL *boardURL)
124+{
125+ const char *host = NULL;
126+ CMRGetHostCStringFromBoardURL(boardURL, &host);
127+ return host ? is_jbbs_livedoor(host) : NO;
128+}
129+- (void)collectUpdateInformation
130+{
131+ NSString *dlFormat = NSLocalizedString(@"Downloding subject.txt of %@", nil);
132+
133+ dispatch_queue_t downloadQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
134+ NSArray *boardNames = [_boards allObjects];
135+ dispatch_apply([boardNames count], downloadQueue, ^(size_t index) {
136+ if(self.isInterrupted) return;
137+
138+ NSString *boardName = [boardNames objectAtIndex:index];
139+
140+ self.message = [NSString stringWithFormat:dlFormat, boardName];
141+
142+ NSURL *boardURL = [[BoardManager defaultManager] URLForBoardName:boardName];
143+ if (!boardURL) {
144+ NSLog(@"Can NOT create url from bbs named %@.",boardName);
145+ return;
146+ }
147+ NSURL *subjectURL = [NSURL URLWithString:CMRAppSubjectTextFileName relativeToURL:boardURL];
148+ NSArray *subjectLines = nil;
149+ BSDownloadTask *dlTask = [[BSDownloadTask alloc] initWithURL:subjectURL];
150+ {
151+ [dlTask synchronousDownLoad];
152+ NSData *subjectData = [dlTask receivedData];
153+ if(!subjectData || [subjectData length] == 0) return;
154+
155+ CMRHostHandler *handler = [CMRHostHandler hostHandlerForURL:boardURL];
156+ if (!handler) {
157+ NSLog(@"Can NOT create host handler from url %@.",boardURL);
158+ return;
159+ }
160+ CFStringEncoding enc = [handler subjectEncoding];
161+ NSString *subjectString = [CMXTextParser stringWithData:subjectData CFEncoding:enc];
162+ subjectLines = [subjectString componentsSeparatedByNewline];
163+ }
164+ [dlTask release];
165+
166+ BOOL isLivedoor = isBoardLivedoor(boardURL);
167+ NSMutableArray *dats = [NSMutableArray array];
168+
169+ if(self.isInterrupted) return;
170+
171+ NSMutableDictionary *infos = [NSMutableDictionary dictionary];
172+ for(NSString *line in subjectLines) {
173+ if(self.isInterrupted) return;
174+
175+ OnigResult *match = [[self regex] search:line];
176+ NSString *datString = [match stringAt:1];
177+ NSString *numString = [match stringAt:2];
178+ if(!numString) continue;
179+
180+ if(isLivedoor) {
181+ if([dats containsObject:datString]) continue;
182+ [dats addObject:datString];
183+ }
184+
185+ [infos setObject:numString forKey:datString];
186+ }
187+ @synchronized(_updateData) {
188+ [_updateData setObject:infos forKey:boardName];
189+ }
190+ });
191+// if(self.isInterrupted) return;
192+// NSLog(@"Collected informations \n%@", _updateData);
193+}
194+
195+static inline BOOL isNSNullOrNil(id obj)
196+{
197+ if(!obj) return YES;
198+ if([obj isKindOfClass:[NSNull class]]) return YES;
199+ return NO;
200+}
201+static inline id nilIfObjectIsNSNull(id obj)
202+{
203+ return (obj == [NSNull null]) ? nil : obj;
204+}
205+static inline BOOL isUpdatedThread(NSInteger readCount, NSString *numString, NSInteger currentCount)
206+{
207+ return (readCount != 0 && !isNSNullOrNil(numString) && currentCount < [numString integerValue]);
208+}
209+- (void)updateDB
210+{
211+ BOOL isUpdate = NO;
212+
213+ SQLiteDB *db = [[DatabaseManager defaultManager] databaseForCurrentThread];
214+ NSString *queryString = [NSString stringWithFormat:@"UPDATE OR IGNORE %@ SET %@ = ?, %@ = ? WHERE %@ = ? AND %@ = ?",
215+ ThreadInfoTableName,
216+ NumberOfAllColumn,
217+ ThreadStatusColumn,// ThreadUpdatedStatus,
218+ BoardIDColumn, ThreadIDColumn];
219+ SQLiteReservedQuery *query = [[SQLiteReservedQuery alloc] initWithQuery:queryString usingSQLiteDB:db];
220+
221+ [db beginTransaction];
222+ for(NSUInteger index = 0, rowCount = [_targetThreads rowCount]; index < rowCount; index++) {
223+ if(self.isInterrupted) {
224+ [db rollbackTransaction];
225+ return;
226+ }
227+ id<SQLiteRow> row = [_targetThreads rowAtIndex:index];
228+
229+ NSInteger status = [nilIfObjectIsNSNull([row valueForColumn:ThreadStatusColumn]) integerValue];
230+ BOOL isNew = (status & ThreadNewCreatedStatus) == ThreadNewCreatedStatus;
231+ NSInteger readCount = [nilIfObjectIsNSNull([row valueForColumn:NumberOfReadColumn]) integerValue];
232+ if(!isNew && readCount == 0) continue;
233+ NSString *boardName = [row valueForColumn:BoardNameColumn];
234+ if(isNSNullOrNil(boardName)) continue;
235+ NSString *datString = [row valueForColumn:ThreadIDColumn];
236+ if(isNSNullOrNil(datString)) continue;
237+ NSString *boardID = [row valueForColumn:BoardIDColumn];
238+ if(isNSNullOrNil(boardID)) continue;
239+ NSInteger currentCount = [nilIfObjectIsNSNull([row valueForColumn:NumberOfAllColumn]) integerValue];
240+ NSString *numString = nil;
241+
242+ NSDictionary *infoForBoard = [_updateData objectForKey:boardName];
243+ numString = [infoForBoard objectForKey:datString];
244+ if(isUpdatedThread(readCount, numString, currentCount)) {
245+ [query cursorWithFormat:"siss", numString, ThreadUpdatedStatus, boardID, datString];
246+ isUpdate = YES;
247+ } else if(isNew) {
248+ [query cursorWithFormat:"iiss", currentCount, ThreadNoCacheStatus, boardID, datString];
249+// isUpdate = YES;
250+ }
251+
252+ }
253+ [db commitTransaction];
254+
255+ [self playFinishSoundIsUpdate:isUpdate];
256+}
257+
258+- (void)excute
259+{
260+ if(!forceDL) {
261+ if(self.isInterrupted) return;
262+ [self.targetList updateCursor];
263+ return;
264+ }
265+ // 更新チェックの回数上限に達している場合ここでブロックする
266+ NSError *error = nil;
267+ if (![[CMRFavoritesManager defaultManager] canHEADCheck:&error]) {
268+ NSAlert *alert = [NSAlert alertWithError:error];
269+ [alert runModal];
270+ return;
271+ }
272+
273+ NSLog(@"Begin update");
274+ // Boardを収集
275+ self.message = NSLocalizedString(@"Collecting Board informations.", nil);
276+ [self collectTargetBoards];
277+ if(self.isInterrupted) return;
278+
279+ // 各Boardのsubject.txtを取得
280+ self.message = NSLocalizedString(@"Download subject.txt.", nil);
281+ [self collectUpdateInformation];
282+ if(self.isInterrupted) return;
283+
284+ // 各subject.txtからDBをupdate
285+ self.message = NSLocalizedString(@"Update database.", nil);
286+ [self updateDB];
287+
288+ [[CMRFavoritesManager defaultManager] decrementHEADCheckCount];
289+
290+ if(self.isInterrupted) return;
291+ [self.targetList updateCursor];
292+ NSLog(@"End update");
293+}
294+
295+@end
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,3 +1,17 @@
1+2012-07-21 masakih <masakih@users.sourceforge.jp>
2+ * application/BathyScaphe.xcodeproj/project.pbxproj:
3+ * application/source/browser/BSSmartBoardUpdateTask.h:
4+ * application/source/browser/BSSmartBoardUpdateTask.m:
5+ [新規追加] お気に入り、スマート掲示板更新タスク。
6+ subject.txtを使用し、対象スレッドのレス数を更新する。
7+ 対象スレッドの新着フラグをすべて外す。
8+ 更新回数制限をチェック。
9+ * application/source/browser/BSDBThreadList.m:
10+ BSSmartBoardUpdateTaskを使うようにした。
11+ 更新回数制限チェックはBSSmartBoardUpdateTaskにて行うようにした。
12+ * application/source/bbs/BoardListItem/FavoritesBoardListItem.m:
13+ * application/source/bbs/BoardListItem/FavoritesBoardListItem.h:
14+ データのキャッシュを行わないようにした。
115 ================================================= 2.2(v335) / Baby universe day / svn Tag : v220_FINAL
216 2012-07-20 tsawada2 <tsawada2@users.sourceforge.jp>
317 * changelog.txt