///////////////////////////////////////////////////////////////////// // // MODULE: PROGSCHD.CPP // // PURPOSE: Provides the implementation of the // CEpisodeTimeSlotRecordProcessor class // These methods parse and collection program and schedule // data that is then stored into the GuideStore using the // gsPrograms and gsScheduleEntries methods. // ///////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "errcodes.h" #include #include #include #include #include #include #include "guidestore.h" #include "services.h" #include "channels.h" #include "programs.h" #include "schedules.h" #include "tmsparse.h" #include "servchan.h" #include "progschd.h" #include "wtmsload.h" #define TIMING 0 #include "..\..\timing.h" #ifdef _DUMP_LOADER CString csDiagMil; extern HANDLE hDiagFile; extern char szDiagBuff[1024]; int ChannelCnt = 0; int TimeSlotCnt = 0; extern DWORD dwBytesWritten; #endif SRatingsID srMPAARatingIDMap[EPGMPAARatings_Fields] = { {_T("NA"), 0}, {_T("G"), 2}, {_T("PG"), 4}, {_T("PG13"), 6}, {_T("R"), 8}, {_T("NC17"), 10}, {_T("X"), 12}, {_T("NR"), 14} }; SRatingsID srTVRatingIDMap[EPGTVRatings_Fields] = { {_T("TVY"), 0}, {_T("TVY7"), 1}, {_T("TVY7FV"), 2}, {_T("TVG"), 3}, {_T("TVPG"), 4}, {_T("TV14"), 5}, {_T("TVMA"), 6} }; SDataFileFields ssfEpisodeTimeSlotFieldInfo[EpisodeTimeSlotRec_Fields] = { TRUE, 120, TRUE, 1, TRUE, 25, TRUE, 255, TRUE, 30, TRUE, 30, TRUE, 30, TRUE, 30, TRUE, 30, TRUE, 30, TRUE, 10, TRUE, 10, TRUE, 8, TRUE, 4, TRUE, 4, TRUE, 1, TRUE, 1, TRUE, 1, TRUE, 1, TRUE, 4, TRUE, 12 }; // CEpisodeTimeSlotRecordProcessor // CEpisodeTimeSlotRecordProcessor::CEpisodeTimeSlotRecordProcessor(int nNumFields, SDataFileFields ssfFieldsInfo[]) { TCHAR ConvBuffer[20] = {0}; m_Init(); m_pFieldsDesc = ssfFieldsInfo; m_nNumFields = nNumFields; m_cmRecordMap.InitHashTable(m_nNumFields, TRUE); int iRatingsCount = 0; for (iRatingsCount=0; iRatingsCount 0 && (lpData[nParsePos-1] != EOC)) if (nFieldSize > 0) { // TODO ASSERT(nFields <= StationRec_Fields); m_szValidField[nFieldSize] = '\0'; m_cmRecordMap[nFields] = m_szValidField; nFieldSize = 0; m_nCurrFieldSize = 0; } else { //nFieldDataPos = nParsePos; nFieldSize = 0; m_nCurrFieldSize = 0; } nFields++; m_nCurrField++; } else if (lpData[nParsePos] == EOR) { // End of the record // #ifdef _DUMP_LOADER TimeSlotCnt++; wsprintf(szDiagBuff, _T("\r\nRec No#%d:\n"), TimeSlotCnt); ::WriteFile(hDiagFile, szDiagBuff, lstrlen(szDiagBuff), &dwBytesWritten, 0); for (int nCnt=0; nCntm_scrpStatChans; long lEpisodeID=0, lServiceID=0, lLength=0; CString csGenre; CString csTVRating; LONG lTVRatingID = -1; LONG lMPAARatingID = -1; IProgramPtr pTMSProgram = NULL; IServicePtr pTMSService = NULL; // Lookup the program Title // cmRecord.Lookup(EpisodeTimeSlotRec_Title, csTitle); csTitle = csTitle.Left(ssfEpisodeTimeSlotFieldInfo[EpisodeTimeSlotRec_Title].nWidth); csTitle.TrimLeft(); csTitle.TrimRight(); // Lookup the program unique Identifier // cmRecord.Lookup(EpisodeTimeSlotRec_ProgramID, csProgramID); csDescription = csDescription.Left(ssfEpisodeTimeSlotFieldInfo[EpisodeTimeSlotRec_ProgramID].nWidth); csDescription.TrimLeft(); csDescription.TrimRight(); // Lookup the program Description // cmRecord.Lookup(EpisodeTimeSlotRec_Description, csDescription); csDescription = csDescription.Left(ssfEpisodeTimeSlotFieldInfo[EpisodeTimeSlotRec_Description].nWidth); csDescription.TrimLeft(); csDescription.TrimRight(); // Lookup the program Rating Data: Rated? // cmRecord.Lookup(EpisodeTimeSlotRec_Rated, csRated); csRated.TrimLeft(); csRated.TrimRight(); // Lookup the program Rating Data: MPAA Rating // cmRecord.Lookup(EpisodeTimeSlotRec_MPAARating, csMPAARating); csMPAARating.TrimLeft(); csMPAARating.TrimRight(); // Lookup the program Rating Data: TV Rating // cmRecord.Lookup(EpisodeTimeSlotRec_TVRating, csTVRating); csTVRating.TrimLeft(); csTVRating.TrimRight(); BOOL bRated = _ttoi(csRated); if (bRated) { // If this Program has an MPAA rating, it is a movie // if (!csMPAARating.IsEmpty()) { CString csRatingID; // Lookup the Rating ID - metaproperty value // m_MPAARatingsMap.Lookup(csMPAARating, csRatingID); if (!csRatingID.IsEmpty()) { lMPAARatingID = _ttol(csRatingID); } } } if (!csTVRating.IsEmpty()) { CString csRatingID; // Lookup the Rating ID - metaproperty value // m_TVRatingsMap.Lookup(csTVRating, csRatingID); if (!csRatingID.IsEmpty()) { lTVRatingID = _ttol(csRatingID); } } // For the moment we're using a dummy copyright date // DATE dtCopyrightDate = 0; // Find a Match for this program in the Programs Collection // pTMSProgram = ctmsLoapApp->m_pgsPrograms.FindProgramMatch( csTitle.GetBuffer(ssfEpisodeTimeSlotFieldInfo[EpisodeTimeSlotRec_Title].nWidth), csProgramID.GetBuffer(ssfEpisodeTimeSlotFieldInfo[EpisodeTimeSlotRec_ProgramID].nWidth)); if (NULL == pTMSProgram) { // There is no matching program in the collection - add it // pTMSProgram = ctmsLoapApp->m_pgsPrograms.AddProgram( csTitle.GetBuffer(ssfEpisodeTimeSlotFieldInfo[EpisodeTimeSlotRec_Title].nWidth), csDescription.GetBuffer(ssfEpisodeTimeSlotFieldInfo[EpisodeTimeSlotRec_Description].nWidth), csProgramID.GetBuffer(ssfEpisodeTimeSlotFieldInfo[EpisodeTimeSlotRec_ProgramID].nWidth), dtCopyrightDate, lTVRatingID, lMPAARatingID); if (NULL != pTMSProgram) { IMetaPropertiesPtr pProgramProps = pTMSProgram->GetMetaProperties(); if (NULL != pProgramProps) { // Set the Program Categorization metaproperties // for (int iGenreCount = EpisodeTimeSlotRec_Genre1Desc; iGenreCount < EpisodeTimeSlotRec_Genre6Desc; iGenreCount++) { CString csGenre; cmRecord.Lookup(iGenreCount, csGenre); if (!csGenre.IsEmpty()) { // There is a valid Category to be set for this Program // Set the Program Categorization metaproperties // ctmsLoapApp->m_pgsPrograms.AddProgramCategory(pProgramProps, csGenre.GetBuffer(ssfEpisodeTimeSlotFieldInfo[iGenreCount].nWidth+1)); } else break; } } } else return ERROR_UPDATE_ADD; } // Lookup the associated Channel Number // CString csTimeSlotChannelNumStr; cmRecord.Lookup(EpisodeTimeSlotRec_Channel, csTimeSlotChannelNumStr); // Lookup the associated Station Number // CString csTimeSlotStationNumStr; cmRecord.Lookup(EpisodeTimeSlotRec_StationNum, csTimeSlotStationNumStr); CString csStatChan = csTimeSlotStationNumStr + _T(",") + csTimeSlotChannelNumStr; // Get the corresponding Service ID // lServiceID = pStatChan->m_GetChannelID(csStatChan); // Lookup the rerun field // cmRecord.Lookup(EpisodeTimeSlotRec_Rerun, csRerun); LONG lRerun = _ttol(csRerun); #ifdef _DUMP_LOADER wsprintf(szDiagBuff, _T("Fetching #%d Channel ID for %s : %d\r\n"), TimeSlotCnt, csStatChan, lChannelID); if (NULL != hDiagFile) { ::WriteFile(hDiagFile, szDiagBuff, lstrlen(szDiagBuff), &dwBytesWritten, 0); } #endif // Lookup the Close Captioned field // cmRecord.Lookup(EpisodeTimeSlotRec_ClosedCaption, csClosed_captioned); LONG lClosed_captioned = _ttol(csClosed_captioned); // Lookup the Stereo field // cmRecord.Lookup(EpisodeTimeSlotRec_Stereo, csStereo); LONG lStereo = _ttol(csStereo); // Lookup the Pay per view field // cmRecord.Lookup(EpisodeTimeSlotRec_PayPerView, csPayPerView); LONG lPayPerView = _ttol(csPayPerView); CString csStartYYYYMMDD, csStartHHMM; IScheduleEntryPtr pScheduleEntry = NULL; // Lookup the Schedule Entry Date // cmRecord.Lookup(EpisodeTimeSlotRec_StartYYYYMMDD, csStartYYYYMMDD); // Lookup the Schedule Entry Time // cmRecord.Lookup(EpisodeTimeSlotRec_StartHHMM, csStartHHMM); int nmin = _ttoi(csStartHHMM.Right(2)); int nhour = _ttoi(csStartHHMM.Left(2)); int nmday = _ttoi(csStartYYYYMMDD.Right(2)); int nwday = 0; int nyday = 0; int nmon = _ttoi(csStartYYYYMMDD.Mid(4,2)); int nyear = _ttoi(csStartYYYYMMDD.Left(4)); cmRecord.Lookup(EpisodeTimeSlotRec_Length, csLength); lLength = _ttol(csLength.Left(2))*60 + _ttol(csLength.Right(2)); COleDateTime codtStart(nyear, nmon, nmday, nhour, nmin, 0); COleDateTime codtEnd = codtStart + COleDateTimeSpan(0, 0, lLength, 0); // This recalulation is necessary to eliminate the unseen fractional // second that messes up datetime comparisons. We only have to do // it for this one because this is calculated with the DateTimeSpan. codtEnd.SetDateTime(codtEnd.GetYear(), codtEnd.GetMonth(), codtEnd.GetDay(), codtEnd.GetHour(), codtEnd.GetMinute(), 0); pTMSService = ctmsLoapApp->m_pgsServices.GetService(lServiceID); if ( NULL != pTMSService && NULL != pTMSProgram) { // Add the new schdule entry // pScheduleEntry = ctmsLoapApp->m_pgsScheduleEntries.AddScheduleEntry(codtStart, codtEnd, COleDateTime::GetCurrentTime() + ctmsLoapApp->m_odtsTimeZoneAdjust, lRerun, lClosed_captioned, lStereo, lPayPerView, pTMSService, pTMSProgram); } if (NULL != pScheduleEntry) { #ifdef _DUMP_LOADER wsprintf(szDiagBuff, _T("Failure: Updating #%d TimeSlot ID Title: %s : %d\r\n"), TimeSlotCnt, csTitle); if (NULL != hDiagFile) { ::WriteFile(hDiagFile, szDiagBuff, lstrlen(szDiagBuff), &dwBytesWritten, 0); } #endif // Update the Guide Start time // if (COleDateTime::invalid == ctmsLoapApp->m_codtGuideStartTime.GetStatus() || codtStart < ctmsLoapApp->m_codtGuideStartTime) ctmsLoapApp->m_codtGuideStartTime = codtStart; // Update the Guide End time // if (COleDateTime::invalid == ctmsLoapApp->m_codtGuideEndTime.GetStatus() || codtEnd > ctmsLoapApp->m_codtGuideEndTime) ctmsLoapApp->m_codtGuideEndTime = codtEnd; iRet = UPDATE_SUCCEEDED; } return iRet; } int CEpisodeTimeSlotRecordProcessor::m_GetState() { return m_nState; } int CEpisodeTimeSlotRecordProcessor::m_GetError() { return m_nError; } int CEpisodeTimeSlotRecordProcessor::m_GetErrorString(CString& csErrStr) { if (m_nError) { // If there is an error to return // return csErrStr.LoadString(m_nError); } return FALSE; }