if (res && (errno == EAGAIN))
break;
- if (res)
- {
- eWarning("FE_GET_EVENT failed! %m");
- return;
- }
-
if (w < 0)
continue;
sec_fe->sendToneburst(m_sec_sequence.current()++->toneburst);
break;
case eSecCommand::SET_FRONTEND:
- eDebugNoSimulate("[SEC] setFrontend");
- setFrontend();
- ++m_sec_sequence.current();
+ {
+ int enableEvents = (m_sec_sequence.current()++)->val;
+ eDebugNoSimulate("[SEC] setFrontend %d", enableEvents);
+ setFrontend(enableEvents);
break;
+ }
case eSecCommand::START_TUNE_TIMEOUT:
{
+ int tuneTimeout = m_sec_sequence.current()->timeout;
+ eDebugNoSimulate("[SEC] startTuneTimeout %d", tuneTimeout);
if (!m_simulate)
- m_timeout->start(m_sec_sequence.current()->timeout, 1);
+ m_timeout->start(tuneTimeout, 1);
++m_sec_sequence.current();
break;
}
int signal = 0;
int isLocked = readFrontendData(locked);
m_idleInputpower[0] = m_idleInputpower[1] = 0;
- if (isLocked && ((abs((signal = readFrontendData(signalQualitydB)) - cmd.lastSignal) < 50) || !cmd.lastSignal))
+ --m_timeoutCount;
+ if (!m_timeoutCount && m_retryCount > 0)
+ --m_retryCount;
+ if (isLocked && ((abs((signal = readFrontendData(signalQualitydB)) - cmd.lastSignal) < 40) || !cmd.lastSignal))
{
if (cmd.lastSignal)
eDebugNoSimulate("[SEC] locked step %d ok (%d %d)", cmd.okcount, signal, cmd.lastSignal);
else
{
eDebugNoSimulate("[SEC] locked step %d ok", cmd.okcount);
- cmd.lastSignal = signal;
+ if (!cmd.okcount)
+ cmd.lastSignal = signal;
}
++cmd.okcount;
if (cmd.okcount > 4)
{
- eDebugNoSimulate("ok > 4 .. goto %d\n",cmd.steps);
+ eDebugNoSimulate("ok > 4 .. goto %d\n", cmd.steps);
setSecSequencePos(cmd.steps);
m_state = stateLock;
m_stateChanged(this);
- feEvent(-1);
+ feEvent(-1); // flush events
m_sn->start();
break;
}
eDebugNoSimulate("[SEC] rotor locked step %d failed (oldSignal %d, curSignal %d)", cmd.okcount, signal, cmd.lastSignal);
else
eDebugNoSimulate("[SEC] rotor locked step %d failed (not locked)", cmd.okcount);
- --m_timeoutCount;
- if (!m_timeoutCount && m_retryCount > 0)
- --m_retryCount;
cmd.okcount=0;
cmd.lastSignal=0;
}
}
int idleInputpower = m_idleInputpower[ (sec_fe_data[CUR_VOLTAGE]&1) ? 0 : 1];
const char *txt = cmd.direction ? "running" : "stopped";
+ --m_timeoutCount;
+ if (!m_timeoutCount && m_retryCount > 0)
+ --m_retryCount;
eDebugNoSimulate("[SEC] waiting for rotor %s %d, idle %d, delta %d",
txt,
m_runningInputpower,
else
{
eDebugNoSimulate("[SEC] rotor not %s... reset counter.. increase timeout", txt);
- --m_timeoutCount;
- if (!m_timeoutCount && m_retryCount > 0)
- --m_retryCount;
cmd.okcount=0;
}
++m_sec_sequence.current();
tuneLoop();
}
-void eDVBFrontend::setFrontend()
+void eDVBFrontend::setFrontend(bool recvEvents)
{
if (!m_simulate)
{
eDebug("setting frontend %d", m_dvbid);
- m_sn->start();
- feEvent(-1);
+ if (recvEvents)
+ m_sn->start();
+ feEvent(-1); // flush events
if (ioctl(m_fd, FE_SET_FRONTEND, &parm) == -1)
{
perror("FE_SET_FRONTEND failed");
goto tune_error;
m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
- m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND) );
+ m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
break;
}
case feTerrestrial:
m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
else
m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltageOff) );
- m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND) );
+ m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
break;
}
void feEvent(int);
void timeout();
void tuneLoop(); // called by m_tuneTimer
- void setFrontend();
+ void setFrontend(bool recvEvents=true);
bool setSecSequencePos(int steps);
static int PriorityOrder;
public:
int first_ac3 = -1;
program.defaultAudioStream = 0;
+ int rdsPid = -1;
+ audioStream *prev_audio = 0;
if ( m_service && !m_service->cacheEmpty() )
{
for (es = pmt.getEsInfo()->begin(); es != pmt.getEsInfo()->end(); ++es)
{
int isaudio = 0, isvideo = 0, issubtitle = 0, forced_video = 0, forced_audio = 0, isteletext = 0;
+ int streamtype = (*es)->getType();
videoStream video;
audioStream audio;
audio.component_tag=video.component_tag=-1;
video.type = videoStream::vtMPEG2;
audio.type = audioStream::atMPEG;
+ audio.rdsPid = -1;
- switch ((*es)->getType())
+ switch (streamtype)
{
case 0x1b: // AVC Video Stream (MPEG4 H264)
video.type = videoStream::vtMPEG4_H264;
}
case 0x06: // PES Private
case 0xEA: // TS_PSI_ST_SMPTE_VC1
+ {
+ int num_descriptors = 0;
for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin();
desc != (*es)->getDescriptors()->end(); ++desc)
{
uint8_t tag = (*desc)->getTag();
/* check descriptors to get the exakt stream type. */
+ ++num_descriptors;
if (!forced_video && !forced_audio)
{
switch (tag)
break;
}
}
+ if (!num_descriptors && streamtype == 0x06 && prev_audio)
+ {
+ prev_audio->rdsPid = (*es)->getPid();
+ eDebug("Rds PID %04x detected ? ! ?", prev_audio->rdsPid);
+ }
+ prev_audio = 0;
+ }
default:
break;
}
first_ac3 = program.audioStreams.size();
program.audioStreams.push_back(audio);
+ prev_audio = &program.audioStreams.back();
}
else
continue;
audioStream s;
s.type = audioStream::atAC3;
s.pid = cached_apid_ac3;
+ s.rdsPid = -1;
program.audioStreams.push_back(s);
++cnt;
}
audioStream s;
s.type = audioStream::atMPEG;
s.pid = cached_apid_mpeg;
+ s.rdsPid = -1;
program.audioStreams.push_back(s);
++cnt;
}
struct audioStream
{
- int pid;
+ int pid,
+ rdsPid; // hack for some radio services which transmit radiotext on different pid (i.e. harmony fm, HIT RADIO FFH, ...)
enum { atMPEG, atAC3, atDTS, atAAC, atAACHE, atLPCM };
int type; // mpeg2, ac3, dts, ...
int pmtPid;
int textPid;
bool isCrypted() { return !caids.empty(); }
-
PyObject *createPythonObject();
};
DEFINE_REF(eDVBRdsDecoder);
-eDVBRdsDecoder::eDVBRdsDecoder(iDVBDemux *demux)
+eDVBRdsDecoder::eDVBRdsDecoder(iDVBDemux *demux, int type)
:msgPtr(0), bsflag(0), qdar_pos(0), t_ptr(0), qdarmvi_show(0), state(0)
- ,m_abortTimer(eTimer::create(eApp))
+ ,m_type(type), m_pid(-1), m_abortTimer(eTimer::create(eApp))
{
setStreamID(0xC0, 0xC0);
if (demux->createPESReader(eApp, m_pes_reader))
eDebug("failed to create PES reader!");
- else
+ else if (type == 0)
m_pes_reader->connectRead(slot(*this, &eDVBRdsDecoder::processData), m_read_connection);
+ else
+ m_pes_reader->connectRead(slot(*this, &eDVBRdsDecoder::gotAncillaryData), m_read_connection);
CONNECT(m_abortTimer->timeout, eDVBRdsDecoder::abortNonAvail);
}
m_abortTimer->stop();
int ancillary_len = 1 + data[offs - 1];
offs -= ancillary_len;
- gotAncillaryData(data+offs, ancillary_len);
+ gotAncillaryData(data+offs, ancillary_len-1);
}
}
}
}
}
-inline void eDVBRdsDecoder::gotAncillaryData(__u8 *buf, int len)
+void eDVBRdsDecoder::gotAncillaryData(const __u8 *buf, int len)
{
- int cnt=buf[--len];
- while ( cnt-- > 0 )
+ if (len <= 0)
+ return;
+ int pos = m_type ? 0 : len-1;
+ while ( len )
{
- unsigned char c = buf[--len];
-
+ unsigned char c = buf[pos];
+
+ pos += m_type ? 1 : -1;
+
+ --len;
+
if (bsflag == 1) // byte stuffing
{
bsflag=2;
int eDVBRdsDecoder::start(int pid)
{
int ret = -1;
- if (m_pes_reader && !(ret = m_pes_reader->start(pid)))
+ if (m_pes_reader && !(ret = m_pes_reader->start(pid)) && m_type == 0)
m_abortTimer->startLongTimer(20);
+ m_pid = pid;
return ret;
}
unsigned char rass_picture_mask[5]; // 40 bits... (10 * 4 pictures)
void addToPictureMask(int id);
void removeFromPictureMask(int id);
+ int m_type;
+ int m_pid;
public:
enum { RadioTextChanged, RtpTextChanged, RassInteractivePicMaskChanged, RecvRassSlidePic };
- eDVBRdsDecoder(iDVBDemux *demux);
+ eDVBRdsDecoder(iDVBDemux *demux, int type);
~eDVBRdsDecoder();
int start(int pid);
void connectEvent(const Slot1<void, int> &slot, ePtr<eConnection> &connection);
ePyObject getRassPictureMask();
std::string getRassPicture(int page, int subpage);
std::string getRassSlideshowPicture() { return "/tmp/RassLast.mvi"; }
+ int getPid() { return m_pid; }
private:
void abortNonAvail();
void processPESPacket(__u8 *pkt, int len);
- inline void gotAncillaryData(__u8 *data, int len);
+ void gotAncillaryData(const __u8 *data, int len);
void process_qdar(unsigned char*);
ePtr<iDVBPESReader> m_pes_reader;
ePtr<eConnection> m_read_connection;
}
if(lnb_param.SatCR_idx == -1)
{
+ int mrt = m_params[MOTOR_RUNNING_TIMEOUT]; // in seconds!
if ( rotor_param.m_inputpower_parameters.m_use )
{ // use measure rotor input power to detect rotor state
bool turn_fast = need_turn_fast(rotor_param.m_inputpower_parameters.m_turning_speed);
sec_sequence.push_back( eSecCommand(eSecCommand::SET_ROTOR_MOVING) );
if (turn_fast)
sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, VOLTAGE(18)) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SET_TIMEOUT, m_params[MOTOR_RUNNING_TIMEOUT]*20) ); // 2 minutes running timeout
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_TIMEOUT, mrt*20) ); // mrt is in seconds... our SLEEP time is 50ms.. so * 20
// rotor running loop
sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) ); // wait 50msec
sec_sequence.push_back( eSecCommand(eSecCommand::MEASURE_RUNNING_INPUTPOWER) );
}
else
{ // use normal turning mode
+ if (curRotorPos != -1)
+ {
+ mrt = abs(curRotorPos - sat.orbital_position);
+ if (mrt > 1800)
+ mrt = 3600 - mrt;
+ if (mrt % 10)
+ mrt += 10; // round a little bit
+ mrt *= 2000; // (we assume a very slow rotor with just 0.5 degree per second here)
+ mrt /= 10000;
+ mrt += 3; // a little bit overhead
+ }
doSetVoltageToneFrontend=false;
doSetFrontend=false;
eSecCommand::rotor cmd;
sec_sequence.push_back( eSecCommand(eSecCommand::INVALIDATE_CURRENT_ROTORPARMS) );
sec_sequence.push_back( eSecCommand(eSecCommand::SET_ROTOR_MOVING) );
sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
-
+ sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 1000) ); // sleep one second before change voltage or tone
+
compare.voltage = voltage;
compare.steps = +3;
sec_sequence.push_back( eSecCommand(eSecCommand::IF_VOLTAGE_GOTO, compare) ); // correct final voltage?
sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 2000) ); // wait 2 second before set high voltage
sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, voltage) );
-
+
compare.tone = tone;
sec_sequence.push_back( eSecCommand(eSecCommand::IF_TONE_GOTO, compare) );
sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, tone) );
sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, m_params[DELAY_AFTER_FINAL_CONT_TONE_CHANGE]) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 0) );
cmd.direction=1; // check for running rotor
cmd.deltaA=0;
- cmd.steps=+3;
+ cmd.steps = +3;
cmd.okcount=0;
- sec_sequence.push_back( eSecCommand(eSecCommand::SET_TIMEOUT, m_params[MOTOR_RUNNING_TIMEOUT]*4) ); // 2 minutes running timeout
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_TIMEOUT, mrt*4) ); // mrt is in seconds... our SLEEP time is 250ms.. so * 4
sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 250) ); // 250msec delay
sec_sequence.push_back( eSecCommand(eSecCommand::IF_TUNER_LOCKED_GOTO, cmd ) );
- sec_sequence.push_back( eSecCommand(eSecCommand::IF_TIMEOUT_GOTO, +3 ) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::IF_TIMEOUT_GOTO, +5 ) );
sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -3) ); // goto loop start
sec_sequence.push_back( eSecCommand(eSecCommand::UPDATE_CURRENT_ROTORPARAMS) );
sec_sequence.push_back( eSecCommand(eSecCommand::SET_ROTOR_STOPPED) );
- sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, +3) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND) );
- sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -4) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, +4) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, tunetimeout) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -5) );
}
+ eDebug("set rotor timeout to %d seconds", mrt);
+ sec_fe->setData(eDVBFrontend::NEW_ROTOR_CMD, RotorCmd);
+ sec_fe->setData(eDVBFrontend::NEW_ROTOR_POS, sat.orbital_position);
}
- sec_fe->setData(eDVBFrontend::NEW_ROTOR_CMD, RotorCmd);
- sec_fe->setData(eDVBFrontend::NEW_ROTOR_POS, sat.orbital_position);
}
}
}
if (doSetFrontend)
{
sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, tunetimeout) );
- sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND) );
+ sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
}
sec_sequence.push_front( eSecCommand(eSecCommand::SET_POWER_LIMITING_MODE, eSecCommand::modeStatic) );
int eDVBSubtitleParser::subtitle_process_pixel_data(subtitle_region *region, subtitle_region_object *object, int *linenr, int *linep, __u8 *data)
{
int data_type = *data++;
- static __u8 line[720];
+ static __u8 line[1920];
bitstream bit;
bit.size=0;
map_2_to_4_bit_table[col] :
region->depth == subtitle_region::bpp8 ?
map_2_to_8_bit_table[col] : col;
- while (len && ((*linep) < 720))
+ while (len && ((*linep) < m_display_size.width()))
{
line[(*linep)++] = c;
len--;
}
uint8_t c = region->depth == subtitle_region::bpp8 ?
map_4_to_8_bit_table[col] : col;
- while (len && ((*linep) < 720))
+ while (len && ((*linep) < m_display_size.width()))
{
line[(*linep)++] = c;
len--;
} else
break;
}
- while (len && ((*linep) < 720))
+ while (len && ((*linep) < m_display_size.width()))
{
line[(*linep)++] = col;
len--;
subtitle_process_line(region, object, *linenr, line, *linep);
/* {
int i;
- for (i=0; i<720; ++i)
+ for (i=0; i<m_display_size.width(); ++i)
eDebugNoNewLine("%d ", line[i]);
eDebug("");
} */
import os
from twisted.mail import smtp, relaymanager
+import MimeWriter, mimetools, StringIO
config.plugins.crashlogautosubmit = ConfigSubsection()
config.plugins.crashlogautosubmit.sendmail = ConfigSelection(default = "send", choices = [
def mxServerFound(mxServer,session):
print "[CrashlogAutoSubmit] - mxServerFound -->", mxServer
- attachments = []
crashLogFilelist = []
+ message = StringIO.StringIO()
+ writer = MimeWriter.MimeWriter(message)
mailFrom = "enigma2@crashlog.dream-multimedia-tv.de"
mailTo = "enigma2@crashlog.dream-multimedia-tv.de"
subject = "Automatically generated crashlogmail"
- mailtext = "\nHello\n\nHere are some crashlogs i found for you.\n"
- mailfooter = "\n\nThis is an automatically generated email from the CrashlogAutoSubmit plugin.\n\n\nHave a nice day.\n"
+ # Define the main body headers.
+ writer.addheader('To', "dream-multimedia-crashlogs <enigma2@crashlog.dream-multimedia-tv.de>")
+ writer.addheader('From', "CrashlogAutoSubmitter <enigma2@crashlog.dream-multimedia-tv.de>")
+ writer.addheader('Subject', str(subject))
+ writer.addheader('Date', smtp.rfc822date())
+ if config.plugins.crashlogautosubmit.attachemail.value is True:
+ if str(config.plugins.crashlogautosubmit.email.value) != "myemail@home.com":
+ writer.addheader('Reply-To', str(str(config.plugins.crashlogautosubmit.email.value)))
+ writer.addheader('MIME-Version', '1.0')
+ writer.startmultipartbody('mixed')
+ # start with a text/plain part
+ part = writer.nextpart()
+ body = part.startbody('text/plain')
+ part.flushheaders()
+ # Define the message body
+ body_text1 = "\nHello\n\nHere are some crashlogs i found for you.\n"
if str(config.plugins.crashlogautosubmit.email.value) == "myemail@home.com":
user_email = ""
else:
user_name = ""
else:
user_name = "\n\nOptional supplied name: " + str(config.plugins.crashlogautosubmit.name.value)
- headers = { 'from': 'CrashlogAutoSubmitter <enigma2@crashlog.dream-multimedia-tv.de>', 'to': 'dream-multimedia-crashlogs <enigma2@crashlog.dream-multimedia-tv.de>', 'subject' : str(subject) }
- mailData = mailtext + user_email + user_name + mailfooter
- if config.plugins.crashlogautosubmit.attachemail.value is True:
- if str(config.plugins.crashlogautosubmit.email.value) != "myemail@home.com":
- headers["reply-to"] = str(config.plugins.crashlogautosubmit.email.value)
+ body_text2 = "\n\nThis is an automatically generated email from the CrashlogAutoSubmit plugin.\n\n\nHave a nice day.\n"
+ body_text = body_text1 + user_email + user_name + body_text2
+ body.write(body_text)
list = (
(_("Yes"), "send"),
def send_mail():
print "[CrashlogAutoSubmit] - send_mail"
- attachments = []
if len(crashLogFilelist):
for crashlog in crashLogFilelist:
filename = str(os.path.basename(crashlog))
- mimetype = "text/plain"
- f = open (crashlog, 'r')
- attachment = str(f.read())
- f.close()
- attachments.append ((filename,mimetype,attachment))
- sending = smtp.sendEmail(str(mxServer), mailFrom, mailTo, str(mailData), headers, attachments)
+ subpart = writer.nextpart()
+ subpart.addheader("Content-Transfer-Encoding", 'base64')
+ subpart.addheader("Content-Disposition",'attachment; filename="%s"' % filename)
+ subpart.addheader('Content-Description', 'Enigma2 crashlog')
+ body = subpart.startbody("%s; name=%s" % ('application/octet-stream', filename))
+ mimetools.encode(open(crashlog, 'rb'), body, 'base64')
+ writer.lastpart()
+ sending = smtp.sendmail(str(mxServer), mailFrom, mailTo, message.getvalue())
sending.addCallback(handleSuccess).addErrback(handleError)
def handleAnswer(answer):
elif answer == "send_not":
print "[CrashlogAutoSubmit] - not sending crashlogs for this time."
-
for crashlog in os.listdir('/media/hdd'):
if crashlog.startswith("enigma2_crash_") and crashlog.endswith(".log"):
print "[CrashlogAutoSubmit] - found crashlog: ",os.path.basename(crashlog)
def getMailExchange(host):
print "[CrashlogAutoSubmit] - getMailExchange"
+ return relaymanager.MXCalculator().getMX(host).addCallback(_gotMXRecord)
- def handleMXError(error):
- print "[CrashlogAutoSubmit] - DNS-Error, sending aborted -->", error.getErrorMessage()
-
- def cbMX(mxRecord):
- return str(mxRecord.name)
-
- return relaymanager.MXCalculator().getMX(host).addCallback(cbMX).addErrback(handleMXError)
+def _gotMXRecord(mxRecord):
+ return str(mxRecord.name)
def startMailer(session):
print "[CrashlogAutoSubmit] - not starting CrashlogAutoSubmit"
return False
+ def gotMXServer(mxServer):
+ print "[CrashlogAutoSubmit] gotMXServer: ",mxServer
+ mxServerFound(mxServer,session)
+
+ def handleMXError(error):
+ print "[CrashlogAutoSubmit] - MX resolve ERROR:", error.getErrorMessage()
+
if not config.misc.firstrun.value:
- getMailExchange('crashlog.dream-multimedia-tv.de').addCallback(mxServerFound,session)
+ getMailExchange('crashlog.dream-multimedia-tv.de').addCallback(gotMXServer).addErrback(handleMXError)
def callCrashMailer(result,session):
from Components.Label import Label
from Components.FileList import FileList
from Components.MultiContent import MultiContentEntryText
+from Components.ScrollLabel import ScrollLabel
from Tools.Directories import fileExists
from Tools.HardwareInfo import HardwareInfo
from enigma import eConsoleAppContainer, eListbox, gFont, eListboxPythonMultiContent, \
if self.instance is not None:
self.instance.moveSelectionTo(idx)
+class NFOViewer(Screen):
+ skin = """
+ <screen name="NFOViewer" position="110,115" size="540,400" title="Changelog viewer" >
+ <widget name="changelog" position="10,10" size="520,380" font="Regular;16" />
+ </screen>"""
+
+ def __init__(self, session, nfo):
+ Screen.__init__(self, session)
+ self["changelog"] = ScrollLabel(nfo)
+
+ self["ViewerActions"] = ActionMap(["SetupActions", "ColorActions", "DirectionActions"],
+ {
+ "green": self.exit,
+ "red": self.exit,
+ "ok": self.exit,
+ "cancel": self.exit,
+ "down": self.pageDown,
+ "up": self.pageUp
+ })
+ def pageUp(self):
+ self["changelog"].pageUp()
+
+ def pageDown(self):
+ self["changelog"].pageDown()
+
+ def exit(self):
+ self.close(False)
+
class NFIDownload(Screen):
LIST_SOURCE = 1
LIST_DEST = 2
self["destlist"].pageDown()
def ok(self):
+ if self.focus is self.LIST_SOURCE and self.nfo:
+ self.session.open(NFOViewer, self.nfo)
if self.download:
return
if self.focus is self.LIST_DEST:
def feed_finished(self, feedhtml):
print "[feed_finished] " + str(feedhtml)
self.downloading(False)
- fileresultmask = re.compile("<a href=[\'\"](?P<url>.*?)[\'\"]>(?P<name>.*?.nfi)</a>", re.DOTALL)
+ fileresultmask = re.compile("<a class=[\'\"]nfi[\'\"] href=[\'\"](?P<url>.*?)[\'\"]>(?P<name>.*?.nfi)</a>", re.DOTALL)
searchresults = fileresultmask.finditer(feedhtml)
fileresultlist = []
if searchresults:
else:
self.nfofilename = ""
self["infolabel"].text = _("No details for this image file")
- self["statusbar"].text = ""
+ self["statusbar"].text = _("Press OK to view full changelog")
def nfi_download(self):
if self["destlist"].getCurrentDirectory() is None:
self.conntected=False
self.session.nav.record_event.remove(self.getRecordEvent)
if value:
- quitMainloop(self.retval)
- else:
- MessageBox.close(self, True)
+ # hack .. we dont like to show any other screens when this screen has closed
+ self.onClose = [self.__closed]
+ self.session.dialog_stack = []
+ self.session.summary_stack = [None]
+ MessageBox.close(self, True)
+
+ def __closed(self):
+ quitMainloop(self.retval)
def __onShow(self):
global inTryQuitMainloop
return -4;
}
+ int rdsPid = apid;
+
/* if we are not in PVR mode, timeshift is not active and we are not in pip mode, check if we need to enable the rds reader */
if (!(m_is_pvr || m_timeshift_active || !m_is_primary))
- if (!m_rds_decoder)
+ {
+ int different_pid = program.videoStreams.empty() && program.audioStreams.size() == 1 && program.audioStreams[stream].rdsPid != -1;
+ if (different_pid)
+ rdsPid = program.audioStreams[stream].rdsPid;
+ if (!m_rds_decoder || m_rds_decoder->getPid() != rdsPid)
{
+ m_rds_decoder = 0;
ePtr<iDVBDemux> data_demux;
if (!h.getDataDemux(data_demux))
{
- m_rds_decoder = new eDVBRdsDecoder(data_demux);
+ m_rds_decoder = new eDVBRdsDecoder(data_demux, different_pid);
m_rds_decoder->connectEvent(slot(*this, &eDVBServicePlay::rdsDecoderEvent), m_rds_decoder_event_connection);
+ m_rds_decoder->start(rdsPid);
}
}
-
- /* if we decided that we need one, update the pid */
- if (m_rds_decoder)
- m_rds_decoder->start(apid);
+ }
/* store new pid as default only when:
a.) we have an entry in the service db for the current service,