9
9
10
10
#include " utilities/FileUtils.h"
11
11
#include " utilities/Logger.h"
12
+ #include " utilities/StringComparer.h"
12
13
#include " utilities/XMLUtils.h"
13
14
15
+ #include < algorithm>
14
16
#include < chrono>
15
17
#include < regex>
18
+ #include < set>
16
19
#include < thread>
17
20
18
21
#include < kodi/tools/StringUtils.h>
@@ -361,9 +364,19 @@ void Epg::LoadEpgEntries(const xml_node& rootElement, int epgWindowStart, int ep
361
364
}
362
365
363
366
Logger::Log (LEVEL_INFO, " %s - Loaded '%d' EPG entries." , __FUNCTION__, count);
367
+
368
+ // Remove channelEpg that have empty EPG entries
369
+ const int epgChannelCount = m_channelEpgs.size ();
370
+ m_channelEpgs.erase (
371
+ std::remove_if (m_channelEpgs.begin (), m_channelEpgs.end (),
372
+ [](ChannelEpg& channelEpg) {
373
+ return channelEpg.GetEpgEntries ().empty ();
374
+ }),
375
+ m_channelEpgs.end ()
376
+ );
377
+ Logger::Log (LEVEL_INFO, " %s - Number of channels with EPG data after cleanup: %d (Removed %d channelEPGs)" , __FUNCTION__, m_channelEpgs.size (), epgChannelCount - m_channelEpgs.size ());
364
378
}
365
379
366
-
367
380
void Epg::ReloadEPG ()
368
381
{
369
382
m_xmltvLocation = m_settings->GetEpgLocation ();
@@ -387,11 +400,6 @@ void Epg::ReloadEPG()
387
400
388
401
PVR_ERROR Epg::GetEPGForChannel (int channelUid, time_t epgWindowStart, time_t epgWindowEnd, kodi::addon::PVREPGTagsResultSet& results)
389
402
{
390
- for (const auto & myChannel : m_channels.GetChannelsList ())
391
- {
392
- if (myChannel.GetUniqueId () != channelUid)
393
- continue ;
394
-
395
403
if (epgWindowStart > m_lastStart || epgWindowEnd > m_lastEnd)
396
404
{
397
405
// reload EPG for new time interval only
@@ -404,6 +412,10 @@ PVR_ERROR Epg::GetEPGForChannel(int channelUid, time_t epgWindowStart, time_t ep
404
412
m_lastEnd = static_cast <int >(epgWindowEnd);
405
413
}
406
414
}
415
+ for (const auto & myChannel : m_channels.GetChannelsList ())
416
+ {
417
+ if (myChannel.GetUniqueId () != channelUid)
418
+ continue ;
407
419
408
420
ChannelEpg* channelEpg = FindEpgForChannel (myChannel);
409
421
if (!channelEpg || channelEpg->GetEpgEntries ().size () == 0 )
@@ -433,71 +445,99 @@ PVR_ERROR Epg::GetEPGForChannel(int channelUid, time_t epgWindowStart, time_t ep
433
445
return PVR_ERROR_NO_ERROR;
434
446
}
435
447
436
- namespace
437
- {
438
- bool TvgIdMatchesCaseOrNoCase (const std::string& idOne, const std::string& idTwo, bool ignoreCaseForEpgChannelIds)
439
- {
440
- if (ignoreCaseForEpgChannelIds)
441
- return StringUtils::EqualsNoCase (idOne, idTwo);
442
- else
443
- return idOne == idTwo;
444
- }
445
- }
446
-
447
448
ChannelEpg* Epg::FindEpgForChannel (const std::string& id) const
448
449
{
449
450
for (auto & myChannelEpg : m_channelEpgs)
450
451
{
451
- if (TvgIdMatchesCaseOrNoCase (myChannelEpg.GetId (), id, m_settings->IgnoreCaseForEpgChannelIds ()))
452
+ if (m_settings->IgnoreCaseForEpgChannelIds ())
453
+ {
454
+ if (StringUtils::EqualsNoCase (myChannelEpg.GetId (), id))
455
+ return const_cast <ChannelEpg*>(&myChannelEpg);
456
+ }
457
+ else if (myChannelEpg.GetId () == id)
458
+ {
452
459
return const_cast <ChannelEpg*>(&myChannelEpg);
460
+ }
453
461
}
454
462
455
463
return nullptr ;
456
464
}
457
465
458
466
ChannelEpg* Epg::FindEpgForChannel (const Channel& channel) const
459
467
{
460
- for (auto & myChannelEpg : m_channelEpgs)
461
- {
462
- if (TvgIdMatchesCaseOrNoCase (myChannelEpg.GetId (), channel.GetTvgId (), m_settings->IgnoreCaseForEpgChannelIds ()))
463
- return const_cast <ChannelEpg*>(&myChannelEpg);
464
- }
468
+ double maxSimilarity = 0.0 ;
469
+ ChannelEpg* bestMatch = nullptr ;
465
470
466
471
for (auto & myChannelEpg : m_channelEpgs)
467
472
{
468
- for (const DisplayNamePair& displayNamePair : myChannelEpg.GetDisplayNames ())
473
+ double similarity = utilities::StringComparer::SorensenDiceSimilarity (
474
+ myChannelEpg.GetId (), channel.GetTvgId (), m_settings);
475
+
476
+ if (similarity > maxSimilarity)
469
477
{
470
- if (StringUtils::EqualsNoCase (displayNamePair.m_displayNameWithUnderscores , channel.GetTvgName ()) ||
471
- StringUtils::EqualsNoCase (displayNamePair.m_displayName , channel.GetTvgName ()))
472
- return const_cast <ChannelEpg*>(&myChannelEpg);
478
+ maxSimilarity = similarity;
479
+ bestMatch = const_cast <ChannelEpg*>(&myChannelEpg);
480
+
481
+ if (maxSimilarity == 1.0 )
482
+ break ;
473
483
}
474
484
}
485
+
486
+ if (bestMatch != nullptr )
487
+ return bestMatch;
475
488
476
489
for (auto & myChannelEpg : m_channelEpgs)
477
490
{
478
491
for (const DisplayNamePair& displayNamePair : myChannelEpg.GetDisplayNames ())
479
492
{
480
- if (StringUtils::EqualsNoCase (displayNamePair.m_displayName , channel.GetChannelName ()))
481
- return const_cast <ChannelEpg*>(&myChannelEpg);
493
+ double similarity = utilities::StringComparer::SorensenDiceSimilarity (
494
+ displayNamePair.m_displayName , channel.GetTvgName (), m_settings);
495
+
496
+ if (similarity == 0.0 )
497
+ similarity = utilities::StringComparer::SorensenDiceSimilarity (
498
+ displayNamePair.m_displayNameWithUnderscores , channel.GetTvgName (), m_settings);
499
+
500
+ if (similarity == 0.0 )
501
+ similarity = utilities::StringComparer::SorensenDiceSimilarity (
502
+ displayNamePair.m_displayName , channel.GetChannelName (), m_settings);
503
+
504
+ if (similarity > maxSimilarity)
505
+ {
506
+ maxSimilarity = similarity;
507
+ bestMatch = const_cast <ChannelEpg*>(&myChannelEpg);
508
+
509
+ if (maxSimilarity == 1.0 )
510
+ break ;
511
+ }
482
512
}
513
+ if (maxSimilarity == 1.0 )
514
+ break ;
483
515
}
484
516
485
- return nullptr ;
517
+ return bestMatch ;
486
518
}
487
519
488
520
ChannelEpg* Epg::FindEpgForMediaEntry (const MediaEntry& mediaEntry) const
489
521
{
490
522
for (auto & myChannelEpg : m_channelEpgs)
491
523
{
492
- if (TvgIdMatchesCaseOrNoCase (myChannelEpg.GetId (), mediaEntry.GetTvgId (), m_settings->IgnoreCaseForEpgChannelIds ()))
524
+ if (m_settings->IgnoreCaseForEpgChannelIds ())
525
+ {
526
+ if (StringUtils::EqualsNoCase (myChannelEpg.GetId (), mediaEntry.GetTvgId ()))
527
+ return const_cast <ChannelEpg*>(&myChannelEpg);
528
+ }
529
+ else if (myChannelEpg.GetId () == mediaEntry.GetTvgId ())
530
+ {
493
531
return const_cast <ChannelEpg*>(&myChannelEpg);
532
+ }
494
533
}
495
534
496
535
for (auto & myChannelEpg : m_channelEpgs)
497
536
{
498
537
for (const DisplayNamePair& displayNamePair : myChannelEpg.GetDisplayNames ())
499
538
{
500
- if (StringUtils::EqualsNoCase (displayNamePair.m_displayNameWithUnderscores , mediaEntry.GetTvgName ()) ||
539
+ if (StringUtils::EqualsNoCase (displayNamePair.m_displayNameWithUnderscores ,
540
+ mediaEntry.GetTvgName ()) ||
501
541
StringUtils::EqualsNoCase (displayNamePair.m_displayName , mediaEntry.GetTvgName ()))
502
542
return const_cast <ChannelEpg*>(&myChannelEpg);
503
543
}
@@ -511,7 +551,7 @@ ChannelEpg* Epg::FindEpgForMediaEntry(const MediaEntry& mediaEntry) const
511
551
if (StringUtils::EqualsNoCase (displayNamePair.m_displayName , mediaEntry.GetM3UName ()))
512
552
return const_cast <ChannelEpg*>(&myChannelEpg);
513
553
}
514
- }
554
+ }
515
555
516
556
return nullptr ;
517
557
}
@@ -522,7 +562,7 @@ void Epg::ApplyChannelsLogosFromEPG()
522
562
523
563
for (const auto & channel : m_channels.GetChannelsList ())
524
564
{
525
- const ChannelEpg* channelEpg = FindEpgForChannel (channel);
565
+ const ChannelEpg* channelEpg = FindEpgForChannel (channel. GetTvgName () );
526
566
if (!channelEpg || channelEpg->GetIconPath ().empty ())
527
567
continue ;
528
568
0 commit comments