engine/src/FeedParser.cpp
branch3rded
changeset 343 9c56bf585696
parent 277 03ad04f315db
child 390 d7abecc9d189
equal deleted inserted replaced
281:1cae65a87b5e 343:9c56bf585696
    22 #include <s32file.h>
    22 #include <s32file.h>
    23 #include <charconv.h>
    23 #include <charconv.h>
    24 #include <xml/stringdictionarycollection.h>
    24 #include <xml/stringdictionarycollection.h>
    25 #include <utf.h>
    25 #include <utf.h>
    26 #include <tinternetdate.h>
    26 #include <tinternetdate.h>
       
    27 #include <e32hashtab.h>
    27 #include "debug.h"
    28 #include "debug.h"
    28 #include "podcastutils.h"
    29 #include "podcastutils.h"
    29 
    30 
    30 using namespace Xml;
    31 using namespace Xml;
    31 const TInt KMaxParseBuffer = 1024;
    32 const TInt KMaxParseBuffer = 1024;
    52 	iItemsParsed = 0;
    53 	iItemsParsed = 0;
    53 	iMaxItems = aMaxItems;
    54 	iMaxItems = aMaxItems;
    54 	iStoppedParsing = EFalse;
    55 	iStoppedParsing = EFalse;
    55 	iEncoding = ELatin1;
    56 	iEncoding = ELatin1;
    56 
    57 
       
    58 	TEntry entry;
       
    59 	User::LeaveIfError(iRfs.Entry(feedFileName, entry));
       
    60 	iFileSize = entry.iSize;
       
    61 	
    57 	ParseL(*parser, iRfs, feedFileName);
    62 	ParseL(*parser, iRfs, feedFileName);
    58 
    63 
    59 	CleanupStack::PopAndDestroy(parser);	
    64 	CleanupStack::PopAndDestroy(parser);	
    60 	
    65 	
    61 	//DP("ParseFeedL END");
    66 	//DP("ParseFeedL END");
   157 		} else {
   162 		} else {
   158 			iFeedState=EStateChannelImage;
   163 			iFeedState=EStateChannelImage;
   159 		}
   164 		}
   160 		break;
   165 		break;
   161 	case EStateItem:
   166 	case EStateItem:
       
   167 		iUid = 0;
   162 		// <channel> <item> <title>
   168 		// <channel> <item> <title>
   163 		if (str.CompareF(KTagTitle) == 0) {
   169 		if (str.CompareF(KTagTitle) == 0) {
   164 			iFeedState=EStateItemTitle;
   170 			iFeedState=EStateItemTitle;
   165 		// <channel> <item> <link>
   171 		// <channel> <item> <link>
   166 		} else if (str.CompareF(KTagLink) == 0) {
   172 		} else if (str.CompareF(KTagLink) == 0) {
   195 			iFeedState=EStateItemDescription;
   201 			iFeedState=EStateItemDescription;
   196 		// <channel> <item> <pubdate>
   202 		// <channel> <item> <pubdate>
   197 		} else if (str.CompareF(KTagPubDate) == 0) {
   203 		} else if (str.CompareF(KTagPubDate) == 0) {
   198 			//DP("LastBuildDate BEGIN");
   204 			//DP("LastBuildDate BEGIN");
   199 			iFeedState = EStateItemPubDate;
   205 			iFeedState = EStateItemPubDate;
       
   206 		// <channel> <item> <guid>
       
   207 		} else if (str.CompareF(KTagGuid) == 0) {
       
   208 			iFeedState = EStateItemGuid;
   200 		}
   209 		}
   201 		break;
   210 		break;
   202 	default:
   211 	default:
   203 		//DP2("Ignoring tag %S when in state %d", &str, iFeedState);
   212 		//DP2("Ignoring tag %S when in state %d", &str, iFeedState);
   204 		break;
   213 		break;
   243 			//DP("LastBuildDate END");
   252 			//DP("LastBuildDate END");
   244 			TInternetDate internetDate;
   253 			TInternetDate internetDate;
   245 			TBuf8<128> temp;
   254 			TBuf8<128> temp;
   246 			temp.Copy(iBuffer);
   255 			temp.Copy(iBuffer);
   247 					
   256 					
       
   257 			DP2("iFileSize=%d, iActiveFeed->FeedFileSize()=%d", iFileSize, iActiveFeed->FeedFileSize());
       
   258 					
   248 			TRAPD(parseError, internetDate.SetDateL(temp));
   259 			TRAPD(parseError, internetDate.SetDateL(temp));
   249 			if(parseError == KErrNone) {				
   260 			if(parseError == KErrNone) {				
   250 				if (TTime(internetDate.DateTime()) > iActiveFeed->BuildDate()) {
   261 				if (TTime(internetDate.DateTime()) > iActiveFeed->BuildDate()) {
   251 					DP("Successfully parsed build date");
   262 					DP("Successfully parsed build date");
   252 					iActiveFeed->SetBuildDate(TTime(internetDate.DateTime()));
   263 					iActiveFeed->SetBuildDate(TTime(internetDate.DateTime()));
   253 				} else {
   264 				} else if (iFileSize == iActiveFeed->FeedFileSize()){
   254 					DP("*** Nothing new, aborting parsing");
   265 					DP("*** Nothing new, aborting parsing");
   255 					iStoppedParsing = ETrue;
   266 					iStoppedParsing = ETrue;
   256 				}
   267 				}
   257 			} else {
   268 			} else {
   258 				DP("Failed to parse last build date");
   269 				DP("Failed to parse last build date");
   259 			}
   270 			}
       
   271 			iActiveFeed->SetFeedFileSize(iFileSize);
   260 			iFeedState = EStateChannel;
   272 			iFeedState = EStateChannel;
   261 			}
   273 			}
   262 			break;
   274 			break;
   263 		case EStateChannelImageUrl:
   275 		case EStateChannelImageUrl:
   264 			//DP1("Image url: %S", &iBuffer);
   276 			//DP1("Image url: %S", &iBuffer);
   271 			}
   283 			}
   272 			break;
   284 			break;
   273 		case EStateItem:
   285 		case EStateItem:
   274 			if (str.CompareF(KTagItem) == 0) 
   286 			if (str.CompareF(KTagItem) == 0) 
   275 				{
   287 				{
   276 				
       
   277 				// check if we have a valid pubdate
   288 				// check if we have a valid pubdate
   278 				
       
   279 				if (iActiveShow->PubDate().Int64() == 0)
   289 				if (iActiveShow->PubDate().Int64() == 0)
   280 					{
   290 					{
   281 					// set pubDate to present time
   291 					// set pubDate to present time
   282 					TTime now;
   292 					TTime now;
   283 					now.UniversalTime();
   293 					now.UniversalTime();
   290 					now -= delta;
   300 					now -= delta;
   291 					
   301 					
   292 					iActiveShow->SetPubDate(now);
   302 					iActiveShow->SetPubDate(now);
   293 					}
   303 					}
   294 				
   304 				
       
   305 				if (iUid)
       
   306 					{
       
   307 					iActiveShow->SetUid(iUid);
       
   308 					}
   295 						
   309 						
   296 				iCallbacks.NewShowL(*iActiveShow);
   310 				iCallbacks.NewShowL(*iActiveShow);
   297 				
   311 				
   298 				delete iActiveShow;				
   312 				delete iActiveShow;				
   299 				
   313 				
   300 				// We should now be finished with the show.
   314 				// We should now be finished with the show.
   301 				iActiveShow = NULL;
   315 				iActiveShow = NULL;
   302 				
   316 				
   303 				iItemsParsed++;
   317 				iItemsParsed++;
   304 				DP2("iItemsParsed: %d, iMaxItems: %d", iItemsParsed, iMaxItems);
   318 				DP2("iItemsParsed: %d, iMaxItems: %d", iItemsParsed, iMaxItems);
   305 //				if (iItemsParsed >= iMaxItems) 
   319 				if (iItemsParsed >= iMaxItems) 
   306 //					{
   320 					{
   307 //					iStoppedParsing = ETrue;
   321 					iStoppedParsing = ETrue;
   308 //					DP("*** Too many items, aborting parsing");
   322 					DP("*** Too many items, aborting parsing");
   309 //					}
   323 					}
   310 				
   324 				
   311 				iFeedState=EStateChannel;
   325 				iFeedState=EStateChannel;
   312 				}
   326 				}
   313 			break;
   327 			break;
   314 		case EStateItemPubDate:
   328 		case EStateItemPubDate:
   315 			DP1("PubDate END: iBuffer='%S'", &iBuffer);
   329 			DP1("PubDate END: iBuffer='%S'", &iBuffer);
   316 			if (str.CompareF(KTagPubDate) == 0) {
   330 			if (str.CompareF(KTagPubDate) == 0) {
   317 				// hack for feeds that don't always write day as two digits
   331 				DP1("iBuffer.Length()=%d", iBuffer.Length());
   318 				TChar five(iBuffer[5]);
   332 				
   319 				TChar six(iBuffer[6]);
   333 				if (iBuffer.Length() > 6)
   320 				
   334 					{
   321 				if (five.IsDigit() && !six.IsDigit()) {
   335 					// hack for feeds that don't always write day as two digits
   322 					TBuf<KMaxStringBuffer> fix;
   336 					TChar five(iBuffer[5]);
   323 					fix.Copy(iBuffer.Left(4));
   337 					TChar six(iBuffer[6]);
   324 					fix.Append(_L(" 0"));
   338 					
   325 					fix.Append(iBuffer.Mid(5));
   339 					if (five.IsDigit() && !six.IsDigit()) {
   326 					iBuffer.Copy(fix);
   340 						TBuf<KMaxStringBuffer> fix;
   327 				}
   341 						fix.Copy(iBuffer.Left(4));
   328 				// end hack
   342 						fix.Append(_L(" 0"));
   329 				
   343 						fix.Append(iBuffer.Mid(5));
   330 				// hack for feeds that write out months in full
   344 						iBuffer.Copy(fix);
   331 				
   345 					}
   332 				if (iBuffer[11] != ' ') {
   346 					// end hack
   333 					TPtrC midPtr = iBuffer.Mid(8);
   347 					}
   334 					
   348 				
   335 					int spacePos = midPtr.Find(_L(" "));
   349 				if (iBuffer.Length() > 11)
   336 					
   350 					{
   337 					if (spacePos != KErrNotFound) {
   351 					// hack for feeds that write out months in full
   338 						//DP1("Month: %S", &midPtr.Left(spacePos));
   352 					
       
   353 					if (iBuffer[11] != ' ') {
       
   354 						TPtrC midPtr = iBuffer.Mid(8);
   339 						
   355 						
   340 						TBuf16<KBufferLength> newBuffer;
   356 						int spacePos = midPtr.Find(_L(" "));
   341 						newBuffer.Copy(iBuffer.Left(11));
   357 						
   342 						newBuffer.Append(_L(" "));
   358 						if (spacePos != KErrNotFound) {
   343 						newBuffer.Append(iBuffer.Mid(11+spacePos));
   359 							//DP1("Month: %S", &midPtr.Left(spacePos));
   344 						//DP1("newBuffer: %S", &newBuffer);
   360 							
   345 						iBuffer.Copy(newBuffer);
   361 							TBuf16<KBufferLength> newBuffer;
   346 					}
   362 							newBuffer.Copy(iBuffer.Left(11));
   347 				}
   363 							newBuffer.Append(_L(" "));
   348 				
   364 							newBuffer.Append(iBuffer.Mid(11+spacePos));
   349 				// hack for feeds that write days and months as UPPERCASE
   365 							//DP1("newBuffer: %S", &newBuffer);
   350 				TChar one(iBuffer[1]);
   366 							iBuffer.Copy(newBuffer);
   351 				TChar two(iBuffer[2]);
   367 						}
   352 				TChar nine(iBuffer[9]);
   368 					}
   353 				TChar ten(iBuffer[10]);
   369 					
   354 
   370 					// hack for feeds that write days and months as UPPERCASE
   355 				one.LowerCase();
   371 					TChar one(iBuffer[1]);
   356 				two.LowerCase();
   372 					TChar two(iBuffer[2]);
   357 				nine.LowerCase();
   373 					TChar nine(iBuffer[9]);
   358 				ten.LowerCase();
   374 					TChar ten(iBuffer[10]);
   359 				
   375 	
   360 				iBuffer[1] = one;
   376 					one.LowerCase();
   361 				iBuffer[2] = two;
   377 					two.LowerCase();
   362 				iBuffer[9] = nine;
   378 					nine.LowerCase();
   363 				iBuffer[10] = ten;
   379 					ten.LowerCase();
   364 				
   380 					
       
   381 					iBuffer[1] = one;
       
   382 					iBuffer[2] = two;
       
   383 					iBuffer[9] = nine;
       
   384 					iBuffer[10] = ten;
       
   385 					}
       
   386 
   365 				TBuf8<128> temp;
   387 				TBuf8<128> temp;
   366 				temp.Copy(iBuffer);
   388 				temp.Copy(iBuffer);
   367 
       
   368 				TInternetDate internetDate;
   389 				TInternetDate internetDate;
   369 				TRAPD(parseError, internetDate.SetDateL(temp));
   390 				TRAPD(parseError, internetDate.SetDateL(temp));
   370 				if(parseError == KErrNone) {				
   391 				if(parseError == KErrNone) {				
   371 					//DP1("PubDate parse success: '%S'", &iBuffer);
   392 					//DP1("PubDate parse success: '%S'", &iBuffer);
   372 					iActiveShow->SetPubDate(TTime(internetDate.DateTime()));
   393 					iActiveShow->SetPubDate(TTime(internetDate.DateTime()));
   384 					DP2("Pubdate parse error: '%S', error=%d", &iBuffer, parseError);
   405 					DP2("Pubdate parse error: '%S', error=%d", &iBuffer, parseError);
   385 				}
   406 				}
   386 			}
   407 			}
   387 			iFeedState=EStateItem;
   408 			iFeedState=EStateItem;
   388 			break;
   409 			break;
       
   410 		case EStateItemGuid:
       
   411 			iUid = DefaultHash::Des16(iBuffer);
       
   412 			iFeedState=EStateItem;
       
   413 			break;
   389 		case EStateItemTitle:
   414 		case EStateItemTitle:
   390 			//DP1("title: %S", &iBuffer);
   415 			//DP1("title: %S", &iBuffer);
   391 			iActiveShow->SetTitleL(iBuffer);
   416 			iActiveShow->SetTitleL(iBuffer);
   392 			iFeedState = EStateItem;
   417 			iFeedState = EStateItem;
   393 			break;
   418 			break;