source: trunk/SapphireFileDataImporter.m @ 194

Revision 194, 8.6 KB checked in by gbooker, 7 years ago (diff)

Compare equality on modification time instead of > just in case

Line 
1//
2//  SapphireFileDataImporter.m
3//  Sapphire
4//
5//  Created by pnmerrill on 6/24/07.
6//  Copyright 2007 __www.nanopi.net__. All rights reserved.
7//
8
9#import "SapphireFileDataImporter.h"
10#import "SapphireMetaData.h"
11#include <sys/types.h>
12#include <sys/stat.h>
13
14//Single Attributes
15#define MEDIA_TVSHOW_XML_QUERY          @"/media[@type='TV Show']/text()"
16#define MEDIA_MOVIE_XML_QUERY           @"/media[@type='Movie']/text()"
17#define SUMMARY_XML_QUERY                       @"/media/summary/text()"
18#define DESCRIPTION_XML_QUERY           @"/media/description/text()"
19#define PUBLISHER_XML_QUERY                     @"/media/publisher/text()"
20#define COPYRIGHT_XML_QUERY                     @"/media/copyright/text()"
21#define USER_RATING_XML_QUERY           @"/media/userStarRating/text()"
22#define RATING_XML_QUERY                        @"/media/rating/text()"
23#define SERIES_NAME_XML_QUERY           @"/media/seriesName/text()"
24#define BROADCASTER_XML_QUERY           @"/media/broadcaster/text()"
25#define EPISODE_NUMBER_XML_QUERY        @"/media/episodeNumber/text()"
26#define EPISODE_XML_QUERY                       @"/media/episode/text()"
27#define SEASON_XML_QUERY                        @"/media/season/text()"
28#define PUBLISHED_XML_QUERY                     @"/media/published/text()"
29//Multi Attributes             
30#define TITLE_XML_QUERY                         @"/media/title/text()"
31#define GENRES_XML_QUERY                        @"/media/genres/genre/text()"
32#define CAST_XML_QUERY                          @"/media/cast/name/text()"
33#define DIRECTORS_XML_QUERY                     @"/media/directors/name/text()"
34#define PRODUCERS_XML_QUERY                     @"/media/producers/name/text()"
35
36@implementation SapphireFileDataImporter
37
38/*Information to make the XML import easier*/
39static NSDictionary *xmlSingleAttributes = nil;
40static NSDictionary *xmlMultiAttributes = nil;
41
42+(void) initialize
43{
44        xmlSingleAttributes = [[NSDictionary alloc] initWithObjectsAndKeys:
45                META_TITLE_KEY,                                 TITLE_XML_QUERY,
46                META_SUMMARY_KEY,                               SUMMARY_XML_QUERY,
47                META_DESCRIPTION_KEY,                   DESCRIPTION_XML_QUERY,
48                @"Publisher",                                   PUBLISHER_XML_QUERY,
49                META_COPYRIGHT_KEY,                             COPYRIGHT_XML_QUERY,
50                META_SHOW_FAVORITE_RATING_KEY,  USER_RATING_XML_QUERY,
51                META_SHOW_RATING_KEY,                   RATING_XML_QUERY,
52                META_SHOW_NAME_KEY,                             SERIES_NAME_XML_QUERY,
53                META_SHOW_BROADCASTER_KEY,              BROADCASTER_XML_QUERY,
54                META_ABSOLUTE_EP_NUMBER_KEY,    EPISODE_NUMBER_XML_QUERY,
55                META_EPISODE_NUMBER_KEY,                EPISODE_XML_QUERY,
56                META_SEASON_NUMBER_KEY,                 SEASON_XML_QUERY,
57                META_SHOW_PUBLISHED_DATE_KEY,   PUBLISHED_XML_QUERY,nil] ;
58        xmlMultiAttributes = [[NSDictionary alloc] initWithObjectsAndKeys:
59                @"Genres",                              GENRES_XML_QUERY,
60                @"Cast",                                CAST_XML_QUERY,
61                @"Producers" ,                  PRODUCERS_XML_QUERY,
62                @"Directors",                   DIRECTORS_XML_QUERY,nil];
63}
64
65- (id)init
66{
67        self = [super init];
68        if(self == nil)
69                return nil;
70       
71        xmlFileCount=0;
72       
73        return self;
74}
75
76/*!
77* @brief Sets the importer's data menu
78 *
79 * @param theDataMenu The importer's menu
80 */
81- (void)setImporterDataMenu:(SapphireImporterDataMenu *)theDataMenu
82{
83}
84
85/*!
86 * @brief Import a single File
87 *
88 * @param metaData The file to import
89 * @return YES if imported, NO otherwise
90 */
91- (BOOL) importMetaData:(SapphireFileMetaData *)metaData
92{
93        /*Initialization*/
94        BOOL ret = NO;
95        NSFileManager *fm = [NSFileManager defaultManager];
96        /*Get the file*/
97        /*Check for XML file*/
98        NSString * xmlFilePath=[metaData path] ;
99        xmlPathIsDir = NO;
100        xmlFilePath=[[xmlFilePath stringByDeletingPathExtension] stringByAppendingPathExtension:@"xml"];
101        if([fm fileExistsAtPath:xmlFilePath isDirectory:&xmlPathIsDir] && !xmlPathIsDir)
102        {
103                /*Check modification date on XML file*/
104                struct stat sb;
105                memset(&sb, 0, sizeof(struct stat));
106                stat([xmlFilePath fileSystemRepresentation], &sb);
107                long modTime = sb.st_mtimespec.tv_sec;
108                long oldTime = [metaData importedTimeFromSource:META_XML_IMPORT_KEY];
109                if(oldTime != modTime)
110                {
111                        /*Import the XML file and update counts*/
112                        [self importXMLFile:xmlFilePath forMeta:metaData] ;
113                        xmlFileCount++ ;
114                        ret = YES;
115                }
116        }
117        /*Import file if necessary*/
118        if ([metaData updateMetaData])
119                ret = YES;
120        /*Return whether we imported or not*/
121        return ret;
122}
123
124/*!
125 * @brief The completion text to display
126 *
127 * @return The completion text to display
128 */
129- (NSString *)completionText
130{
131        return BRLocalizedString(@"Sapphire will continue to import new files as it encounters them.  You may initiate this import again at any time, and any new or changed files will be imported", @"End text after import of files is complete");
132}
133
134/*!
135 * @brief Import and XML file into meta data
136 *
137 * @param xmlFileName The path of the xml file
138 * @param fileMeta The file's meta data
139 */
140- (void)importXMLFile:(NSString *)xmlFileName forMeta: (SapphireFileMetaData *) fileMeta
141{
142        /*Read the XML document*/
143        NSURL *url = [NSURL fileURLWithPath:xmlFileName];
144        NSError *error = nil;
145        NSMutableDictionary * metaData=[NSMutableDictionary dictionary];
146        NSXMLDocument *document = [[NSXMLDocument alloc] initWithContentsOfURL:url options:NSXMLDocumentTidyXML error:&error];
147        NSXMLElement *root = [document rootElement];
148        if(!root)
149                return;
150/*
151        NSString *type = [[root attributeForName:@"type"] stringValue];
152        //Need to catch the media type {"TV Show" , "Movie"}
153        if(type!=nil)metaData
154*/
155        /*Import single attribute items*/
156        NSEnumerator *keyEnum = [xmlSingleAttributes keyEnumerator];
157        NSString *key = nil;
158       
159        while((key = [keyEnum nextObject]) != nil)
160        {
161                /*Search for the attribute*/
162                NSArray *objects = [root objectsForXQuery:key error:&error];
163                if([objects count])
164                {
165                        /*Import the attribute*/
166                        [metaData setObject:[[objects objectAtIndex:0] stringValue] forKey:[xmlSingleAttributes objectForKey:key]] ;
167                }
168    }
169        /*Search for multi attribute items*/
170        keyEnum = [xmlMultiAttributes keyEnumerator];
171        while((key = [keyEnum nextObject]) != nil)
172        {
173                /*Search for the attribute*/
174                NSArray *objects = [root objectsForXQuery:key error:&error];
175                int count = [objects count];
176                NSMutableArray *newData= nil;
177                if(!count)
178                        continue;
179                /*Itterate through the attribute's values*/
180                newData = [NSMutableArray arrayWithCapacity:count];
181                NSEnumerator *objectsEnum = [objects objectEnumerator];
182                NSXMLNode *node = nil;
183                while((node = [objectsEnum nextObject]) != nil)
184                {
185                        /*Add each value*/
186                        [newData addObject:[node stringValue]];
187                }
188                /*Import the attribute*/
189                [metaData setObject:newData forKey:[xmlMultiAttributes objectForKey:key]] ;
190        }
191        /*Special cases*/
192        /*The air date*/
193        NSString *value = [metaData objectForKey:META_SHOW_AIR_DATE];
194        if(value != nil)
195        {
196                /*Change date string to a number*/
197                [metaData removeObjectForKey:META_SHOW_AIR_DATE];
198                NSDate *newValue = [NSDate dateWithNaturalLanguageString:value];
199                if([newValue timeIntervalSince1970])
200                        [metaData setObject:newValue forKey:META_SHOW_AIR_DATE];
201        }
202        /*The aquired date*/
203        value = [metaData objectForKey:META_SHOW_AQUIRED_DATE];
204        if(value != nil)
205        {
206                /*Change date sttring to a number*/
207                [metaData removeObjectForKey:META_SHOW_AQUIRED_DATE];
208                NSDate *newValue = [NSDate dateWithNaturalLanguageString:value];
209                if([newValue timeIntervalSince1970])
210                        [metaData setObject:newValue forKey:META_SHOW_AQUIRED_DATE];
211        }
212        /*Values which need to be converted to numbers*/
213        NSArray *convertToNumbers = [NSArray arrayWithObjects:META_SHOW_FAVORITE_RATING_KEY, META_ABSOLUTE_EP_NUMBER_KEY, META_SEASON_NUMBER_KEY, META_EPISODE_NUMBER_KEY, nil];
214        NSEnumerator *numEnum = [convertToNumbers objectEnumerator];
215        while((key = [numEnum nextObject]) != nil)
216        {
217                /*Check for presence of value*/
218                NSString *value = [metaData objectForKey:key];
219                if(value != nil)
220                {
221                        /*Convert to a number, either a double or int, depending on value*/
222                        double newValue = [value doubleValue];
223                        NSNumber *newNum = [NSNumber numberWithInt:[value intValue]];
224                        if(newValue != round(newValue))
225                                newNum = [NSNumber numberWithDouble:newValue];
226                        [metaData setObject:newNum forKey:key];
227                }
228        }
229        /*Update modification date*/
230        struct stat sb;
231        memset(&sb, 0, sizeof(struct stat));
232        stat([xmlFileName fileSystemRepresentation], &sb);
233        long modTime = sb.st_mtimespec.tv_sec;
234        /*Import into meta data*/
235        [fileMeta importInfo: metaData fromSource:META_XML_IMPORT_KEY withTime:modTime];
236}
237
238/*!
239 * @brief The initial text to display
240 *
241 * @return The initial text to display
242 */
243- (NSString *)initialText
244{
245        return BRLocalizedString(@"Populate File Data", @"Title");
246}
247
248/*!
249 * @brief The informative text to display
250 *
251 * @return The informative text to display
252 */
253- (NSString *)informativeText
254{
255        return BRLocalizedString(@"This tool will populate Sapphire's File data.  This proceedure may take a while, but you may cancel at any time.", @"Description of the import processes");
256}
257
258/*!
259 * @brief The button title
260 *
261 * @return The button title
262 */
263- (NSString *)buttonTitle
264{
265        return BRLocalizedString(@"Start Populating Data", @"Button");
266}
267
268/*!
269* @brief The data menu was exhumed
270 *
271 * @param controller The Controller which was on top
272 */
273- (void) wasExhumedByPoppingController: (BRLayerController *) controller
274{
275}
276@end
Note: See TracBrowser for help on using the repository browser.