Skip to content

Commit

Permalink
Fix "Import Existing Scan" option
Browse files Browse the repository at this point in the history
Fix the Channel Scan option "Import Existing Scan".
This option has been broken since adding the field service_type
to database table channel in ticket #8774.
The functionality has been restored, but excluding the service_type value which
will be added before release of v32 as this requires a database schema change.

Other changes are:
- Present the saved scans in descending chronological order, so with the newest on top
- When saving a new scan, delete all scans older than 14 days from that video source
  Previously, only scans created with the same capture card were deleted.
- Delete al saved scans of a video source when the video source is deleted

Refs #8774
Refs #13472
  • Loading branch information
kmdewaal committed Apr 27, 2020
1 parent c38564e commit c970d58
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 84 deletions.
14 changes: 5 additions & 9 deletions mythtv/libs/libmythtv/channelscan/paneexistingscanimport.h
Expand Up @@ -57,16 +57,12 @@ class PaneExistingScanImport : public GroupSetting
if (!m_sourceid)
return;

vector<ScanInfo> scans = LoadScanList();
for (auto & scan : scans)
vector<ScanInfo> scans = LoadScanList(m_sourceid);
for (vector<ScanInfo>::reverse_iterator it = scans.rbegin(); it != scans.rend(); ++it)
{
if (scan.m_sourceid != m_sourceid)
continue;

QString scanDate = MythDate::toString(
scan.m_scandate, MythDate::kDateTimeFull);
QString proc = (scan.m_processed) ?
tr("processed") : tr("unprocessed");
ScanInfo &scan = *it;
QString scanDate = MythDate::toString(scan.m_scandate, MythDate::kDateTimeFull);
QString proc = (scan.m_processed) ? tr("processed") : tr("unprocessed");

m_scanSelect->addSelection(
QString("%1 %2").arg(scanDate).arg(proc),
Expand Down
197 changes: 122 additions & 75 deletions mythtv/libs/libmythtv/channelscan/scaninfo.cpp
Expand Up @@ -31,14 +31,17 @@ uint SaveScan(const ScanDTVTransportList &scan)
uint sourceid = scan[0].m_channels[0].m_sourceId;
uint cardid = scan[0].m_cardid;

// Delete very old scans
const vector<ScanInfo> list = LoadScanList();
// Delete scans more than two weeks old
const vector<ScanInfo> list = LoadScanList(sourceid);
for (const auto & si : list)
{
if (si.m_scandate > MythDate::current().addDays(-14))
continue;
if ((si.m_cardid == cardid) && (si.m_sourceid == sourceid))
if (si.m_scandate < MythDate::current().addDays(-14))
{
LOG(VB_CHANSCAN, LOG_DEBUG, "ScanInfo::SaveScan " +
QString("si.m_scanid:%1 si.m_scandate:%2 -- delete now")
.arg(si.m_scanid).arg(si.m_scandate.toString()));
ScanInfo::DeleteScan(si.m_scanid);
}
}

MSqlQuery query(MSqlQuery::InitCon());
Expand Down Expand Up @@ -76,13 +79,13 @@ ScanDTVTransportList LoadScan(uint scanid)
MSqlQuery query(MSqlQuery::InitCon());
MSqlQuery query2(MSqlQuery::InitCon());
query.prepare(
"SELECT frequency, inversion, symbolrate, "
" fec, polarity, "
" hp_code_rate, lp_code_rate, modulation, "
" transmission_mode, guard_interval, hierarchy, "
" modulation, bandwidth, sistandard, "
" tuner_type, transportid, mod_sys, "
" rolloff "
"SELECT frequency, inversion, symbolrate, " // 0, 1, 2
" fec, polarity, " // 3, 4
" hp_code_rate, lp_code_rate, modulation, " // 5, 6, 7
" transmission_mode, guard_interval, hierarchy, " // 8, 9, 10
" modulation, bandwidth, sistandard, " // 11, 12, 13
" tuner_type, transportid, mod_sys, " // 14, 15, 16
" rolloff " // 17
"FROM channelscan_dtv_multiplex "
"WHERE scanid = :SCANID");
query.bindValue(":SCANID", scanid);
Expand All @@ -97,30 +100,32 @@ ScanDTVTransportList LoadScan(uint scanid)
ScanDTVTransport mux;
mux.ParseTuningParams(
(DTVTunerType) query.value(14).toUInt(),
query.value(0).toString(), query.value(1).toString(),
query.value(2).toString(), query.value(3).toString(),
query.value(4).toString(), query.value(5).toString(),
query.value(6).toString(), query.value(7).toString(),
query.value(8).toString(), query.value(9).toString(),
query.value(10).toString(), query.value(11).toString(),
query.value(12).toString(), query.value(13).toString(),
query.value(14).toString());
query.value(0).toString(), query.value(1).toString(), // frequency inversion
query.value(2).toString(), query.value(3).toString(), // symbolrate fec
query.value(4).toString(), query.value(5).toString(), // polarity hp_code_rate
query.value(6).toString(), query.value(7).toString(), // lp_code_rate modulation
query.value(8).toString(), query.value(9).toString(), // transmission_mode guard_interval
query.value(10).toString(), query.value(11).toString(), // hierarchy modulation
query.value(12).toString(), query.value(16).toString(), // bandwidth mod_sys
query.value(17).toString()); // roloff

mux.m_sistandard = query.value(13).toString(); // sistandard

query2.prepare(
"SELECT "
" mplex_id, source_id, channel_id, "
" callsign, service_name, chan_num, "
" service_id, atsc_major_channel, atsc_minor_channel, "
" use_on_air_guide, hidden, hidden_in_guide, "
" freqid, icon, tvformat, "
" xmltvid, pat_tsid, vct_tsid, "
" vct_chan_tsid, sdt_tsid, orig_netid, "
" netid, si_standard, in_channels_conf, "
" in_pat, in_pmt, in_vct, "
" in_nit, in_sdt, is_encrypted, "
" is_data_service, is_audio_service, is_opencable, "
" could_be_opencable, decryption_status, default_authority, "
" service_type "
" mplex_id, source_id, channel_id, " // 0, 1, 2
" callsign, service_name, chan_num, " // 3, 4, 5
" service_id, atsc_major_channel, atsc_minor_channel, " // 6, 7, 8
" use_on_air_guide, hidden, hidden_in_guide, " // 9, 10, 11
" freqid, icon, tvformat, " // 12, 13, 14
" xmltvid, pat_tsid, vct_tsid, " // 15, 16, 17
" vct_chan_tsid, sdt_tsid, orig_netid, " // 18, 19, 20
" netid, si_standard, in_channels_conf, " // 21, 22, 23
" in_pat, in_pmt, in_vct, " // 24, 25, 26
" in_nit, in_sdt, is_encrypted, " // 27, 28, 29
" is_data_service, is_audio_service, is_opencable, " // 30, 31, 32
" could_be_opencable, decryption_status, default_authority " // 33, 34, 35
// " service_type " // See ticket #8774
"FROM channelscan_channel "
"WHERE transportid = :TRANSPORTID");
query2.bindValue(":TRANSPORTID", query.value(15).toUInt());
Expand All @@ -138,51 +143,54 @@ ScanDTVTransportList LoadScan(uint scanid)
query.value(13).toString() : si_standard;

ChannelInsertInfo chan(
query2.value(0).toUInt()/*mplex_id*/,
query2.value(1).toUInt()/*source_id*/,
query2.value(2).toUInt()/*channel_id*/,
query2.value(3).toString()/*callsign*/,
query2.value(4).toString()/*service_name*/,
query2.value(5).toString()/*chan_num*/,
query2.value(6).toUInt()/*service_id*/,

query2.value(7).toUInt()/*atsc_major_channel*/,
query2.value(8).toUInt()/*atsc_minor_channel*/,
query2.value(9).toBool()/*use_on_air_guide*/,
query2.value(10).toBool()/*hidden*/,
query2.value(11).toBool()/*hidden_in_guide*/,

query2.value(12).toString()/*freqid*/,
query2.value(13).toString()/*icon*/,
query2.value(14).toString()/*tvformat*/,
query2.value(15).toString()/*xmltvid*/,

query2.value(16).toUInt()/*pat_tsid*/,
query2.value(17).toUInt()/*vct_tsid*/,
query2.value(18).toUInt()/*vct_chan_tsid*/,
query2.value(19).toUInt()/*sdt_tsid*/,

query2.value(20).toUInt()/*orig_netid*/,
query2.value(21).toUInt()/*netid*/,
query2.value(0).toUInt(), // mplex_id
query2.value(1).toUInt(), // source_id
query2.value(2).toUInt(), // channel_id
query2.value(3).toString(), // callsign
query2.value(4).toString(), // service_name
query2.value(5).toString(), // chan_num
query2.value(6).toUInt(), // service_id

query2.value(7).toUInt(), // atsc_major_channel
query2.value(8).toUInt(), // atsc_minor_channel
query2.value(9).toBool(), // use_on_air_guide
query2.value(10).toBool(), // hidden
query2.value(11).toBool(), // hidden_in_guide

query2.value(12).toString(), // freqid
query2.value(13).toString(), // icon
query2.value(14).toString(), // tvformat
query2.value(15).toString(), // xmltvid

query2.value(16).toUInt(), // pat_tsid
query2.value(17).toUInt(), // vct_tsid
query2.value(18).toUInt(), // vct_chan_tsid
query2.value(19).toUInt(), // sdt_tsid

query2.value(20).toUInt(), // orig_netid
query2.value(21).toUInt(), // netid

si_standard,

query2.value(23).toBool()/*in_channels_conf*/,
query2.value(24).toBool()/*in_pat*/,
query2.value(25).toBool()/*in_pmt*/,
query2.value(26).toBool()/*in_vct*/,
query2.value(27).toBool()/*in_nit*/,
query2.value(28).toBool()/*in_sdt*/,

query2.value(29).toBool()/*is_encrypted*/,
query2.value(30).toBool()/*is_data_service*/,
query2.value(31).toBool()/*is_audio_service*/,
query2.value(32).toBool()/*is_opencable*/,
query2.value(33).toBool()/*could_be_opencable*/,
query2.value(34).toInt()/*decryption_status*/,
query2.value(35).toString()/*default_authority*/,
query2.value(36).toUInt()/*service_type*/);

query2.value(23).toBool(), // in_channels_conf
query2.value(24).toBool(), // in_pat
query2.value(25).toBool(), // in_pmt
query2.value(26).toBool(), // in_vct
query2.value(27).toBool(), // in_nit
query2.value(28).toBool(), // in_sdt

query2.value(29).toBool(), // is_encrypted
query2.value(30).toBool(), // is_data_service
query2.value(31).toBool(), // is_audio_service
query2.value(32).toBool(), // is_opencable
query2.value(33).toBool(), // could_be_opencable
query2.value(34).toInt(), // decryption_status
query2.value(35).toString(), // default_authority
#if 0 // See ticket #8774
query2.value(36).toUInt()); // service_type
#else
0);
#endif
mux.m_channels.push_back(chan);
}

Expand Down Expand Up @@ -249,6 +257,15 @@ bool ScanInfo::DeleteScan(uint scanid)
return true;
}

void ScanInfo::DeleteScansFromSource(uint sourceid)
{
vector<ScanInfo> scans = LoadScanList(sourceid);
for (auto &scan : scans)
{
DeleteScan(scan.m_scanid);
}
}

vector<ScanInfo> LoadScanList(void)
{
vector<ScanInfo> list;
Expand Down Expand Up @@ -276,3 +293,33 @@ vector<ScanInfo> LoadScanList(void)

return list;
}

vector<ScanInfo> LoadScanList(uint sourceid)
{
vector<ScanInfo> list;

MSqlQuery query(MSqlQuery::InitCon());
query.prepare(
"SELECT scanid, cardid, sourceid, processed, scandate "
"FROM channelscan "
"WHERE sourceid = :SOURCEID "
"ORDER BY scanid, sourceid, cardid, scandate");
query.bindValue(":SOURCEID", sourceid);

if (!query.exec())
{
MythDB::DBError("LoadScanList", query);
return list;
}

while (query.next())
{
list.emplace_back(query.value(0).toUInt(),
query.value(1).toUInt(),
query.value(2).toUInt(),
(bool) query.value(3).toUInt(),
MythDate::as_utc(query.value(4).toDateTime()));
}

return list;
}
2 changes: 2 additions & 0 deletions mythtv/libs/libmythtv/channelscan/scaninfo.h
Expand Up @@ -24,6 +24,7 @@ class ScanInfo

static bool MarkProcessed(uint scanid);
static bool DeleteScan(uint scanid);
static void DeleteScansFromSource(uint sourceid);

public:
uint m_scanid {0};
Expand All @@ -34,6 +35,7 @@ class ScanInfo
};

MTV_PUBLIC vector<ScanInfo> LoadScanList(void);
MTV_PUBLIC vector<ScanInfo> LoadScanList(uint sourceid);
uint SaveScan(const ScanDTVTransportList &scan);
MTV_PUBLIC ScanDTVTransportList LoadScan(uint scanid);

Expand Down
4 changes: 4 additions & 0 deletions mythtv/libs/libmythtv/sourceutil.cpp
Expand Up @@ -6,6 +6,7 @@
// MythTV headers
#include "sourceutil.h"
#include "cardutil.h"
#include "scaninfo.h"
#include "mythdb.h"
#include "mythdirs.h"
#include "mythlogging.h"
Expand Down Expand Up @@ -533,6 +534,9 @@ bool SourceUtil::DeleteSource(uint sourceid)
return false;
}

// Delete all the saved channel scans for this source
ScanInfo::DeleteScansFromSource(sourceid);

// Delete the source itself
query.prepare("DELETE FROM videosource "
"WHERE sourceid = :SOURCEID");
Expand Down

0 comments on commit c970d58

Please sign in to comment.