aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Navigation.py4
-rw-r--r--data/defaults/Dream/userbouquet.favourites.tv10
-rwxr-xr-xdata/keymap.xml4
-rwxr-xr-xdata/skin_default.xml8
-rwxr-xr-x[-rw-r--r--]data/skin_default/Makefile.am2
-rwxr-xr-xdata/skin_default/border_menu_350.pngbin0 -> 2754 bytes
-rwxr-xr-x[-rw-r--r--]data/skin_default/div-h.pngbin151 -> 140 bytes
-rw-r--r--data/skin_default/unhandled-key.pngbin0 -> 1335 bytes
-rw-r--r--lib/actions/action.cpp2
-rw-r--r--lib/base/elock.h13
-rw-r--r--lib/driver/rc.cpp30
-rw-r--r--lib/driver/rc.h8
-rw-r--r--lib/driver/rcconsole.cpp1
-rw-r--r--lib/driver/rcinput.cpp5
-rw-r--r--lib/driver/rcinput.h1
-rw-r--r--lib/dvb/dvb.cpp2
-rw-r--r--lib/dvb/idvb.h2
-rw-r--r--lib/dvb/pmt.cpp3
-rw-r--r--lib/dvb/pmt.h1
-rw-r--r--lib/dvb/tstools.cpp83
-rw-r--r--lib/dvb/tstools.h6
-rwxr-xr-xlib/python/Components/ChoiceList.py2
-rw-r--r--lib/python/Components/NimManager.py12
-rw-r--r--lib/python/Plugins/Extensions/CutListEditor/plugin.py2
-rw-r--r--lib/python/Plugins/Extensions/DVDBurn/Process.py1
-rwxr-xr-xlib/python/Plugins/Extensions/DVDBurn/ProjectSettings.py2
-rwxr-xr-xlib/python/Plugins/Extensions/DVDBurn/TitleList.py32
-rwxr-xr-xlib/python/Plugins/Extensions/DVDBurn/TitleProperties.py5
-rw-r--r--lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.cpp2
-rwxr-xr-x[-rw-r--r--]lib/python/Plugins/SystemPlugins/SoftwareManager/Makefile.am3
-rwxr-xr-xlib/python/Plugins/SystemPlugins/SoftwareManager/SoftwareTools.py226
-rwxr-xr-xlib/python/Plugins/SystemPlugins/SoftwareManager/plugin.py1200
-rw-r--r--lib/python/Plugins/SystemPlugins/Videomode/VideoWizard.py8
-rw-r--r--lib/python/Plugins/SystemPlugins/Videomode/videowizard.xml6
-rw-r--r--lib/python/Screens/ChannelSelection.py49
-rw-r--r--lib/python/Screens/InfoBar.py6
-rw-r--r--lib/python/Screens/InfoBarGenerics.py52
-rwxr-xr-xlib/python/Screens/Makefile.am2
-rwxr-xr-xlib/python/Screens/PluginBrowser.py23
-rw-r--r--lib/python/Screens/Satconfig.py13
-rw-r--r--lib/python/Screens/UnhandledKey.py7
-rw-r--r--lib/service/servicedvb.cpp13
-rw-r--r--lib/service/servicemp3.cpp26
-rw-r--r--lib/service/servicexine.cpp2
-rwxr-xr-xtools/genmetaindex.py2
45 files changed, 1175 insertions, 706 deletions
diff --git a/Navigation.py b/Navigation.py
index 2ca87f6f..2437bbf5 100644
--- a/Navigation.py
+++ b/Navigation.py
@@ -50,9 +50,9 @@ class Navigation:
for x in self.record_event:
x(rec_service, event)
- def playService(self, ref, checkParentalControl = True):
+ def playService(self, ref, checkParentalControl = True, forceRestart = False):
oldref = self.currentlyPlayingServiceReference
- if ref and oldref and ref == oldref:
+ if ref and oldref and ref == oldref and not forceRestart:
print "ignore request to play already running service"
return 0
print "playing", ref and ref.toString()
diff --git a/data/defaults/Dream/userbouquet.favourites.tv b/data/defaults/Dream/userbouquet.favourites.tv
index f1adaf9e..cc5e9fe9 100644
--- a/data/defaults/Dream/userbouquet.favourites.tv
+++ b/data/defaults/Dream/userbouquet.favourites.tv
@@ -10,7 +10,7 @@
#SERVICE 1:0:1:33:21:85:C00000:0:0:0:
#SERVICE 1:0:1:701:5:85:C00000:0:0:0:
#SERVICE 1:0:1:2F1C:441:1:C00000:0:0:0:
-#SERVICE 1:0:1:7005:436:1:C00000:0:0:0:
+#SERVICE 1:0:1:6D6E:437:1:C00000:0:0:0:
#SERVICE 1:0:1:2FC:5:85:C00000:0:0:0:
#SERVICE 1:0:1:F98:454:1:C00000:0:0:0:
#SERVICE 1:0:1:7034:41B:1:C00000:0:0:0:
@@ -26,7 +26,6 @@
#SERVICE 1:64:B:0:0:0:0:0:0:0::Doku/Wissen/Themen
#DESCRIPTION Doku/Wissen/Themen
#SERVICE 1:0:1:6DD0:44D:1:C00000:0:0:0:
-#SERVICE 1:0:1:6D6E:437:1:C00000:0:0:0:
#SERVICE 1:0:1:6D6B:437:1:C00000:0:0:0:
#SERVICE 1:0:1:2775:444:1:C00000:0:0:0:
#SERVICE 1:0:1:293:5:85:C00000:0:0:0:
@@ -77,8 +76,6 @@
#SERVICE 1:64:5:0:0:0:0:0:0:0::Reisen
#DESCRIPTION Reisen
#SERVICE 1:0:1:20:21:85:C00000:0:0:0:
-#SERVICE 1:0:1:3339:45B:1:C00000:0:0:0:
-#SERVICE 1:0:1:27B9:444:1:C00000:0:0:0:
#SERVICE 1:64:9:0:0:0:0:0:0:0::Beratung
#DESCRIPTION Beratung
#SERVICE 1:0:1:295:21:85:C00000:0:0:0:
@@ -92,7 +89,6 @@
#SERVICE 1:0:1:36:7:85:C00000:0:0:0:
#SERVICE 1:0:1:307:7:85:C00000:0:0:0:
#SERVICE 1:0:1:296:5:85:C00000:0:0:0:
-#SERVICE 1:0:1:2791:444:1:C00000:0:0:0:
#SERVICE 1:0:1:383:21:85:C00000:0:0:0:
#SERVICE 1:0:1:313C:459:1:C00000:0:0:0:
#SERVICE 1:0:1:3159:459:1:C00000:0:0:0:
@@ -104,9 +100,9 @@
#SERVICE 1:0:19:2B66:3F3:1:C00000:0:0:0:
#SERVICE 1:0:19:2B70:3F3:1:C00000:0:0:0:
#SERVICE 1:0:19:6EEC:4B1:1:C00000:0:0:0:
-#SERVICE 1:0:19:1324:3EF:1:C00000:0:0:0:
-#SERVICE 1:0:19:1325:3EF:1:C00000:0:0:0:
+#SERVICE 1:0:19:EF12:421:1:C00000:0:0:0:
#SERVICE 1:0:19:2B84:3F3:1:C00000:0:0:0:
+#SERVICE 1:0:19:EF13:421:1:C00000:0:0:0:
#SERVICE 1:64:0:0:0:0:0:0:0:0::Alternativen
#DESCRIPTION Alternativen
#SERVICE 1:0:1:6DCB:44D:1:C00000:0:0:0:
diff --git a/data/keymap.xml b/data/keymap.xml
index 25538f87..9461d509 100755
--- a/data/keymap.xml
+++ b/data/keymap.xml
@@ -98,6 +98,10 @@
<key id="KEY_BLUE" mapto="extensions" flags="b" />
</map>
+ <map context="SatlistShortcutAction">
+ <key id="KEY_BLUE" mapto="nothingconnected" flags="b" />
+ </map>
+
<map context="InfobarChannelSelection">
<key id="KEY_LEFT" mapto="zapUp" flags="mr" />
<key id="KEY_RIGHT" mapto="zapDown" flags="mr" />
diff --git a/data/skin_default.xml b/data/skin_default.xml
index 71f579cb..85c4016a 100755
--- a/data/skin_default.xml
+++ b/data/skin_default.xml
@@ -70,8 +70,8 @@
<widget name="menu" position="10,10" size="290,225" scrollbarMode="showOnDemand" />
</screen>
<!-- Channel context menu -->
- <screen name="ChannelContextMenu" position="center,center" size="300,255" title="Channellist menu">
- <widget name="menu" position="10,10" size="290,230" scrollbarMode="showOnDemand" />
+ <screen name="ChannelContextMenu" position="center,center" size="350,255" title="Channellist menu">
+ <widget name="menu" position="10,10" size="340,230" scrollbarMode="showOnDemand" />
</screen>
<!-- Channel selection - TV -->
<screen name="ChannelSelection" position="center,center" size="560,430" title="Channel Selection">
@@ -253,6 +253,10 @@ self.instance.move(ePoint((720-wsizex)/2, (576-wsizey)/(count &gt; 7 and 2 or 3)
<screen name="Dish" flags="wfNoBorder" position="300,100" size="130,160" title="Dish" zPosition="100" backgroundColor="transparent">
<widget name="Dishpixmap" pixmap="skin_default/icons/dish.png" position="0,0" size="130,160" alphatest="off" />
</screen>
+ <!-- unhandled key pressed -->
+ <screen name="UnhandledKey" flags="wfNoBorder" position="620,50" size="34,45" title="UnhandledKey" zPosition="100" backgroundColor="transparent">
+ <widget name="UnhandledKeyPixmap" pixmap="skin_default/unhandled-key.png" position="0,0" size="34,45" alphatest="off" />
+ </screen>
<!-- EPG Selection - Single -->
<screen name="EPGSelection" position="center,center" size="560,430" title="EPG Selection">
<ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
diff --git a/data/skin_default/Makefile.am b/data/skin_default/Makefile.am
index e2d2abcc..9e9b7cd4 100644..100755
--- a/data/skin_default/Makefile.am
+++ b/data/skin_default/Makefile.am
@@ -15,6 +15,7 @@ dist_install_DATA = \
border_eventinfo.png \
border_info.png \
border_menu_300.png \
+ border_menu_350.png \
border_menu.png \
border_multiepg.png \
bottombar.png \
@@ -50,6 +51,7 @@ dist_install_DATA = \
sleeptimer.png \
timeline-now.png \
timeline.png \
+ unhandled-key.png \
verticalline-plugins.png \
vkey_backspace.png \
vkey_bg.png \
diff --git a/data/skin_default/border_menu_350.png b/data/skin_default/border_menu_350.png
new file mode 100755
index 00000000..4f6f49c2
--- /dev/null
+++ b/data/skin_default/border_menu_350.png
Binary files differ
diff --git a/data/skin_default/div-h.png b/data/skin_default/div-h.png
index d6fcc7fb..9ab4ff45 100644..100755
--- a/data/skin_default/div-h.png
+++ b/data/skin_default/div-h.png
Binary files differ
diff --git a/data/skin_default/unhandled-key.png b/data/skin_default/unhandled-key.png
new file mode 100644
index 00000000..8e543498
--- /dev/null
+++ b/data/skin_default/unhandled-key.png
Binary files differ
diff --git a/lib/actions/action.cpp b/lib/actions/action.cpp
index 0eb4cdb1..a2d85ffd 100644
--- a/lib/actions/action.cpp
+++ b/lib/actions/action.cpp
@@ -208,7 +208,7 @@ void eActionMap::keyPressed(const std::string &device, int key, int flags)
}
} else
{
- eDebug("wildcard.");
+// eDebug("wildcard.");
ePyObject pArgs = PyTuple_New(2);
PyTuple_SET_ITEM(pArgs, 0, PyInt_FromLong(key));
PyTuple_SET_ITEM(pArgs, 1, PyInt_FromLong(flags));
diff --git a/lib/base/elock.h b/lib/base/elock.h
index 51582e67..01757182 100644
--- a/lib/base/elock.h
+++ b/lib/base/elock.h
@@ -83,9 +83,18 @@ class eSingleLock
pthread_mutex_t m_lock;
eSingleLock(eSingleLock &);
public:
- eSingleLock()
+ eSingleLock(bool recursive=false)
{
- pthread_mutex_init(&m_lock, 0);
+ if (recursive)
+ {
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+ pthread_mutex_init(&m_lock, &attr);
+ pthread_mutexattr_destroy(&attr);
+ }
+ else
+ pthread_mutex_init(&m_lock, 0);
}
~eSingleLock()
{
diff --git a/lib/driver/rc.cpp b/lib/driver/rc.cpp
index c7acd113..c56fde44 100644
--- a/lib/driver/rc.cpp
+++ b/lib/driver/rc.cpp
@@ -81,7 +81,6 @@ eRCShortDriver::eRCShortDriver(const char *filename): eRCDriver(eRCInput::getIns
{
sn=eSocketNotifier::create(eApp, handle, eSocketNotifier::Read);
CONNECT(sn->activated, eRCShortDriver::keyPressed);
- eRCInput::getInstance()->setFile(handle);
}
}
@@ -115,7 +114,6 @@ eRCInputEventDriver::eRCInputEventDriver(const char *filename): eRCDriver(eRCInp
{
sn=eSocketNotifier::create(eApp, handle, eSocketNotifier::Read);
CONNECT(sn->activated, eRCInputEventDriver::keyPressed);
- eRCInput::getInstance()->setFile(handle);
}
}
@@ -127,6 +125,16 @@ std::string eRCInputEventDriver::getDeviceName()
return name;
}
+void eRCInputEventDriver::setExclusive(bool b)
+{
+ if (handle >= 0)
+ {
+ int grab = b;
+ if (::ioctl(handle, EVIOCGRAB, grab) < 0)
+ perror("EVIOCGRAB");
+ }
+}
+
eRCInputEventDriver::~eRCInputEventDriver()
{
if (handle>=0)
@@ -165,7 +173,6 @@ eRCInput::eRCInput()
{
ASSERT( !instance);
instance=this;
- handle = -1;
locked = 0;
keyboardMode = kmNone;
}
@@ -183,21 +190,18 @@ bool eRCInput::open()
return false;
}
-int eRCInput::lock()
+void eRCInput::lock()
{
locked=1;
- return handle;
+ for (std::map<std::string,eRCDevice*>::iterator i=devices.begin(); i != devices.end(); ++i)
+ i->second->setExclusive(false);
}
void eRCInput::unlock()
{
- if (locked)
- locked=0;
-}
-
-void eRCInput::setFile(int newh)
-{
- handle=newh;
+ locked=0;
+ for (std::map<std::string,eRCDevice*>::iterator i=devices.begin(); i != devices.end(); ++i)
+ i->second->setExclusive(true);
}
void eRCInput::addDevice(const std::string &id, eRCDevice *dev)
@@ -216,7 +220,7 @@ eRCDevice *eRCInput::getDevice(const std::string &id)
if (i == devices.end())
{
eDebug("failed, possible choices are:");
- for (std::map<std::string,eRCDevice*>::iterator i=devices.begin(); i != devices.end(); ++i)
+ for (std::map<std::string,eRCDevice*>::iterator i=devices.begin(); i != devices.end(); ++i)
eDebug("%s", i->first.c_str());
return 0;
}
diff --git a/lib/driver/rc.h b/lib/driver/rc.h
index 9708ea7b..52909468 100644
--- a/lib/driver/rc.h
+++ b/lib/driver/rc.h
@@ -53,6 +53,7 @@ public:
* \param key The key to get the description for.
* \result User readable description of given key.
*/
+ virtual void setExclusive(bool b) { };
};
/**
@@ -89,6 +90,7 @@ public:
~eRCDriver();
void enable(int en) { enabled=en; }
+ virtual void setExclusive(bool) { }
};
class eRCShortDriver: public eRCDriver
@@ -112,6 +114,7 @@ public:
std::string getDeviceName();
eRCInputEventDriver(const char *filename);
~eRCInputEventDriver();
+ void setExclusive(bool b); // in exclusive mode data is not carried to console device
};
class eRCKey
@@ -173,7 +176,6 @@ public:
class eRCInput: public Object
{
int locked;
- int handle;
static eRCInput *instance;
int keyboardMode;
#ifdef SWIG
@@ -199,8 +201,6 @@ public:
void close();
bool open();
- void setFile(int handle);
-
/* This is only relevant for "keyboard"-styled input devices,
i.e. not plain remote controls. It's up to the input device
driver to decide wheter an input device is a keyboard or
@@ -237,7 +237,7 @@ public:
void setKeyboardMode(int mode) { keyboardMode = mode; }
int getKeyboardMode() { return keyboardMode; }
static eRCInput *getInstance() { return instance; }
- int lock();
+ void lock();
void unlock();
int islocked() { return locked; }
};
diff --git a/lib/driver/rcconsole.cpp b/lib/driver/rcconsole.cpp
index bcce5601..eb5aee3d 100644
--- a/lib/driver/rcconsole.cpp
+++ b/lib/driver/rcconsole.cpp
@@ -16,7 +16,6 @@ eRCConsoleDriver::eRCConsoleDriver(const char *filename): eRCDriver(eRCInput::ge
{
sn=eSocketNotifier::create(eApp, handle, eSocketNotifier::Read);
CONNECT(sn->activated, eRCConsoleDriver::keyPressed);
- eRCInput::getInstance()->setFile(handle);
}
/* set console mode */
diff --git a/lib/driver/rcinput.cpp b/lib/driver/rcinput.cpp
index d10d94f3..e593087d 100644
--- a/lib/driver/rcinput.cpp
+++ b/lib/driver/rcinput.cpp
@@ -83,8 +83,13 @@ eRCDeviceInputDev::eRCDeviceInputDev(eRCInputEventDriver *driver)
break;
}
}
+ setExclusive(true);
eDebug("Input device \"%s\" is %sa keyboard.", id.c_str(), iskeyboard ? "" : "not ");
+}
+void eRCDeviceInputDev::setExclusive(bool b)
+{
+ driver->setExclusive(!iskeyboard && b);
}
const char *eRCDeviceInputDev::getDescription() const
diff --git a/lib/driver/rcinput.h b/lib/driver/rcinput.h
index c7f56975..3b4579c5 100644
--- a/lib/driver/rcinput.h
+++ b/lib/driver/rcinput.h
@@ -10,6 +10,7 @@ public:
void handleCode(long code);
eRCDeviceInputDev(eRCInputEventDriver *driver);
const char *getDescription() const;
+ void setExclusive(bool);
};
#endif
diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp
index a8dfb193..6eaadb04 100644
--- a/lib/dvb/dvb.cpp
+++ b/lib/dvb/dvb.cpp
@@ -1766,6 +1766,8 @@ RESULT eDVBChannel::playFile(const char *file)
m_pvr_thread->setStreamMode(1);
m_pvr_thread->setScatterGather(this);
+ m_event(this, evtPreStart);
+
if (m_pvr_thread->start(file, m_pvr_fd_dst))
{
delete m_pvr_thread;
diff --git a/lib/dvb/idvb.h b/lib/dvb/idvb.h
index cff4dbb9..4ef7efad 100644
--- a/lib/dvb/idvb.h
+++ b/lib/dvb/idvb.h
@@ -522,7 +522,7 @@ public:
virtual RESULT getCurrentFrontendParameters(ePtr<iDVBFrontendParameters> &)=0;
enum
{
- evtEOF, evtSOF, evtFailed
+ evtPreStart, evtEOF, evtSOF, evtFailed
};
virtual RESULT connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)=0;
virtual RESULT connectEvent(const Slot2<void,iDVBChannel*,int> &eventChange, ePtr<eConnection> &connection)=0;
diff --git a/lib/dvb/pmt.cpp b/lib/dvb/pmt.cpp
index 9bd065b3..ee89a3a4 100644
--- a/lib/dvb/pmt.cpp
+++ b/lib/dvb/pmt.cpp
@@ -75,6 +75,9 @@ void eDVBServicePMTHandler::channelEvent(iDVBChannel *channel, int event)
{
switch (event)
{
+ case iDVBChannel::evtPreStart:
+ serviceEvent(eventPreStart);
+ break;
case iDVBChannel::evtEOF:
serviceEvent(eventEOF);
break;
diff --git a/lib/dvb/pmt.h b/lib/dvb/pmt.h
index a9ca23f2..483c06b1 100644
--- a/lib/dvb/pmt.h
+++ b/lib/dvb/pmt.h
@@ -123,6 +123,7 @@ public:
eventNewProgramInfo, // we just received a PMT
eventTuned, // a channel was sucessfully (re-)tuned in, you may start additional filters now
+ eventPreStart, // before start filepush thread
eventSOF, // seek pre start
eventEOF, // a file playback did end
diff --git a/lib/dvb/tstools.cpp b/lib/dvb/tstools.cpp
index b7ea945f..d5ad2494 100644
--- a/lib/dvb/tstools.cpp
+++ b/lib/dvb/tstools.cpp
@@ -7,6 +7,7 @@
#include <stdio.h>
eDVBTSTools::eDVBTSTools()
+ :m_file_lock(true)
{
m_pid = -1;
m_maxrange = 256*1024;
@@ -47,6 +48,7 @@ int eDVBTSTools::openFile(const char *filename, int nostreaminfo)
m_samples_taken = 0;
+ eSingleLocker l(m_file_lock);
if (m_file.open(filename, 1) < 0)
return -1;
return 0;
@@ -54,6 +56,7 @@ int eDVBTSTools::openFile(const char *filename, int nostreaminfo)
void eDVBTSTools::closeFile()
{
+ eSingleLocker l(m_file_lock);
m_file.close();
}
@@ -78,7 +81,8 @@ int eDVBTSTools::getPTS(off_t &offset, pts_t &pts, int fixed)
return -1;
offset -= offset % 188;
-
+
+ eSingleLocker l(m_file_lock);
if (m_file.lseek(offset, SEEK_SET) < 0)
{
eDebug("lseek failed");
@@ -144,24 +148,83 @@ int eDVBTSTools::getPTS(off_t &offset, pts_t &pts, int fixed)
} else
payload = packet + 4;
-
/* if (m_pid >= 0)
if (pid != m_pid)
continue; */
if (!pusi)
continue;
-
-
+
/* somehow not a startcode. (this is invalid, since pusi was set.) ignore it. */
if (payload[0] || payload[1] || (payload[2] != 1))
continue;
-
+
+ if (payload[3] == 0xFD)
+ { // stream use extension mechanism defined in ISO 13818-1 Amendment 2
+ if (payload[7] & 1) // PES extension flag
+ {
+ int offs = 0;
+ if (payload[7] & 0x80) // pts avail
+ offs += 5;
+ if (payload[7] & 0x40) // dts avail
+ offs += 5;
+ if (payload[7] & 0x20) // escr avail
+ offs += 6;
+ if (payload[7] & 0x10) // es rate
+ offs += 3;
+ if (payload[7] & 0x8) // dsm trickmode
+ offs += 1;
+ if (payload[7] & 0x4) // additional copy info
+ offs += 1;
+ if (payload[7] & 0x2) // crc
+ offs += 2;
+ if (payload[8] < offs)
+ continue;
+ uint8_t pef = payload[9+offs++]; // pes extension field
+ if (pef & 1) // pes extension flag 2
+ {
+ if (pef & 0x80) // private data flag
+ offs += 16;
+ if (pef & 0x40) // pack header field flag
+ offs += 1;
+ if (pef & 0x20) // program packet sequence counter flag
+ offs += 2;
+ if (pef & 0x10) // P-STD buffer flag
+ offs += 2;
+ if (payload[8] < offs)
+ continue;
+ uint8_t stream_id_extension_len = payload[9+offs++] & 0x7F;
+ if (stream_id_extension_len >= 1)
+ {
+ if (payload[8] < (offs + stream_id_extension_len) )
+ continue;
+ if (payload[9+offs] & 0x80) // stream_id_extension_bit (should not set)
+ continue;
+ switch (payload[9+offs])
+ {
+ case 0x55 ... 0x5f: // VC-1
+ break;
+ case 0x71: // AC3 / DTS
+ break;
+ default:
+ eDebug("skip unknwn stream_id_extension %02x\n", payload[9+offs]);
+ continue;
+ }
+ }
+ else
+ continue;
+ }
+ else
+ continue;
+ }
+ else
+ continue;
+ }
/* drop non-audio, non-video packets because other streams
can be non-compliant.*/
- if (((payload[3] & 0xE0) != 0xC0) && // audio
- ((payload[3] & 0xF0) != 0xE0)) // video
+ else if (((payload[3] & 0xE0) != 0xC0) && // audio
+ ((payload[3] & 0xF0) != 0xE0)) // video
continue;
-
+
if (payload[7] & 0x80) /* PTS */
{
pts = ((unsigned long long)(payload[ 9]&0xE)) << 29;
@@ -358,7 +421,8 @@ void eDVBTSTools::calcEnd()
{
if (!m_file.valid())
return;
-
+
+ eSingleLocker l(m_file_lock);
off_t end = m_file.lseek(0, SEEK_END);
if (llabs(end - m_last_filelength) > 1*1024*1024)
@@ -515,6 +579,7 @@ int eDVBTSTools::findPMT(int &pmt_pid, int &service_id)
return -1;
}
+ eSingleLocker l(m_file_lock);
if (m_file.lseek(0, SEEK_SET) < 0)
{
eDebug("seek failed");
diff --git a/lib/dvb/tstools.h b/lib/dvb/tstools.h
index c230a341..ed8b9241 100644
--- a/lib/dvb/tstools.h
+++ b/lib/dvb/tstools.h
@@ -4,6 +4,7 @@
#include <sys/types.h>
#include <lib/dvb/pvrparse.h>
#include <lib/base/rawfile.h>
+#include <lib/base/elock.h>
/*
* Note: we're interested in PTS values, not STC values.
@@ -75,9 +76,10 @@ public:
private:
int m_pid;
int m_maxrange;
-
+
+ eSingleLock m_file_lock;
eRawFile m_file;
-
+
int m_begin_valid, m_end_valid;
pts_t m_pts_begin, m_pts_end;
off_t m_offset_begin, m_offset_end;
diff --git a/lib/python/Components/ChoiceList.py b/lib/python/Components/ChoiceList.py
index 4700e9e6..33868d61 100755
--- a/lib/python/Components/ChoiceList.py
+++ b/lib/python/Components/ChoiceList.py
@@ -3,7 +3,7 @@ from Tools.Directories import SCOPE_CURRENT_SKIN, resolveFilename
from enigma import RT_HALIGN_LEFT, eListboxPythonMultiContent, gFont
from Tools.LoadPixmap import LoadPixmap
-def ChoiceEntryComponent(key, text):
+def ChoiceEntryComponent(key = "", text = ["--"]):
res = [ text ]
if text[0] == "--":
res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 00, 800, 25, 0, RT_HALIGN_LEFT, "-"*200))
diff --git a/lib/python/Components/NimManager.py b/lib/python/Components/NimManager.py
index 7d148f3c..00d06095 100644
--- a/lib/python/Components/NimManager.py
+++ b/lib/python/Components/NimManager.py
@@ -1213,10 +1213,21 @@ def InitNimManager(nimmgr):
tmp.lnb = lnb
nim.advanced.sat[x] = tmp
+ def toneAmplitudeChanged(configElement):
+ fe_id = configElement.fe_id
+ slot_id = configElement.slot_id
+ if nimmgr.nim_slots[slot_id].description == 'Alps BSBE2':
+ open("/proc/stb/frontend/%d/tone_amplitude" %(fe_id), "w").write(configElement.value)
+
+ empty_slots = 0
for slot in nimmgr.nim_slots:
x = slot.slot
nim = config.Nims[x]
if slot.isCompatible("DVB-S"):
+ nim.toneAmplitude = ConfigSelection([("9", "600mV"), ("8", "700mV"), ("7", "800mV"), ("6", "900mV"), ("5", "1100mV")], "7")
+ nim.toneAmplitude.fe_id = x - empty_slots
+ nim.toneAmplitude.slot_id = x
+ nim.toneAmplitude.addNotifier(toneAmplitudeChanged)
nim.diseqc13V = ConfigYesNo(False)
nim.diseqcMode = ConfigSelection(diseqc_mode_choices, "diseqc_a_b")
nim.connectedTo = ConfigSelection([(str(id), nimmgr.getNimDescription(id)) for id in nimmgr.getNimListOfType("DVB-S") if id != x])
@@ -1306,6 +1317,7 @@ def InitNimManager(nimmgr):
nim.terrestrial = ConfigSelection(choices = list)
nim.terrestrial_5V = ConfigOnOff()
else:
+ empty_slots += 1
nim.configMode = ConfigSelection(choices = { "nothing": _("disabled") }, default="nothing");
if slot.type is not None:
print "pls add support for this frontend type!", slot.type
diff --git a/lib/python/Plugins/Extensions/CutListEditor/plugin.py b/lib/python/Plugins/Extensions/CutListEditor/plugin.py
index efe9f761..abd606d6 100644
--- a/lib/python/Plugins/Extensions/CutListEditor/plugin.py
+++ b/lib/python/Plugins/Extensions/CutListEditor/plugin.py
@@ -195,7 +195,7 @@ class CutListEditor(Screen, InfoBarBase, InfoBarSeek, InfoBarCueSheetSupport, He
self.onClose.append(self.__onClose)
def __onClose(self):
- self.session.nav.playService(self.old_service)
+ self.session.nav.playService(self.old_service, forceRestart=True)
def updateStateLabel(self, state):
self["SeekState"].setText(state[3].strip())
diff --git a/lib/python/Plugins/Extensions/DVDBurn/Process.py b/lib/python/Plugins/Extensions/DVDBurn/Process.py
index 44075d64..642a898d 100644
--- a/lib/python/Plugins/Extensions/DVDBurn/Process.py
+++ b/lib/python/Plugins/Extensions/DVDBurn/Process.py
@@ -264,6 +264,7 @@ class WaitForResidentTasks(Task):
def run(self, callback):
print "waiting for %d resident task(s) %s to finish..." % (len(self.job.resident_tasks),str(self.job.resident_tasks))
+ self.callback = callback
if self.job.resident_tasks == 0:
callback(self, [])
diff --git a/lib/python/Plugins/Extensions/DVDBurn/ProjectSettings.py b/lib/python/Plugins/Extensions/DVDBurn/ProjectSettings.py
index c4289cb0..a1c38842 100755
--- a/lib/python/Plugins/Extensions/DVDBurn/ProjectSettings.py
+++ b/lib/python/Plugins/Extensions/DVDBurn/ProjectSettings.py
@@ -8,7 +8,6 @@ from Components.Sources.List import List
from Components.Sources.StaticText import StaticText
from Components.Sources.Progress import Progress
from Components.FileList import FileList
-from enigma import eListboxPythonMultiContent, gFont, RT_HALIGN_LEFT
from Tools.Directories import fileExists, resolveFilename, SCOPE_PLUGINS, SCOPE_FONTS, SCOPE_HDD
from Components.config import config, getConfigListEntry
from Components.ConfigList import ConfigListScreen
@@ -235,7 +234,6 @@ class ProjectSettings(Screen,ConfigListScreen):
self.session.open(MessageBox,self.project.error,MessageBox.TYPE_ERROR)
elif scope == "project":
if self.project.loadProject(path):
- configRef.setValue(path)
self.initConfigList()
else:
self.session.open(MessageBox,self.project.error,MessageBox.TYPE_ERROR)
diff --git a/lib/python/Plugins/Extensions/DVDBurn/TitleList.py b/lib/python/Plugins/Extensions/DVDBurn/TitleList.py
index 928a8b82..dbc988b1 100755
--- a/lib/python/Plugins/Extensions/DVDBurn/TitleList.py
+++ b/lib/python/Plugins/Extensions/DVDBurn/TitleList.py
@@ -10,7 +10,8 @@ from Components.ActionMap import HelpableActionMap, ActionMap
from Components.Sources.List import List
from Components.Sources.StaticText import StaticText
from Components.Sources.Progress import Progress
-from enigma import eListboxPythonMultiContent, gFont, RT_HALIGN_LEFT
+from Components.MultiContent import MultiContentEntryText
+from enigma import gFont, RT_HALIGN_LEFT, RT_HALIGN_RIGHT
from Tools.Directories import resolveFilename, SCOPE_PLUGINS
class TitleList(Screen, HelpableScreen):
@@ -27,7 +28,18 @@ class TitleList(Screen, HelpableScreen):
<widget source="title_label" render="Label" position="10,48" size="540,38" font="Regular;18" transparent="1" />
<widget source="error_label" render="Label" position="10,48" size="540,395" zPosition="3" font="Regular;20" transparent="1" />
<widget source="titles" render="Listbox" scrollbarMode="showOnDemand" position="10,86" size="540,312" zPosition="3" transparent="1" >
- <convert type="StaticMultiList" />
+ <convert type="TemplatedMultiContent">
+ {"template": [
+ MultiContentEntryText(pos = (0, 0), size = (420, 20), font = 0, flags = RT_HALIGN_LEFT, text = 1), # index 1 Title,
+ MultiContentEntryText(pos = (0, 20), size = (328, 17), font = 1, flags = RT_HALIGN_LEFT, text = 2), # index 2 description,
+ MultiContentEntryText(pos = (420, 6), size = (120, 20), font = 1, flags = RT_HALIGN_RIGHT, text = 3), # index 3 begin time,
+ MultiContentEntryText(pos = (328, 20), size = (154, 17), font = 1, flags = RT_HALIGN_RIGHT, text = 4), # index 4 channel,
+ MultiContentEntryText(pos = (482, 20), size = (58, 20), font = 1, flags = RT_HALIGN_RIGHT, text = 5), # index 4 channel,
+ ],
+ "fonts": [gFont("Regular", 20), gFont("Regular", 14)],
+ "itemHeight": 37
+ }
+ </convert>
</widget>
<widget source="space_bar" render="Progress" position="10,410" size="540,26" borderWidth="1" backgroundColor="#254f7497" />
<widget source="space_label" render="Label" position="40,414" size="480,22" zPosition="2" font="Regular;18" halign="center" transparent="1" foregroundColor="#000000" />
@@ -71,7 +83,7 @@ class TitleList(Screen, HelpableScreen):
else:
self.newProject()
- self["titles"] = List(list = [ ], enableWrapAround = True, item_height=30, fonts = [gFont("Regular", 20)])
+ self["titles"] = List([])
self.updateTitleList()
self.previous_size = 0
self.onLayoutFinish.append(self.layoutFinished)
@@ -188,6 +200,9 @@ class TitleList(Screen, HelpableScreen):
def selectedSource(self, source):
if source is None:
return None
+ if not source.getPath().endswith(".ts"):
+ self.session.open(MessageBox,text = _("You can only burn Dreambox recordings!"), type = MessageBox.TYPE_ERROR)
+ return None
t = self.project.addService(source)
try:
editor = source.edit
@@ -256,15 +271,14 @@ class TitleList(Screen, HelpableScreen):
job = Process.DVDJob(self.project, menupreview=True)
job_manager.in_background = False
job_manager.AddJob(job)
-
+
def updateTitleList(self):
- res = [ ]
+ list = [ ]
for title in self.project.titles:
- a = [ title, (eListboxPythonMultiContent.TYPE_TEXT, 0, 5, 500, 25, 0, RT_HALIGN_LEFT, title.properties.menutitle.getValue()) ]
- res.append(a)
- self["titles"].list = res
+ list.append((title, title.properties.menutitle.getValue(), title.properties.menusubtitle.getValue(), title.DVBchannel, title.formatDVDmenuText("$D.$M.$Y, $T", 0), title.formatDVDmenuText("$l", 0)))
+ self["titles"].list = list
self.updateSize()
- if len(res):
+ if len(list):
self["key_red"].text = _("Remove title")
self["key_yellow"].text = _("Title properties")
else:
diff --git a/lib/python/Plugins/Extensions/DVDBurn/TitleProperties.py b/lib/python/Plugins/Extensions/DVDBurn/TitleProperties.py
index 11601cc3..0a664eba 100755
--- a/lib/python/Plugins/Extensions/DVDBurn/TitleProperties.py
+++ b/lib/python/Plugins/Extensions/DVDBurn/TitleProperties.py
@@ -9,7 +9,7 @@ from Components.Sources.StaticText import StaticText
from Components.Sources.Progress import Progress
from Components.FileList import FileList
from Components.Pixmap import Pixmap
-from enigma import eListboxPythonMultiContent, gFont, RT_HALIGN_LEFT, ePicLoad
+from enigma import ePicLoad
from Tools.Directories import fileExists, resolveFilename, SCOPE_PLUGINS, SCOPE_FONTS, SCOPE_HDD
from Components.config import config, getConfigListEntry, ConfigInteger, ConfigSubsection, ConfigSelection
from Components.ConfigList import ConfigListScreen
@@ -164,7 +164,8 @@ class LanguageChoices():
self.choices.sort()
self.choices.insert(0,("nolang", ("unspecified")))
self.choices.insert(1,(syslang, self.langdict[syslang]))
- self.choices.insert(2,("en", self.langdict["en"]))
+ if syslang != "en":
+ self.choices.insert(2,("en", self.langdict["en"]))
def getLanguage(self, DVB_lang):
DVB_lang = DVB_lang.lower()
diff --git a/lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.cpp b/lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.cpp
index 94f2ee38..0372c497 100644
--- a/lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.cpp
+++ b/lib/python/Plugins/Extensions/DVDPlayer/src/servicedvd.cpp
@@ -696,7 +696,7 @@ RESULT eServiceDVD::setTrickmode(int /*trick*/)
RESULT eServiceDVD::isCurrentlySeekable()
{
- return m_state == stRunning;
+ return m_state == stRunning ? 3 : 0;
}
RESULT eServiceDVD::keyPressed(int key)
diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/Makefile.am b/lib/python/Plugins/SystemPlugins/SoftwareManager/Makefile.am
index ee1e56de..2d5e3381 100644..100755
--- a/lib/python/Plugins/SystemPlugins/SoftwareManager/Makefile.am
+++ b/lib/python/Plugins/SystemPlugins/SoftwareManager/Makefile.am
@@ -6,7 +6,8 @@ install_PYTHON = \
__init__.py \
plugin.py \
BackupRestore.py \
- ImageWizard.py
+ ImageWizard.py \
+ SoftwareTools.py
dist_install_DATA = \
imagewizard.xml \
diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/SoftwareTools.py b/lib/python/Plugins/SystemPlugins/SoftwareManager/SoftwareTools.py
new file mode 100755
index 00000000..4e7591ef
--- /dev/null
+++ b/lib/python/Plugins/SystemPlugins/SoftwareManager/SoftwareTools.py
@@ -0,0 +1,226 @@
+from enigma import eConsoleAppContainer
+from Components.Console import Console
+from Components.About import about
+from Components.DreamInfoHandler import DreamInfoHandler
+from Components.Language import language
+from Components.Sources.List import List
+from Components.Ipkg import IpkgComponent
+from Components.Network import iNetwork
+from Tools.Directories import pathExists, fileExists, resolveFilename, SCOPE_METADIR
+
+from time import time
+
+class SoftwareTools(DreamInfoHandler):
+ lastDownloadDate = None
+ NetworkConnectionAvailable = None
+ list_updating = False
+ available_updates = 0
+ available_updatelist = []
+ available_packetlist = []
+ installed_packetlist = {}
+
+
+ def __init__(self):
+ aboutInfo = about.getImageVersionString()
+ if aboutInfo.startswith("dev-"):
+ self.ImageVersion = 'Experimental'
+ else:
+ self.ImageVersion = 'Stable'
+ self.language = language.getLanguage()[:2] # getLanguage returns e.g. "fi_FI" for "language_country"
+ DreamInfoHandler.__init__(self, self.statusCallback, blocking = False, neededTag = 'ALL_TAGS', neededFlag = self.ImageVersion, language = self.language)
+ self.directory = resolveFilename(SCOPE_METADIR)
+ self.list = List([])
+ self.NotifierCallback = None
+ self.Console = Console()
+ self.UpdateConsole = Console()
+ self.cmdList = []
+ self.unwanted_extensions = ('-dbg', '-dev', '-doc')
+ self.ipkg = IpkgComponent()
+ self.ipkg.addCallback(self.ipkgCallback)
+
+ def statusCallback(self, status, progress):
+ pass
+
+ def startSoftwareTools(self, callback = None):
+ if callback is not None:
+ self.NotifierCallback = callback
+ iNetwork.checkNetworkState(self.checkNetworkCB)
+
+ def checkNetworkCB(self,data):
+ if data is not None:
+ if data <= 2:
+ SoftwareTools.NetworkConnectionAvailable = True
+ self.getUpdates()
+ else:
+ SoftwareTools.NetworkConnectionAvailable = False
+ self.getUpdates()
+
+ def getUpdates(self, callback = None):
+ if SoftwareTools.NetworkConnectionAvailable == True:
+ SoftwareTools.lastDownloadDate = time()
+ if SoftwareTools.list_updating is False and callback is None:
+ SoftwareTools.list_updating = True
+ self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
+ elif SoftwareTools.list_updating is False and callback is not None:
+ SoftwareTools.list_updating = True
+ self.NotifierCallback = callback
+ self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
+ elif SoftwareTools.list_updating is True and callback is not None:
+ #update info collecting already in progress
+ self.NotifierCallback = callback
+ else:
+ SoftwareTools.list_updating = False
+ if callback is not None:
+ callback(False)
+ elif self.NotifierCallback is not None:
+ self.NotifierCallback(False)
+
+ def ipkgCallback(self, event, param):
+ if event == IpkgComponent.EVENT_ERROR:
+ SoftwareTools.list_updating = False
+ elif event == IpkgComponent.EVENT_DONE:
+ if SoftwareTools.list_updating:
+ self.startIpkgListAvailable()
+ pass
+
+ def startIpkgListAvailable(self, callback = None):
+ if callback is not None:
+ SoftwareTools.list_updating = True
+ if SoftwareTools.list_updating:
+ if not self.UpdateConsole:
+ self.UpdateConsole = Console()
+ cmd = "ipkg list"
+ self.UpdateConsole.ePopen(cmd, self.IpkgListAvailableCB, callback)
+
+ def IpkgListAvailableCB(self, result, retval, extra_args = None):
+ (callback) = extra_args
+ if len(result):
+ if SoftwareTools.list_updating:
+ SoftwareTools.available_packetlist = []
+ for x in result.splitlines():
+ split = x.split(' - ')
+ name = split[0].strip()
+ if not any(name.endswith(x) for x in self.unwanted_extensions):
+ SoftwareTools.available_packetlist.append([name, split[1].strip(), split[2].strip()])
+ if callback is None:
+ self.startInstallMetaPackage()
+ else:
+ if self.UpdateConsole:
+ if len(self.UpdateConsole.appContainers) == 0:
+ callback(True)
+ else:
+ SoftwareTools.list_updating = False
+ if self.UpdateConsole:
+ if len(self.UpdateConsole.appContainers) == 0:
+ if callback is not None:
+ callback(False)
+
+ def startInstallMetaPackage(self, callback = None):
+ if callback is not None:
+ SoftwareTools.list_updating = True
+ if SoftwareTools.list_updating:
+ if not self.UpdateConsole:
+ self.UpdateConsole = Console()
+ cmd = "ipkg install enigma2-meta enigma2-plugins-meta enigma2-skins-meta"
+ self.UpdateConsole.ePopen(cmd, self.InstallMetaPackageCB, callback)
+
+ def InstallMetaPackageCB(self, result, retval, extra_args = None):
+ (callback) = extra_args
+ if len(result):
+ self.fillPackagesIndexList()
+ if callback is None:
+ self.startIpkgListInstalled()
+ else:
+ if self.UpdateConsole:
+ if len(self.UpdateConsole.appContainers) == 0:
+ callback(True)
+ else:
+ SoftwareTools.list_updating = False
+ if self.UpdateConsole:
+ if len(self.UpdateConsole.appContainers) == 0:
+ if callback is not None:
+ callback(False)
+
+ def startIpkgListInstalled(self, callback = None):
+ if callback is not None:
+ SoftwareTools.list_updating = True
+ if SoftwareTools.list_updating:
+ if not self.UpdateConsole:
+ self.UpdateConsole = Console()
+ cmd = "ipkg list_installed"
+ self.UpdateConsole.ePopen(cmd, self.IpkgListInstalledCB, callback)
+
+ def IpkgListInstalledCB(self, result, retval, extra_args = None):
+ (callback) = extra_args
+ if len(result):
+ SoftwareTools.installed_packetlist = {}
+ for x in result.splitlines():
+ split = x.split(' - ')
+ name = split[0].strip()
+ if not any(name.endswith(x) for x in self.unwanted_extensions):
+ SoftwareTools.installed_packetlist[name] = split[1].strip()
+ if callback is None:
+ self.countUpdates()
+ else:
+ if self.UpdateConsole:
+ if len(self.UpdateConsole.appContainers) == 0:
+ callback(True)
+ else:
+ SoftwareTools.list_updating = False
+ if self.UpdateConsole:
+ if len(self.UpdateConsole.appContainers) == 0:
+ if callback is not None:
+ callback(False)
+
+ def countUpdates(self, callback = None):
+ SoftwareTools.available_updates = 0
+ SoftwareTools.available_updatelist = []
+ for package in self.packagesIndexlist[:]:
+ attributes = package[0]["attributes"]
+ packagename = attributes["packagename"]
+ for x in SoftwareTools.available_packetlist:
+ if x[0] == packagename:
+ if SoftwareTools.installed_packetlist.has_key(packagename):
+ if SoftwareTools.installed_packetlist[packagename] != x[1]:
+ SoftwareTools.available_updates +=1
+ SoftwareTools.available_updatelist.append([packagename])
+
+ SoftwareTools.list_updating = False
+ if self.UpdateConsole:
+ if len(self.UpdateConsole.appContainers) == 0:
+ if callback is not None:
+ callback(True)
+ callback = None
+ elif self.NotifierCallback is not None:
+ self.NotifierCallback(True)
+ self.NotifierCallback = None
+
+ def startIpkgUpdate(self, callback = None):
+ if not self.Console:
+ self.Console = Console()
+ cmd = "ipkg update"
+ self.Console.ePopen(cmd, self.IpkgUpdateCB, callback)
+
+ def IpkgUpdateCB(self, result, retval, extra_args = None):
+ (callback) = extra_args
+ if len(result):
+ if self.Console:
+ if len(self.Console.appContainers) == 0:
+ if callback is not None:
+ callback(True)
+ callback = None
+
+ def cleanupSoftwareTools(self):
+ if self.NotifierCallback is not None:
+ self.NotifierCallback = None
+ self.ipkg.stop()
+ if self.Console is not None:
+ if len(self.Console.appContainers):
+ for name in self.Console.appContainers.keys():
+ self.Console.kill(name)
+ if self.UpdateConsole is not None:
+ if len(self.UpdateConsole.appContainers):
+ for name in self.UpdateConsole.appContainers.keys():
+ self.UpdateConsole.kill(name)
+
+iSoftwareTools = SoftwareTools() \ No newline at end of file
diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/plugin.py b/lib/python/Plugins/SystemPlugins/SoftwareManager/plugin.py
index c70201b3..f61ea53c 100755
--- a/lib/python/Plugins/SystemPlugins/SoftwareManager/plugin.py
+++ b/lib/python/Plugins/SystemPlugins/SoftwareManager/plugin.py
@@ -23,6 +23,7 @@ from Components.About import about
from Components.DreamInfoHandler import DreamInfoHandler
from Components.Language import language
from Components.AVSwitch import AVSwitch
+from Components.Network import iNetwork
from Tools.Directories import pathExists, fileExists, resolveFilename, SCOPE_PLUGINS, SCOPE_CURRENT_PLUGIN, SCOPE_CURRENT_SKIN, SCOPE_METADIR
from Tools.LoadPixmap import LoadPixmap
from enigma import eTimer, quitMainloop, RT_HALIGN_LEFT, RT_VALIGN_CENTER, eListboxPythonMultiContent, eListbox, gFont, getDesktop, ePicLoad
@@ -36,6 +37,7 @@ from twisted.internet import reactor
from ImageWizard import ImageWizard
from BackupRestore import BackupSelection, RestoreMenu, BackupScreen, RestoreScreen, getBackupPath, getBackupFilename
+from SoftwareTools import iSoftwareTools
config.plugins.configurationbackup = ConfigSubsection()
config.plugins.configurationbackup.backuplocation = ConfigText(default = '/media/hdd/', visible_width = 50, fixed_size = False)
@@ -74,30 +76,31 @@ def load_cache(cache_file):
class UpdatePluginMenu(Screen):
skin = """
- <screen name="UpdatePluginMenu" position="center,center" size="560,400" title="Software manager" >
+ <screen name="UpdatePluginMenu" position="center,center" size="610,410" title="Software management" >
<ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
<widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
- <ePixmap pixmap="skin_default/border_menu_300.png" position="5,50" zPosition="1" size="300,300" transparent="1" alphatest="on" />
- <widget source="menu" render="Listbox" position="10,60" size="290,260" scrollbarMode="showOnDemand">
+ <ePixmap pixmap="skin_default/border_menu_350.png" position="5,50" zPosition="1" size="350,300" transparent="1" alphatest="on" />
+ <widget source="menu" render="Listbox" position="15,60" size="330,290" scrollbarMode="showOnDemand">
<convert type="TemplatedMultiContent">
{"template": [
- MultiContentEntryText(pos = (2, 2), size = (290, 22), flags = RT_HALIGN_LEFT, text = 1), # index 0 is the MenuText,
+ MultiContentEntryText(pos = (2, 2), size = (330, 24), flags = RT_HALIGN_LEFT, text = 1), # index 0 is the MenuText,
],
- "fonts": [gFont("Regular", 20)],
+ "fonts": [gFont("Regular", 22)],
"itemHeight": 25
}
</convert>
</widget>
- <widget source="menu" render="Listbox" position="310,50" size="240,300" scrollbarMode="showNever" selectionDisabled="1">
+ <widget source="menu" render="Listbox" position="360,50" size="240,300" scrollbarMode="showNever" selectionDisabled="1">
<convert type="TemplatedMultiContent">
{"template": [
MultiContentEntryText(pos = (2, 2), size = (240, 300), flags = RT_HALIGN_CENTER|RT_VALIGN_CENTER|RT_WRAP, text = 2), # index 2 is the Description,
],
- "fonts": [gFont("Regular", 20)],
+ "fonts": [gFont("Regular", 22)],
"itemHeight": 300
}
</convert>
</widget>
+ <widget source="status" render="Label" position="5,360" zPosition="10" size="600,50" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
</screen>"""
def __init__(self, session, args = 0):
@@ -106,14 +109,15 @@ class UpdatePluginMenu(Screen):
self.menu = args
self.list = []
self.oktext = _("\nPress OK on your remote control to continue.")
+ self.text = ""
self.backupdirs = ' '.join( config.plugins.configurationbackup.backupdirs.value )
if self.menu == 0:
+ self.list.append(("install-extensions", _("Manage extensions"), _("\nManage extensions or plugins for your Dreambox" ) + self.oktext, None))
self.list.append(("software-update", _("Software update"), _("\nOnline update of your Dreambox software." ) + self.oktext, None))
- #self.list.append(("install-plugins", _("Install extensions"), _("\nInstall new Extensions or Plugins to your dreambox" ) + self.oktext, None))
self.list.append(("software-restore", _("Software restore"), _("\nRestore your Dreambox with a new firmware." ) + self.oktext, None))
self.list.append(("system-backup", _("Backup system settings"), _("\nBackup your Dreambox settings." ) + self.oktext, None))
self.list.append(("system-restore",_("Restore system settings"), _("\nRestore your Dreambox settings." ) + self.oktext, None))
- self.list.append(("ipkg-install", _("Install local extension"), _("\nScan for local packages and install them." ) + self.oktext, None))
+ self.list.append(("ipkg-install", _("Install local extension"), _("\nScan for local extensions and install them." ) + self.oktext, None))
for p in plugins.getPlugins(PluginDescriptor.WHERE_SOFTWAREMANAGER):
if p.__call__.has_key("SoftwareSupported"):
callFnc = p.__call__["SoftwareSupported"](None)
@@ -133,8 +137,8 @@ class UpdatePluginMenu(Screen):
self.list.append(("advancedrestore", _("Advanced restore"), _("\nRestore your backups by date." ) + self.oktext, None))
self.list.append(("backuplocation", _("Choose backup location"), _("\nSelect your backup device.\nCurrent device: " ) + config.plugins.configurationbackup.backuplocation.value + self.oktext, None))
self.list.append(("backupfiles", _("Choose backup files"), _("Select files for backup. Currently selected:\n" ) + self.backupdirs + self.oktext, None))
- if config.usage.setup_level.index >= 2: # expert+
- self.list.append(("ipkg-manager", _("Packet management"), _("\nView, install and remove available or installed packages." ) + self.oktext, None))
+ #if config.usage.setup_level.index >= 2: # expert+
+ # self.list.append(("ipkg-manager", _("Packet management"), _("\nView, install and remove available or installed packages." ) + self.oktext, None))
self.list.append(("ipkg-source",_("Choose upgrade source"), _("\nEdit the upgrade source address." ) + self.oktext, None))
for p in plugins.getPlugins(PluginDescriptor.WHERE_SOFTWAREMANAGER):
if p.__call__.has_key("AdvancedSoftwareSupported"):
@@ -152,28 +156,54 @@ class UpdatePluginMenu(Screen):
self["menu"] = List(self.list)
self["key_red"] = StaticText(_("Close"))
+ self["status"] = StaticText("")
- self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
+ self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions", "InfobarEPGActions"],
{
"ok": self.go,
"back": self.close,
"red": self.close,
}, -1)
-
self.onLayoutFinish.append(self.layoutFinished)
self.backuppath = getBackupPath()
self.backupfile = getBackupFilename()
self.fullbackupfilename = self.backuppath + "/" + self.backupfile
self.onShown.append(self.setWindowTitle)
+ #self.onClose.append(self.cleanup)
def layoutFinished(self):
idx = 0
self["menu"].index = idx
+ #self.getUpdateInfos()
def setWindowTitle(self):
- self.setTitle(_("Software manager"))
+ self.setTitle(_("Software management"))
+
+ def cleanup(self):
+ iNetwork.stopPingConsole()
+ iSoftwareTools.cleanupSoftwareTools()
+
+ def getUpdateInfos(self):
+ self.text = ""
+ if iSoftwareTools.NetworkConnectionAvailable == True:
+ if iSoftwareTools.list_updating is False:
+ if iSoftwareTools.available_updates is not 0:
+ self.text = _("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available.")
+ else:
+ self.text = "" #_("There are no updates available.")
+ else:
+ if iSoftwareTools.available_updates is not 0:
+ self.text = _("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available.")
+ else:
+ self.text = "" #_("There are no updates available.")
+ self.text += "\n" + _("A search for available updates is currently in progress.")
+ else:
+ self.text = _("No network connection available.")
+ self["status"].setText(self.text)
+
def go(self):
+ #iNetwork.stopPingConsole()
current = self["menu"].getCurrent()
if current:
currentEntry = current[0]
@@ -182,7 +212,7 @@ class UpdatePluginMenu(Screen):
self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to update your Dreambox?")+"\n"+_("\nAfter pressing OK, please wait!"))
elif (currentEntry == "software-restore"):
self.session.open(ImageWizard)
- elif (currentEntry == "install-plugins"):
+ elif (currentEntry == "install-extensions"):
self.session.open(PluginManager, self.skin_path)
elif (currentEntry == "system-backup"):
self.session.openWithCallback(self.backupDone,BackupScreen, runBackup = True)
@@ -260,433 +290,11 @@ class UpdatePluginMenu(Screen):
self.exe = True
self.session.open(RestoreScreen, runRestore = True)
-class IPKGMenu(Screen):
- skin = """
- <screen name="IPKGMenu" position="center,center" size="560,400" title="Select upgrade source to edit." >
- <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
- <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
- <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
- <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
- <widget name="filelist" position="5,50" size="550,340" scrollbarMode="showOnDemand" />
- </screen>"""
-
- def __init__(self, session, plugin_path):
- Screen.__init__(self, session)
- self.skin_path = plugin_path
-
- self["key_red"] = StaticText(_("Close"))
- self["key_green"] = StaticText(_("Edit"))
-
- self.sel = []
- self.val = []
- self.entry = False
- self.exe = False
-
- self.path = ""
-
- self["actions"] = NumberActionMap(["SetupActions"],
- {
- "ok": self.KeyOk,
- "cancel": self.keyCancel
- }, -1)
-
- self["shortcuts"] = ActionMap(["ShortcutActions"],
- {
- "red": self.keyCancel,
- "green": self.KeyOk,
- })
- self.flist = []
- self["filelist"] = MenuList(self.flist)
- self.fill_list()
- self.onLayoutFinish.append(self.layoutFinished)
-
- def layoutFinished(self):
- self.setWindowTitle()
-
- def setWindowTitle(self):
- self.setTitle(_("Select upgrade source to edit."))
-
- def fill_list(self):
- self.flist = []
- self.path = '/etc/ipkg/'
- if (os_path.exists(self.path) == False):
- self.entry = False
- return
- for file in listdir(self.path):
- if (file.endswith(".conf")):
- if file != 'arch.conf':
- self.flist.append((file))
- self.entry = True
- self["filelist"].l.setList(self.flist)
-
- def KeyOk(self):
- if (self.exe == False) and (self.entry == True):
- self.sel = self["filelist"].getCurrent()
- self.val = self.path + self.sel
- self.session.open(IPKGSource, self.val)
-
- def keyCancel(self):
- self.close()
-
- def Exit(self):
- self.close()
-
-
-class IPKGSource(Screen):
- skin = """
- <screen name="IPKGSource" position="center,center" size="560,80" title="Edit upgrade source url." >
- <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
- <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
- <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
- <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
- <widget name="text" position="5,50" size="550,25" font="Regular;20" backgroundColor="background" foregroundColor="#cccccc" />
- </screen>"""
-
- def __init__(self, session, configfile = None):
- Screen.__init__(self, session)
- self.session = session
- self.configfile = configfile
- text = ""
- if self.configfile:
- try:
- fp = file(configfile, 'r')
- sources = fp.readlines()
- if sources:
- text = sources[0]
- fp.close()
- except IOError:
- pass
-
- desk = getDesktop(0)
- x= int(desk.size().width())
- y= int(desk.size().height())
-
- self["key_red"] = StaticText(_("Cancel"))
- self["key_green"] = StaticText(_("Save"))
-
- if (y>=720):
- self["text"] = Input(text, maxSize=False, type=Input.TEXT)
- else:
- self["text"] = Input(text, maxSize=False, visible_width = 55, type=Input.TEXT)
-
- self["actions"] = NumberActionMap(["WizardActions", "InputActions", "TextEntryActions", "KeyboardInputActions","ShortcutActions"],
- {
- "ok": self.go,
- "back": self.close,
- "red": self.close,
- "green": self.go,
- "left": self.keyLeft,
- "right": self.keyRight,
- "home": self.keyHome,
- "end": self.keyEnd,
- "deleteForward": self.keyDeleteForward,
- "deleteBackward": self.keyDeleteBackward,
- "1": self.keyNumberGlobal,
- "2": self.keyNumberGlobal,
- "3": self.keyNumberGlobal,
- "4": self.keyNumberGlobal,
- "5": self.keyNumberGlobal,
- "6": self.keyNumberGlobal,
- "7": self.keyNumberGlobal,
- "8": self.keyNumberGlobal,
- "9": self.keyNumberGlobal,
- "0": self.keyNumberGlobal
- }, -1)
-
- self.onLayoutFinish.append(self.layoutFinished)
-
- def layoutFinished(self):
- self.setWindowTitle()
- self["text"].right()
-
- def setWindowTitle(self):
- self.setTitle(_("Edit upgrade source url."))
-
- def go(self):
- text = self["text"].getText()
- if text:
- fp = file(self.configfile, 'w')
- fp.write(text)
- fp.write("\n")
- fp.close()
- self.close()
-
- def keyLeft(self):
- self["text"].left()
-
- def keyRight(self):
- self["text"].right()
-
- def keyHome(self):
- self["text"].home()
-
- def keyEnd(self):
- self["text"].end()
-
- def keyDeleteForward(self):
- self["text"].delete()
-
- def keyDeleteBackward(self):
- self["text"].deleteBackward()
-
- def keyNumberGlobal(self, number):
- self["text"].number(number)
-
-
-class PacketManager(Screen):
- skin = """
- <screen name="PacketManager" position="center,center" size="530,420" title="Packet manager" >
- <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
- <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
- <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
- <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
- <widget source="list" render="Listbox" position="5,50" size="520,365" scrollbarMode="showOnDemand">
- <convert type="TemplatedMultiContent">
- {"template": [
- MultiContentEntryText(pos = (5, 1), size = (440, 28), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
- MultiContentEntryText(pos = (5, 26), size = (440, 20), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is the description
- MultiContentEntryPixmapAlphaTest(pos = (445, 2), size = (48, 48), png = 4), # index 4 is the status pixmap
- MultiContentEntryPixmapAlphaTest(pos = (5, 50), size = (510, 2), png = 5), # index 4 is the div pixmap
- ],
- "fonts": [gFont("Regular", 22),gFont("Regular", 14)],
- "itemHeight": 52
- }
- </convert>
- </widget>
- </screen>"""
-
- def __init__(self, session, plugin_path, args = None):
- Screen.__init__(self, session)
- self.session = session
- self.skin_path = plugin_path
-
- self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
- {
- "ok": self.go,
- "back": self.exit,
- "red": self.exit,
- "green": self.reload,
- }, -1)
-
- self.list = []
- self.statuslist = []
- self["list"] = List(self.list)
- self["key_red"] = StaticText(_("Close"))
- self["key_green"] = StaticText(_("Reload"))
-
- self.list_updating = True
- self.packetlist = []
- self.installed_packetlist = {}
- self.Console = Console()
- self.cmdList = []
- self.cachelist = []
- self.cache_ttl = 86400 #600 is default, 0 disables, Seconds cache is considered valid (24h should be ok for caching ipkgs)
- self.cache_file = '/usr/lib/enigma2/python/Plugins/SystemPlugins/SoftwareManager/packetmanager.cache' #Path to cache directory
- self.oktext = _("\nAfter pressing OK, please wait!")
- self.unwanted_extensions = ('-dbg', '-dev', '-doc', 'busybox')
-
- self.ipkg = IpkgComponent()
- self.ipkg.addCallback(self.ipkgCallback)
- self.onShown.append(self.setWindowTitle)
- self.onLayoutFinish.append(self.rebuildList)
-
- def exit(self):
- self.ipkg.stop()
- if self.Console is not None:
- if len(self.Console.appContainers):
- for name in self.Console.appContainers.keys():
- self.Console.kill(name)
- self.close()
-
- def reload(self):
- if (os_path.exists(self.cache_file) == True):
- remove(self.cache_file)
- self.list_updating = True
- self.rebuildList()
-
- def setWindowTitle(self):
- self.setTitle(_("Packet manager"))
-
- def setStatus(self,status = None):
- if status:
- self.statuslist = []
- divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
- if status == 'update':
- statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
- self.statuslist.append(( _("Package list update"), '', _("Trying to download a new packetlist. Please wait..." ),'',statuspng, divpng ))
- self['list'].setList(self.statuslist)
- elif status == 'error':
- statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
- self.statuslist.append(( _("Error"), '', _("There was an error downloading the packetlist. Please try again." ),'',statuspng, divpng ))
- self['list'].setList(self.statuslist)
-
- def rebuildList(self):
- self.setStatus('update')
- self.inv_cache = 0
- self.vc = valid_cache(self.cache_file, self.cache_ttl)
- if self.cache_ttl > 0 and self.vc != 0:
- try:
- self.buildPacketList()
- except:
- self.inv_cache = 1
- if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
- self.run = 0
- self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
-
- def go(self, returnValue = None):
- cur = self["list"].getCurrent()
- if cur:
- status = cur[3]
- package = cur[0]
- self.cmdList = []
- if status == 'installed':
- self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package }))
- if len(self.cmdList):
- self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n") + package + "\n" + self.oktext)
- elif status == 'upgradeable':
- self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package }))
- if len(self.cmdList):
- self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to upgrade the package:\n") + package + "\n" + self.oktext)
- elif status == "installable":
- self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package }))
- if len(self.cmdList):
- self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n") + package + "\n" + self.oktext)
-
- def runRemove(self, result):
- if result:
- self.session.openWithCallback(self.runRemoveFinished, Ipkg, cmdList = self.cmdList)
-
- def runRemoveFinished(self):
- self.session.openWithCallback(self.RemoveReboot, MessageBox, _("Remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
-
- def RemoveReboot(self, result):
- if result is None:
- return
- if result is False:
- cur = self["list"].getCurrent()
- if cur:
- item = self['list'].getIndex()
- self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installable')
- self.cachelist[item] = [cur[0], cur[1], cur[2], 'installable']
- self['list'].setList(self.list)
- write_cache(self.cache_file, self.cachelist)
- self.reloadPluginlist()
- if result:
- quitMainloop(3)
-
- def runUpgrade(self, result):
- if result:
- self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList = self.cmdList)
-
- def runUpgradeFinished(self):
- self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
-
- def UpgradeReboot(self, result):
- if result is None:
- return
- if result is False:
- cur = self["list"].getCurrent()
- if cur:
- item = self['list'].getIndex()
- self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installed')
- self.cachelist[item] = [cur[0], cur[1], cur[2], 'installed']
- self['list'].setList(self.list)
- write_cache(self.cache_file, self.cachelist)
- self.reloadPluginlist()
- if result:
- quitMainloop(3)
-
- def ipkgCallback(self, event, param):
- if event == IpkgComponent.EVENT_ERROR:
- self.list_updating = False
- self.setStatus('error')
- elif event == IpkgComponent.EVENT_DONE:
- if self.list_updating:
- self.list_updating = False
- if not self.Console:
- self.Console = Console()
- cmd = "ipkg list"
- self.Console.ePopen(cmd, self.IpkgList_Finished)
- #print event, "-", param
- pass
-
- def IpkgList_Finished(self, result, retval, extra_args = None):
- if len(result):
- self.packetlist = []
- for x in result.splitlines():
- split = x.split(' - ') #self.blacklisted_packages
- if not any(split[0].strip().endswith(x) for x in self.unwanted_extensions):
- self.packetlist.append([split[0].strip(), split[1].strip(),split[2].strip()])
- if not self.Console:
- self.Console = Console()
- cmd = "ipkg list_installed"
- self.Console.ePopen(cmd, self.IpkgListInstalled_Finished)
-
- def IpkgListInstalled_Finished(self, result, retval, extra_args = None):
- if len(result):
- self.installed_packetlist = {}
- for x in result.splitlines():
- split = x.split(' - ')
- if not any(split[0].strip().endswith(x) for x in self.unwanted_extensions):
- self.installed_packetlist[split[0].strip()] = split[1].strip()
- self.buildPacketList()
-
- def buildEntryComponent(self, name, version, description, state):
- divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
- if state == 'installed':
- installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png"))
- return((name, version, description, state, installedpng, divpng))
- elif state == 'upgradeable':
- upgradeablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgradeable.png"))
- return((name, version, description, state, upgradeablepng, divpng))
- else:
- installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png"))
- return((name, version, description, state, installablepng, divpng))
-
- def buildPacketList(self):
- self.list = []
- self.cachelist = []
-
- if self.cache_ttl > 0 and self.vc != 0:
- print 'Loading packagelist cache from ',self.cache_file
- try:
- self.cachelist = load_cache(self.cache_file)
- if len(self.cachelist) > 0:
- for x in self.cachelist:
- self.list.append(self.buildEntryComponent(x[0], x[1], x[2], x[3]))
- self['list'].setList(self.list)
- except:
- self.inv_cache = 1
-
- if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
- print 'rebuilding fresh package list'
- for x in self.packetlist:
- status = ""
- if self.installed_packetlist.has_key(x[0].strip()):
- if self.installed_packetlist[x[0].strip()] == x[1].strip():
- status = "installed"
- self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status))
- else:
- status = "upgradeable"
- self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status))
- else:
- status = "installable"
- self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status))
- if not any(x[0].strip().endswith(x) for x in self.unwanted_extensions):
- self.cachelist.append([x[0].strip(), x[1].strip(), x[2].strip(), status])
- write_cache(self.cache_file, self.cachelist)
- self['list'].setList(self.list)
-
- def reloadPluginlist(self):
- plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
-
class PluginManager(Screen, DreamInfoHandler):
- lastDownloadDate = None
-
skin = """
- <screen name="PluginManager" position="center,center" size="560,440" title="Plugin manager" >
+ <screen name="PluginManager" position="center,center" size="560,440" title="Extensions management" >
<ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
<ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
<ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
@@ -700,17 +308,17 @@ class PluginManager(Screen, DreamInfoHandler):
{"templates":
{"default": (51,[
MultiContentEntryText(pos = (30, 1), size = (470, 24), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
- MultiContentEntryText(pos = (30, 25), size = (470, 20), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is the description
+ MultiContentEntryText(pos = (30, 25), size = (470, 24), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is the description
MultiContentEntryPixmapAlphaTest(pos = (475, 0), size = (48, 48), png = 5), # index 5 is the status pixmap
MultiContentEntryPixmapAlphaTest(pos = (0, 49), size = (550, 2), png = 6), # index 6 is the div pixmap
]),
"category": (40,[
MultiContentEntryText(pos = (30, 0), size = (500, 22), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
- MultiContentEntryText(pos = (30, 22), size = (500, 16), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the description
+ MultiContentEntryText(pos = (30, 22), size = (500, 16), font=2, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the description
MultiContentEntryPixmapAlphaTest(pos = (0, 38), size = (550, 2), png = 3), # index 3 is the div pixmap
])
},
- "fonts": [gFont("Regular", 22),gFont("Regular", 16)],
+ "fonts": [gFont("Regular", 22),gFont("Regular", 20),gFont("Regular", 16)],
"itemHeight": 52
}
</convert>
@@ -722,15 +330,6 @@ class PluginManager(Screen, DreamInfoHandler):
Screen.__init__(self, session)
self.session = session
self.skin_path = plugin_path
- aboutInfo = about.getImageVersionString()
- if aboutInfo.startswith("dev-"):
- self.ImageVersion = 'Experimental'
- else:
- self.ImageVersion = 'Stable'
- self.language = language.getLanguage()[:2] # getLanguage returns e.g. "fi_FI" for "language_country"
-
- DreamInfoHandler.__init__(self, self.statusCallback, blocking = False, neededTag = 'ALL_TAGS', neededFlag = self.ImageVersion, language = self.language)
- self.directory = resolveFilename(SCOPE_METADIR)
self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions", "InfobarEPGActions", "HelpActions" ],
{
@@ -747,6 +346,7 @@ class PluginManager(Screen, DreamInfoHandler):
self.statuslist = []
self.selectedFiles = []
self.categoryList = []
+ self.packetlist = []
self["list"] = List(self.list)
self["key_red"] = StaticText(_("Close"))
self["key_green"] = StaticText("")
@@ -754,30 +354,22 @@ class PluginManager(Screen, DreamInfoHandler):
self["key_blue"] = StaticText("")
self["status"] = StaticText("")
- self.list_updating = True
- self.packetlist = []
- self.installed_packetlist = {}
- self.available_packetlist = []
- self.available_updates = 0
- self.Console = Console()
self.cmdList = []
self.oktext = _("\nAfter pressing OK, please wait!")
- self.unwanted_extensions = ('-dbg', '-dev', '-doc')
-
- self.ipkg = IpkgComponent()
- self.ipkg.addCallback(self.ipkgCallback)
if not self.selectionChanged in self["list"].onSelectionChanged:
self["list"].onSelectionChanged.append(self.selectionChanged)
self.currList = ""
self.currentSelectedTag = None
self.currentSelectedIndex = None
-
+ self.currentSelectedPackage = None
+ self.saved_currentSelectedPackage = None
+
self.onShown.append(self.setWindowTitle)
- self.onLayoutFinish.append(self.rebuildList)
+ self.onLayoutFinish.append(self.getUpdateInfos)
def setWindowTitle(self):
- self.setTitle(_("Plugin manager"))
+ self.setTitle(_("Extensions management"))
def exit(self):
if self.currList == "packages":
@@ -789,11 +381,7 @@ class PluginManager(Screen, DreamInfoHandler):
self["list"].updateList(self.categoryList)
self.selectionChanged()
else:
- self.ipkg.stop()
- if self.Console is not None:
- if len(self.Console.appContainers):
- for name in self.Console.appContainers.keys():
- self.Console.kill(name)
+ iSoftwareTools.cleanupSoftwareTools()
self.prepareInstall()
if len(self.cmdList):
self.session.openWithCallback(self.runExecute, PluginManagerInfo, self.skin_path, self.cmdList)
@@ -814,7 +402,7 @@ class PluginManager(Screen, DreamInfoHandler):
divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
if status == 'update':
statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
- self.statuslist.append(( _("Package list update"), '', _("Trying to download a new packetlist. Please wait..." ),'', '', statuspng, divpng, None, '' ))
+ self.statuslist.append(( _("Updating software catalog"), '', _("Searching for available updates. Please wait..." ),'', '', statuspng, divpng, None, '' ))
self["list"].style = "default"
self['list'].setList(self.statuslist)
elif status == 'sync':
@@ -828,8 +416,26 @@ class PluginManager(Screen, DreamInfoHandler):
self["list"].style = "default"
self['list'].setList(self.statuslist)
- def statusCallback(self, status, progress):
- pass
+ def getUpdateInfos(self):
+ self.setState('update')
+ iSoftwareTools.getUpdates(self.getUpdateInfosCB)
+
+ def getUpdateInfosCB(self, retval = None):
+ if retval is not None:
+ if retval is True:
+ if iSoftwareTools.available_updates is not 0:
+ self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available."))
+ else:
+ self["status"].setText(_("There are no updates available."))
+ elif retval is False:
+ self["status"].setText(_("No network connection available."))
+ self.rebuildList()
+
+ def rebuildList(self, retval = None):
+ if self.currentSelectedTag is None:
+ self.buildCategoryList()
+ else:
+ self.buildPacketList(self.currentSelectedTag)
def selectionChanged(self):
current = self["list"].getCurrent()
@@ -838,34 +444,34 @@ class PluginManager(Screen, DreamInfoHandler):
if self.currList == "packages":
self["key_red"].setText(_("Back"))
if current[4] == 'installed':
- self["key_green"].setText(_("Remove"))
+ self["key_green"].setText(_("Uninstall"))
elif current[4] == 'installable':
self["key_green"].setText(_("Install"))
elif current[4] == 'remove':
- self["key_green"].setText(_("Undo\nRemove"))
+ self["key_green"].setText(_("Undo uninstall"))
elif current[4] == 'install':
- self["key_green"].setText(_("Undo\nInstall"))
+ self["key_green"].setText(_("Undo install"))
self["key_yellow"].setText(_("View details"))
self["key_blue"].setText("")
- if len(self.selectedFiles) == 0 and self.available_updates is not 0:
- self["status"].setText(_("There are at least ") + str(self.available_updates) + _(" updates available."))
+ if len(self.selectedFiles) == 0 and iSoftwareTools.available_updates is not 0:
+ self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available."))
elif len(self.selectedFiles) is not 0:
self["status"].setText(str(len(self.selectedFiles)) + _(" packages selected."))
else:
- self["status"].setText(_("There is nothing to be done."))
+ self["status"].setText(_("There are currently no outstanding actions."))
elif self.currList == "category":
self["key_red"].setText(_("Close"))
self["key_green"].setText("")
self["key_yellow"].setText("")
self["key_blue"].setText("")
- if len(self.selectedFiles) == 0 and self.available_updates is not 0:
- self["status"].setText(_("There are at least ") + str(self.available_updates) + _(" updates available."))
+ if len(self.selectedFiles) == 0 and iSoftwareTools.available_updates is not 0:
+ self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + _(" updates available."))
self["key_yellow"].setText(_("Update"))
elif len(self.selectedFiles) is not 0:
self["status"].setText(str(len(self.selectedFiles)) + _(" packages selected."))
self["key_yellow"].setText(_("Process"))
else:
- self["status"].setText(_("There is nothing to be done."))
+ self["status"].setText(_("There are currently no outstanding actions."))
def getSelectionState(self, detailsFile):
for entry in self.selectedFiles:
@@ -873,82 +479,6 @@ class PluginManager(Screen, DreamInfoHandler):
return True
return False
- def rebuildList(self):
- self.setState('update')
- if not PluginManager.lastDownloadDate or (time() - PluginManager.lastDownloadDate) > 3600:
- # Only update from internet once per hour
- PluginManager.lastDownloadDate = time()
- print "last update time > 1h"
- self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
- else:
- print "last update time < 1h"
- self.startIpkgList()
-
- def ipkgCallback(self, event, param):
- if event == IpkgComponent.EVENT_ERROR:
- self.list_updating = False
- self.setState('error')
- elif event == IpkgComponent.EVENT_DONE:
- self.startIpkgList()
- pass
-
- def startIpkgList(self):
- if self.list_updating:
- if not self.Console:
- self.Console = Console()
- cmd = "ipkg list"
- self.Console.ePopen(cmd, self.IpkgList_Finished)
-
- def IpkgList_Finished(self, result, retval, extra_args = None):
- if len(result):
- self.available_packetlist = []
- for x in result.splitlines():
- split = x.split(' - ')
- if not any(split[0].strip().endswith(x) for x in self.unwanted_extensions):
- self.available_packetlist.append([split[0].strip(), split[1].strip(), split[2].strip()])
- self.startInstallMetaPackage()
-
- def startInstallMetaPackage(self):
- if self.list_updating:
- self.list_updating = False
- if not self.Console:
- self.Console = Console()
- cmd = "ipkg install enigma2-meta" #dummy,will change probably"
- self.Console.ePopen(cmd, self.InstallMetaPackage_Finished)
-
- def InstallMetaPackage_Finished(self, result, retval, extra_args = None):
- if len(result):
- self.fillPackagesIndexList()
- if not self.Console:
- self.Console = Console()
- self.setState('sync')
- cmd = "ipkg list_installed"
- self.Console.ePopen(cmd, self.IpkgListInstalled_Finished)
-
- def IpkgListInstalled_Finished(self, result, retval, extra_args = None):
- if len(result):
- self.installed_packetlist = {}
- for x in result.splitlines():
- split = x.split(' - ')
- if not any(split[0].strip().endswith(x) for x in self.unwanted_extensions):
- self.installed_packetlist[split[0].strip()] = split[1].strip()
- self.countUpdates()
- if self.currentSelectedTag is None:
- self.buildCategoryList()
- else:
- self.buildPacketList(self.currentSelectedTag)
-
- def countUpdates(self):
- self.available_updates = 0
- for package in self.packagesIndexlist[:]:
- attributes = package[0]["attributes"]
- packagename = attributes["packagename"]
- for x in self.available_packetlist:
- if x[0].strip() == packagename:
- if self.installed_packetlist.has_key(packagename):
- if self.installed_packetlist[packagename] != x[1].strip():
- self.available_updates +=1
-
def handleCurrent(self):
current = self["list"].getCurrent()
if current:
@@ -971,6 +501,7 @@ class PluginManager(Screen, DreamInfoHandler):
alreadyinList = True
if not alreadyinList:
self.selectedFiles.append((detailsFile,current[4],current[3]))
+ self.currentSelectedPackage = ((detailsFile,current[4],current[3]))
if current[4] == 'installed':
self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'remove', True)
elif current[4] == 'installable':
@@ -989,8 +520,9 @@ class PluginManager(Screen, DreamInfoHandler):
if current:
if self.currList == "packages":
if current[7] is not '':
- detailsfile = self.directory[0] + "/" + current[1]
+ detailsfile = iSoftwareTools.directory[0] + "/" + current[1]
if (os_path.exists(detailsfile) == True):
+ self.saved_currentSelectedPackage = self.currentSelectedPackage
self.session.openWithCallback(self.detailsClosed, PluginDetails, self.skin_path, current)
else:
self.session.open(MessageBox, _("Sorry, no Details available!"), MessageBox.TYPE_INFO, timeout = 10)
@@ -999,29 +531,29 @@ class PluginManager(Screen, DreamInfoHandler):
if len(self.cmdList):
self.session.openWithCallback(self.runExecute, PluginManagerInfo, self.skin_path, self.cmdList)
- def detailsClosed(self, result):
- if result:
- if not self.Console:
- self.Console = Console()
- self.setState('sync')
- PluginManager.lastDownloadDate = time()
- self.selectedFiles = []
- cmd = "ipkg update"
- self.Console.ePopen(cmd, self.InstallMetaPackage_Finished)
+ def detailsClosed(self, result = None):
+ if result is not None:
+ if result is not False:
+ self.setState('sync')
+ iSoftwareTools.lastDownloadDate = time()
+ for entry in self.selectedFiles:
+ if entry == self.saved_currentSelectedPackage:
+ self.selectedFiles.remove(entry)
+ iSoftwareTools.startIpkgListInstalled(self.rebuildList)
def buildEntryComponent(self, name, details, description, packagename, state, selected = False):
divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
+ installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png"))
+ installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png"))
+ removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
+ installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png"))
if state == 'installed':
- installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png"))
return((name, details, description, packagename, state, installedpng, divpng, selected))
elif state == 'installable':
- installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png"))
return((name, details, description, packagename, state, installablepng, divpng, selected))
elif state == 'remove':
- removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
return((name, details, description, packagename, state, removepng, divpng, selected))
elif state == 'install':
- installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png"))
return((name, details, description, packagename, state, installpng, divpng, selected))
def buildPacketList(self, categorytag = None):
@@ -1029,7 +561,7 @@ class PluginManager(Screen, DreamInfoHandler):
self.currList = "packages"
self.currentSelectedTag = categorytag
self.packetlist = []
- for package in self.packagesIndexlist[:]:
+ for package in iSoftwareTools.packagesIndexlist[:]:
prerequisites = package[0]["prerequisites"]
if prerequisites.has_key("tag"):
for foundtag in prerequisites["tag"]:
@@ -1044,19 +576,23 @@ class PluginManager(Screen, DreamInfoHandler):
self.list = []
for x in self.packetlist:
status = ""
- selectState = self.getSelectionState(x[1].strip())
- if self.installed_packetlist.has_key(x[3].strip()):
+ name = x[0].strip()
+ details = x[1].strip()
+ description = x[2].strip()
+ packagename = x[3].strip()
+ selectState = self.getSelectionState(details)
+ if iSoftwareTools.installed_packetlist.has_key(packagename):
if selectState == True:
status = "remove"
else:
status = "installed"
- self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), x[3].strip(), status, selected = selectState))
+ self.list.append(self.buildEntryComponent(name, details, description, packagename, status, selected = selectState))
else:
if selectState == True:
status = "install"
else:
status = "installable"
- self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), x[3].strip(), status, selected = selectState))
+ self.list.append(self.buildEntryComponent(name, details, description, packagename, status, selected = selectState))
if len(self.list):
self.list.sort(key=lambda x: x[0])
self["list"].style = "default"
@@ -1068,7 +604,7 @@ class PluginManager(Screen, DreamInfoHandler):
self.currList = "category"
self.categories = []
self.categoryList = []
- for package in self.packagesIndexlist[:]:
+ for package in iSoftwareTools.packagesIndexlist[:]:
prerequisites = package[0]["prerequisites"]
if prerequisites.has_key("tag"):
for foundtag in prerequisites["tag"]:
@@ -1114,14 +650,14 @@ class PluginManager(Screen, DreamInfoHandler):
def prepareInstall(self):
self.cmdList = []
- if self.available_updates > 0:
+ if iSoftwareTools.available_updates > 0:
self.cmdList.append((IpkgComponent.CMD_UPGRADE, { "test_only": False }))
if self.selectedFiles and len(self.selectedFiles):
for plugin in self.selectedFiles:
- detailsfile = self.directory[0] + "/" + plugin[0]
+ detailsfile = iSoftwareTools.directory[0] + "/" + plugin[0]
if (os_path.exists(detailsfile) == True):
- self.fillPackageDetails(plugin[0])
- self.package = self.packageDetails[0]
+ iSoftwareTools.fillPackageDetails(plugin[0])
+ self.package = iSoftwareTools.packageDetails[0]
if self.package[0].has_key("attributes"):
self.attributes = self.package[0]["attributes"]
if self.attributes.has_key("package"):
@@ -1144,9 +680,13 @@ class PluginManager(Screen, DreamInfoHandler):
else:
self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": plugin[2] }))
- def runExecute(self, result):
- if result:
- self.session.openWithCallback(self.runExecuteFinished, Ipkg, cmdList = self.cmdList)
+ def runExecute(self, result = None):
+ if result is not None:
+ if result[0] is True:
+ self.session.openWithCallback(self.runExecuteFinished, Ipkg, cmdList = self.cmdList)
+ elif result[0] is False:
+ self.cmdList = result[1]
+ self.session.openWithCallback(self.runExecuteFinished, Ipkg, cmdList = self.cmdList)
else:
self.close()
@@ -1158,6 +698,7 @@ class PluginManager(Screen, DreamInfoHandler):
return
if result is False:
self.reloadPluginlist()
+ self.selectedFiles = []
self.detailsClosed(True)
if result:
quitMainloop(3)
@@ -1168,7 +709,7 @@ class PluginManager(Screen, DreamInfoHandler):
class PluginManagerInfo(Screen):
skin = """
- <screen name="PluginManagerInfo" position="center,center" size="560,440" title="Plugin manager activity information" >
+ <screen name="PluginManagerInfo" position="center,center" size="560,450" title="Plugin manager activity information" >
<ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
<ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
<widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
@@ -1176,18 +717,18 @@ class PluginManagerInfo(Screen):
<widget source="list" render="Listbox" position="5,50" size="550,350" scrollbarMode="showOnDemand" selectionDisabled="1">
<convert type="TemplatedMultiContent">
{"template": [
- MultiContentEntryText(pos = (50, 1), size = (150, 24), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
- MultiContentEntryText(pos = (50, 25), size = (540, 24), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the state
+ MultiContentEntryText(pos = (50, 0), size = (150, 26), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
+ MultiContentEntryText(pos = (50, 27), size = (540, 23), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the state
MultiContentEntryPixmapAlphaTest(pos = (0, 1), size = (48, 48), png = 2), # index 2 is the status pixmap
- MultiContentEntryPixmapAlphaTest(pos = (0, 49), size = (550, 2), png = 3), # index 3 is the div pixmap
+ MultiContentEntryPixmapAlphaTest(pos = (0, 48), size = (550, 2), png = 3), # index 3 is the div pixmap
],
- "fonts": [gFont("Regular", 22),gFont("Regular", 18)],
- "itemHeight": 52
+ "fonts": [gFont("Regular", 24),gFont("Regular", 22)],
+ "itemHeight": 50
}
</convert>
</widget>
- <ePixmap pixmap="skin_default/div-h.png" position="0,410" zPosition="10" size="560,2" transparent="1" alphatest="on" />
- <widget source="status" render="Label" position="5,420" zPosition="10" size="550,30" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
+ <ePixmap pixmap="skin_default/div-h.png" position="0,404" zPosition="10" size="560,2" transparent="1" alphatest="on" />
+ <widget source="status" render="Label" position="5,408" zPosition="10" size="550,44" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
</screen>"""
def __init__(self, session, plugin_path, cmdlist = None):
@@ -1198,17 +739,17 @@ class PluginManagerInfo(Screen):
self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
{
- "ok": self.process,
+ "ok": self.process_all,
"back": self.exit,
"red": self.exit,
- "green": self.process,
+ "green": self.process_extensions,
}, -1)
self.list = []
self["list"] = List(self.list)
self["key_red"] = StaticText(_("Cancel"))
- self["key_green"] = StaticText(_("Continue"))
- self["status"] = StaticText(_("Following tasks will be done after you press continue!"))
+ self["key_green"] = StaticText(_("Only extensions."))
+ self["status"] = StaticText(_("Following tasks will be done after you press OK!"))
self.onShown.append(self.setWindowTitle)
self.onLayoutFinish.append(self.rebuildList)
@@ -1254,32 +795,41 @@ class PluginManagerInfo(Screen):
return(( _('Upgrading'), info, upgradepng, divpng))
def exit(self):
- self.close(False)
+ self.close()
- def process(self):
- self.close(True)
+ def process_all(self):
+ self.close((True,None))
+
+ def process_extensions(self):
+ self.list = []
+ if self.cmdlist is not None:
+ for entry in self.cmdlist:
+ cmd = entry[0]
+ if entry[0] in (0,2):
+ self.list.append((entry))
+ self.close((False,self.list))
class PluginManagerHelp(Screen):
skin = """
- <screen name="PluginManagerHelp" position="center,center" size="560,440" title="Plugin manager help" >
+ <screen name="PluginManagerHelp" position="center,center" size="560,450" title="Plugin manager help" >
<ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
<widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
<widget source="list" render="Listbox" position="5,50" size="550,350" scrollbarMode="showOnDemand" selectionDisabled="1">
<convert type="TemplatedMultiContent">
{"template": [
- MultiContentEntryText(pos = (50, 1), size = (540, 24), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
- MultiContentEntryText(pos = (50, 25), size = (540, 24), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the state
+ MultiContentEntryText(pos = (50, 0), size = (150, 26), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
+ MultiContentEntryText(pos = (50, 27), size = (540, 23), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the state
MultiContentEntryPixmapAlphaTest(pos = (0, 1), size = (48, 48), png = 2), # index 2 is the status pixmap
- MultiContentEntryPixmapAlphaTest(pos = (0, 49), size = (550, 2), png = 3), # index 3 is the div pixmap
+ MultiContentEntryPixmapAlphaTest(pos = (0, 48), size = (550, 2), png = 3), # index 3 is the div pixmap
],
- "fonts": [gFont("Regular", 22),gFont("Regular", 18)],
- "itemHeight": 52
+ "fonts": [gFont("Regular", 24),gFont("Regular", 22)],
+ "itemHeight": 50
}
</convert>
</widget>
- <ePixmap pixmap="skin_default/div-h.png" position="0,410" zPosition="10" size="550,2" transparent="1" alphatest="on" />
- <widget source="status" render="Label" position="5,420" zPosition="10" size="550,30" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
+ <ePixmap pixmap="skin_default/div-h.png" position="0,404" zPosition="10" size="560,2" transparent="1" alphatest="on" />
+ <widget source="status" render="Label" position="5,408" zPosition="10" size="550,44" halign="center" valign="center" font="Regular;22" transparent="1" shadowColor="black" shadowOffset="-1,-1" />
</screen>"""
def __init__(self, session, plugin_path):
@@ -1401,7 +951,7 @@ class PluginDetails(Screen, DreamInfoHandler):
self.onLayoutFinish.append(self.setInfos)
def setWindowTitle(self):
- self.setTitle(_("Package details for: " + self.pluginname))
+ self.setTitle(_("Details for extension: " + self.pluginname))
def exit(self):
self.close(False)
@@ -1444,7 +994,7 @@ class PluginDetails(Screen, DreamInfoHandler):
self["author"].setText(_("Author: ") + self.author)
self["detailtext"].setText(self.description.strip())
- if self.pluginstate == 'installable':
+ if self.pluginstate in ('installable', 'install'):
self["key_green"].setText(_("Install"))
else:
self["key_green"].setText(_("Remove"))
@@ -1489,7 +1039,7 @@ class PluginDetails(Screen, DreamInfoHandler):
if self.attributes.has_key("package"):
self.packagefiles = self.attributes["package"]
self.cmdList = []
- if self.pluginstate == 'installed':
+ if self.pluginstate in ('installed', 'remove'):
if self.packagefiles:
for package in self.packagefiles[:]:
self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package["name"] }))
@@ -1654,6 +1204,427 @@ class UpdatePlugin(Screen):
self.close()
+
+class IPKGMenu(Screen):
+ skin = """
+ <screen name="IPKGMenu" position="center,center" size="560,400" title="Select upgrade source to edit." >
+ <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
+ <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
+ <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
+ <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
+ <widget name="filelist" position="5,50" size="550,340" scrollbarMode="showOnDemand" />
+ </screen>"""
+
+ def __init__(self, session, plugin_path):
+ Screen.__init__(self, session)
+ self.skin_path = plugin_path
+
+ self["key_red"] = StaticText(_("Close"))
+ self["key_green"] = StaticText(_("Edit"))
+
+ self.sel = []
+ self.val = []
+ self.entry = False
+ self.exe = False
+
+ self.path = ""
+
+ self["actions"] = NumberActionMap(["SetupActions"],
+ {
+ "ok": self.KeyOk,
+ "cancel": self.keyCancel
+ }, -1)
+
+ self["shortcuts"] = ActionMap(["ShortcutActions"],
+ {
+ "red": self.keyCancel,
+ "green": self.KeyOk,
+ })
+ self.flist = []
+ self["filelist"] = MenuList(self.flist)
+ self.fill_list()
+ self.onLayoutFinish.append(self.layoutFinished)
+
+ def layoutFinished(self):
+ self.setWindowTitle()
+
+ def setWindowTitle(self):
+ self.setTitle(_("Select upgrade source to edit."))
+
+ def fill_list(self):
+ self.flist = []
+ self.path = '/etc/ipkg/'
+ if (os_path.exists(self.path) == False):
+ self.entry = False
+ return
+ for file in listdir(self.path):
+ if (file.endswith(".conf")):
+ if file != 'arch.conf':
+ self.flist.append((file))
+ self.entry = True
+ self["filelist"].l.setList(self.flist)
+
+ def KeyOk(self):
+ if (self.exe == False) and (self.entry == True):
+ self.sel = self["filelist"].getCurrent()
+ self.val = self.path + self.sel
+ self.session.open(IPKGSource, self.val)
+
+ def keyCancel(self):
+ self.close()
+
+ def Exit(self):
+ self.close()
+
+
+class IPKGSource(Screen):
+ skin = """
+ <screen name="IPKGSource" position="center,center" size="560,80" title="Edit upgrade source url." >
+ <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
+ <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
+ <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
+ <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
+ <widget name="text" position="5,50" size="550,25" font="Regular;20" backgroundColor="background" foregroundColor="#cccccc" />
+ </screen>"""
+
+ def __init__(self, session, configfile = None):
+ Screen.__init__(self, session)
+ self.session = session
+ self.configfile = configfile
+ text = ""
+ if self.configfile:
+ try:
+ fp = file(configfile, 'r')
+ sources = fp.readlines()
+ if sources:
+ text = sources[0]
+ fp.close()
+ except IOError:
+ pass
+
+ desk = getDesktop(0)
+ x= int(desk.size().width())
+ y= int(desk.size().height())
+
+ self["key_red"] = StaticText(_("Cancel"))
+ self["key_green"] = StaticText(_("Save"))
+
+ if (y>=720):
+ self["text"] = Input(text, maxSize=False, type=Input.TEXT)
+ else:
+ self["text"] = Input(text, maxSize=False, visible_width = 55, type=Input.TEXT)
+
+ self["actions"] = NumberActionMap(["WizardActions", "InputActions", "TextEntryActions", "KeyboardInputActions","ShortcutActions"],
+ {
+ "ok": self.go,
+ "back": self.close,
+ "red": self.close,
+ "green": self.go,
+ "left": self.keyLeft,
+ "right": self.keyRight,
+ "home": self.keyHome,
+ "end": self.keyEnd,
+ "deleteForward": self.keyDeleteForward,
+ "deleteBackward": self.keyDeleteBackward,
+ "1": self.keyNumberGlobal,
+ "2": self.keyNumberGlobal,
+ "3": self.keyNumberGlobal,
+ "4": self.keyNumberGlobal,
+ "5": self.keyNumberGlobal,
+ "6": self.keyNumberGlobal,
+ "7": self.keyNumberGlobal,
+ "8": self.keyNumberGlobal,
+ "9": self.keyNumberGlobal,
+ "0": self.keyNumberGlobal
+ }, -1)
+
+ self.onLayoutFinish.append(self.layoutFinished)
+
+ def layoutFinished(self):
+ self.setWindowTitle()
+ self["text"].right()
+
+ def setWindowTitle(self):
+ self.setTitle(_("Edit upgrade source url."))
+
+ def go(self):
+ text = self["text"].getText()
+ if text:
+ fp = file(self.configfile, 'w')
+ fp.write(text)
+ fp.write("\n")
+ fp.close()
+ self.close()
+
+ def keyLeft(self):
+ self["text"].left()
+
+ def keyRight(self):
+ self["text"].right()
+
+ def keyHome(self):
+ self["text"].home()
+
+ def keyEnd(self):
+ self["text"].end()
+
+ def keyDeleteForward(self):
+ self["text"].delete()
+
+ def keyDeleteBackward(self):
+ self["text"].deleteBackward()
+
+ def keyNumberGlobal(self, number):
+ self["text"].number(number)
+
+
+class PacketManager(Screen):
+ skin = """
+ <screen name="PacketManager" position="center,center" size="530,420" title="Packet manager" >
+ <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
+ <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
+ <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
+ <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
+ <widget source="list" render="Listbox" position="5,50" size="520,365" scrollbarMode="showOnDemand">
+ <convert type="TemplatedMultiContent">
+ {"template": [
+ MultiContentEntryText(pos = (5, 1), size = (440, 28), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name
+ MultiContentEntryText(pos = (5, 26), size = (440, 20), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is the description
+ MultiContentEntryPixmapAlphaTest(pos = (445, 2), size = (48, 48), png = 4), # index 4 is the status pixmap
+ MultiContentEntryPixmapAlphaTest(pos = (5, 50), size = (510, 2), png = 5), # index 4 is the div pixmap
+ ],
+ "fonts": [gFont("Regular", 22),gFont("Regular", 14)],
+ "itemHeight": 52
+ }
+ </convert>
+ </widget>
+ </screen>"""
+
+ def __init__(self, session, plugin_path, args = None):
+ Screen.__init__(self, session)
+ self.session = session
+ self.skin_path = plugin_path
+
+ self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
+ {
+ "ok": self.go,
+ "back": self.exit,
+ "red": self.exit,
+ "green": self.reload,
+ }, -1)
+
+ self.list = []
+ self.statuslist = []
+ self["list"] = List(self.list)
+ self["key_red"] = StaticText(_("Close"))
+ self["key_green"] = StaticText(_("Reload"))
+
+ self.list_updating = True
+ self.packetlist = []
+ self.installed_packetlist = {}
+ self.Console = Console()
+ self.cmdList = []
+ self.cachelist = []
+ self.cache_ttl = 86400 #600 is default, 0 disables, Seconds cache is considered valid (24h should be ok for caching ipkgs)
+ self.cache_file = '/usr/lib/enigma2/python/Plugins/SystemPlugins/SoftwareManager/packetmanager.cache' #Path to cache directory
+ self.oktext = _("\nAfter pressing OK, please wait!")
+ self.unwanted_extensions = ('-dbg', '-dev', '-doc', 'busybox')
+
+ self.ipkg = IpkgComponent()
+ self.ipkg.addCallback(self.ipkgCallback)
+ self.onShown.append(self.setWindowTitle)
+ self.onLayoutFinish.append(self.rebuildList)
+
+ def exit(self):
+ self.ipkg.stop()
+ if self.Console is not None:
+ if len(self.Console.appContainers):
+ for name in self.Console.appContainers.keys():
+ self.Console.kill(name)
+ self.close()
+
+ def reload(self):
+ if (os_path.exists(self.cache_file) == True):
+ remove(self.cache_file)
+ self.list_updating = True
+ self.rebuildList()
+
+ def setWindowTitle(self):
+ self.setTitle(_("Packet manager"))
+
+ def setStatus(self,status = None):
+ if status:
+ self.statuslist = []
+ divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
+ if status == 'update':
+ statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png"))
+ self.statuslist.append(( _("Package list update"), '', _("Trying to download a new packetlist. Please wait..." ),'',statuspng, divpng ))
+ self['list'].setList(self.statuslist)
+ elif status == 'error':
+ statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png"))
+ self.statuslist.append(( _("Error"), '', _("There was an error downloading the packetlist. Please try again." ),'',statuspng, divpng ))
+ self['list'].setList(self.statuslist)
+
+ def rebuildList(self):
+ self.setStatus('update')
+ self.inv_cache = 0
+ self.vc = valid_cache(self.cache_file, self.cache_ttl)
+ if self.cache_ttl > 0 and self.vc != 0:
+ try:
+ self.buildPacketList()
+ except:
+ self.inv_cache = 1
+ if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
+ self.run = 0
+ self.ipkg.startCmd(IpkgComponent.CMD_UPDATE)
+
+ def go(self, returnValue = None):
+ cur = self["list"].getCurrent()
+ if cur:
+ status = cur[3]
+ package = cur[0]
+ self.cmdList = []
+ if status == 'installed':
+ self.cmdList.append((IpkgComponent.CMD_REMOVE, { "package": package }))
+ if len(self.cmdList):
+ self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n") + package + "\n" + self.oktext)
+ elif status == 'upgradeable':
+ self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package }))
+ if len(self.cmdList):
+ self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to upgrade the package:\n") + package + "\n" + self.oktext)
+ elif status == "installable":
+ self.cmdList.append((IpkgComponent.CMD_INSTALL, { "package": package }))
+ if len(self.cmdList):
+ self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n") + package + "\n" + self.oktext)
+
+ def runRemove(self, result):
+ if result:
+ self.session.openWithCallback(self.runRemoveFinished, Ipkg, cmdList = self.cmdList)
+
+ def runRemoveFinished(self):
+ self.session.openWithCallback(self.RemoveReboot, MessageBox, _("Remove finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
+
+ def RemoveReboot(self, result):
+ if result is None:
+ return
+ if result is False:
+ cur = self["list"].getCurrent()
+ if cur:
+ item = self['list'].getIndex()
+ self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installable')
+ self.cachelist[item] = [cur[0], cur[1], cur[2], 'installable']
+ self['list'].setList(self.list)
+ write_cache(self.cache_file, self.cachelist)
+ self.reloadPluginlist()
+ if result:
+ quitMainloop(3)
+
+ def runUpgrade(self, result):
+ if result:
+ self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList = self.cmdList)
+
+ def runUpgradeFinished(self):
+ self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Upgrade finished.") +" "+_("Do you want to reboot your Dreambox?"), MessageBox.TYPE_YESNO)
+
+ def UpgradeReboot(self, result):
+ if result is None:
+ return
+ if result is False:
+ cur = self["list"].getCurrent()
+ if cur:
+ item = self['list'].getIndex()
+ self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installed')
+ self.cachelist[item] = [cur[0], cur[1], cur[2], 'installed']
+ self['list'].setList(self.list)
+ write_cache(self.cache_file, self.cachelist)
+ self.reloadPluginlist()
+ if result:
+ quitMainloop(3)
+
+ def ipkgCallback(self, event, param):
+ if event == IpkgComponent.EVENT_ERROR:
+ self.list_updating = False
+ self.setStatus('error')
+ elif event == IpkgComponent.EVENT_DONE:
+ if self.list_updating:
+ self.list_updating = False
+ if not self.Console:
+ self.Console = Console()
+ cmd = "ipkg list"
+ self.Console.ePopen(cmd, self.IpkgList_Finished)
+ #print event, "-", param
+ pass
+
+ def IpkgList_Finished(self, result, retval, extra_args = None):
+ if len(result):
+ self.packetlist = []
+ for x in result.splitlines():
+ split = x.split(' - ') #self.blacklisted_packages
+ if not any(split[0].strip().endswith(x) for x in self.unwanted_extensions):
+ self.packetlist.append([split[0].strip(), split[1].strip(),split[2].strip()])
+ if not self.Console:
+ self.Console = Console()
+ cmd = "ipkg list_installed"
+ self.Console.ePopen(cmd, self.IpkgListInstalled_Finished)
+
+ def IpkgListInstalled_Finished(self, result, retval, extra_args = None):
+ if len(result):
+ self.installed_packetlist = {}
+ for x in result.splitlines():
+ split = x.split(' - ')
+ if not any(split[0].strip().endswith(x) for x in self.unwanted_extensions):
+ self.installed_packetlist[split[0].strip()] = split[1].strip()
+ self.buildPacketList()
+
+ def buildEntryComponent(self, name, version, description, state):
+ divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "skin_default/div-h.png"))
+ if state == 'installed':
+ installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png"))
+ return((name, version, description, state, installedpng, divpng))
+ elif state == 'upgradeable':
+ upgradeablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgradeable.png"))
+ return((name, version, description, state, upgradeablepng, divpng))
+ else:
+ installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png"))
+ return((name, version, description, state, installablepng, divpng))
+
+ def buildPacketList(self):
+ self.list = []
+ self.cachelist = []
+
+ if self.cache_ttl > 0 and self.vc != 0:
+ print 'Loading packagelist cache from ',self.cache_file
+ try:
+ self.cachelist = load_cache(self.cache_file)
+ if len(self.cachelist) > 0:
+ for x in self.cachelist:
+ self.list.append(self.buildEntryComponent(x[0], x[1], x[2], x[3]))
+ self['list'].setList(self.list)
+ except:
+ self.inv_cache = 1
+
+ if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0:
+ print 'rebuilding fresh package list'
+ for x in self.packetlist:
+ status = ""
+ if self.installed_packetlist.has_key(x[0].strip()):
+ if self.installed_packetlist[x[0].strip()] == x[1].strip():
+ status = "installed"
+ self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status))
+ else:
+ status = "upgradeable"
+ self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status))
+ else:
+ status = "installable"
+ self.list.append(self.buildEntryComponent(x[0].strip(), x[1].strip(), x[2].strip(), status))
+ if not any(x[0].strip().endswith(x) for x in self.unwanted_extensions):
+ self.cachelist.append([x[0].strip(), x[1].strip(), x[2].strip(), status])
+ write_cache(self.cache_file, self.cachelist)
+ self['list'].setList(self.list)
+
+ def reloadPluginlist(self):
+ plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
+
class IpkgInstaller(Screen):
skin = """
<screen name="IpkgInstaller" position="center,center" size="550,450" title="Install extensions" >
@@ -1719,15 +1690,20 @@ def UpgradeMain(session, **kwargs):
def startSetup(menuid):
if menuid != "setup":
return [ ]
- return [(_("Software manager"), UpgradeMain, "software_manager", 50)]
+ return [(_("Software management"), UpgradeMain, "software_manager", 50)]
+
+def autostart(reason, **kwargs):
+ if reason is True:
+ iSoftwareTools.startSoftwareTools()
def Plugins(path, **kwargs):
global plugin_path
plugin_path = path
list = [
- PluginDescriptor(name=_("Software manager"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_MENU, fnc=startSetup),
+ PluginDescriptor(where = [PluginDescriptor.WHERE_NETWORKCONFIG_READ], fnc = autostart),
+ PluginDescriptor(name=_("Software management"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_MENU, fnc=startSetup),
PluginDescriptor(name=_("Ipkg"), where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)
]
if config.usage.setup_level.index >= 2: # expert+
- list.append(PluginDescriptor(name=_("Software manager"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=UpgradeMain))
+ list.append(PluginDescriptor(name=_("Software management"), description=_("Manage your receiver's software"), where = PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=UpgradeMain))
return list
diff --git a/lib/python/Plugins/SystemPlugins/Videomode/VideoWizard.py b/lib/python/Plugins/SystemPlugins/Videomode/VideoWizard.py
index cd1529aa..512bcec3 100644
--- a/lib/python/Plugins/SystemPlugins/Videomode/VideoWizard.py
+++ b/lib/python/Plugins/SystemPlugins/Videomode/VideoWizard.py
@@ -131,8 +131,12 @@ class VideoWizard(WizardLanguage, Rc):
def modeSelect(self, mode):
ratesList = self.listRates(mode)
print "ratesList:", ratesList
- self.hw.setMode(port = self.port, mode = mode, rate = ratesList[0][0])
-
+ if self.port == "DVI" and mode in ("720p", "1080i"):
+ self.rate = "multi"
+ self.hw.setMode(port = self.port, mode = mode, rate = "multi")
+ else:
+ self.hw.setMode(port = self.port, mode = mode, rate = ratesList[0][0])
+
def listRates(self, querymode = None):
if querymode is None:
querymode = self.mode
diff --git a/lib/python/Plugins/SystemPlugins/Videomode/videowizard.xml b/lib/python/Plugins/SystemPlugins/Videomode/videowizard.xml
index 29ac4297..5dea661d 100644
--- a/lib/python/Plugins/SystemPlugins/Videomode/videowizard.xml
+++ b/lib/python/Plugins/SystemPlugins/Videomode/videowizard.xml
@@ -20,7 +20,7 @@ self.selectKey("DOWN")
self["portpic"].hide()
</code>
</step>
- <step id="rateselection" nextstep="dvirateintroduction" timeout="20" timeoutaction="selectnext">
+ <step id="rateselection" nextstep="end" timeout="20" timeoutaction="selectnext">
<condition>
self.condition = (self.port != "DVI" or self.mode == "PC")
</condition>
@@ -33,7 +33,7 @@ self.selectKey("UP")
self.selectKey("DOWN")
</code>
</step>
- <step id="dvirateintroduction" nextstep="dvirateselection">
+ <!--step id="dvirateintroduction" nextstep="dvirateselection">
<condition>
self.condition = (self.port == "DVI" and self.mode in ["720p", "1080i"])
</condition>
@@ -89,7 +89,7 @@ self.selectKey("UP")
self.selectKey("DOWN")
self.rateSelect("50Hz")
</code>
- </step>
+ </step-->
<step id="end">
<code>
self.hw.saveMode(self.port, self.mode, self.rate)
diff --git a/lib/python/Screens/ChannelSelection.py b/lib/python/Screens/ChannelSelection.py
index 0432823b..5fbfd591 100644
--- a/lib/python/Screens/ChannelSelection.py
+++ b/lib/python/Screens/ChannelSelection.py
@@ -21,10 +21,13 @@ profile("ChannelSelection.py 2.3")
from Components.Input import Input
profile("ChannelSelection.py 3")
from Components.ParentalControl import parentalControl
+from Components.ChoiceList import ChoiceList, ChoiceEntryComponent
+from Components.SystemInfo import SystemInfo
from Screens.InputBox import InputBox, PinInput
from Screens.MessageBox import MessageBox
from Screens.ServiceInfo import ServiceInfo
profile("ChannelSelection.py 4")
+from Screens.PictureInPicture import PictureInPicture
from Screens.RdsDisplay import RassInteractive
from ServiceReference import ServiceReference
from Tools.BoundFunction import boundFunction
@@ -69,9 +72,9 @@ OFF = 0
EDIT_BOUQUET = 1
EDIT_ALTERNATIVES = 2
-def append_when_current_valid(current, menu, args, level = 0):
+def append_when_current_valid(current, menu, args, level = 0, key = ""):
if current and current.valid() and level <= config.usage.setup_level.index:
- menu.append(args)
+ menu.append(ChoiceEntryComponent(key, args))
class ChannelContextMenu(Screen):
def __init__(self, session, csel):
@@ -80,13 +83,15 @@ class ChannelContextMenu(Screen):
self.csel = csel
self.bsel = None
- self["actions"] = ActionMap(["OkCancelActions"],
+ self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "NumberActions"],
{
"ok": self.okbuttonClick,
- "cancel": self.cancelClick
+ "cancel": self.cancelClick,
+ "blue": self.showServiceInPiP
})
menu = [ ]
+ self.pipAvailable = False
current = csel.getCurrentSelection()
current_root = csel.getRoot()
current_sel_path = current.getPath()
@@ -122,8 +127,11 @@ class ChannelContextMenu(Screen):
append_when_current_valid(current, menu, (_("remove entry"), self.removeCurrentService), level = 0)
if current_root and current_root.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1:
append_when_current_valid(current, menu, (_("remove new found flag"), self.removeNewFoundFlag), level = 0)
+ if isPlayable and SystemInfo.get("NumVideoDecoders", 1) > 1:
+ append_when_current_valid(current, menu, (_("Activate Picture in Picture"), self.showServiceInPiP), level = 0, key = "blue")
+ self.pipAvailable = True
else:
- menu.append((_("add bouquet"), self.showBouquetInputBox))
+ menu.append(ChoiceEntryComponent(text = (_("add bouquet"), self.showBouquetInputBox)))
append_when_current_valid(current, menu, (_("remove entry"), self.removeBouquet), level = 0)
if inBouquet: # current list is editable?
@@ -131,7 +139,7 @@ class ChannelContextMenu(Screen):
if not csel.movemode:
append_when_current_valid(current, menu, (_("enable move mode"), self.toggleMoveMode), level = 1)
if not inBouquetRootList and current_root and not (current_root.flags & eServiceReference.isGroup):
- menu.append((_("add marker"), self.showMarkerInputBox))
+ menu.append(ChoiceEntryComponent(text = (_("add marker"), self.showMarkerInputBox)))
if haveBouquets:
append_when_current_valid(current, menu, (_("enable bouquet edit"), self.bouquetMarkStart), level = 0)
else:
@@ -156,11 +164,11 @@ class ChannelContextMenu(Screen):
append_when_current_valid(current, menu, (_("end alternatives edit"), self.bouquetMarkEnd), level = 0)
append_when_current_valid(current, menu, (_("abort alternatives edit"), self.bouquetMarkAbort), level = 0)
- menu.append((_("back"), self.cancelClick))
- self["menu"] = MenuList(menu)
+ menu.append(ChoiceEntryComponent(text = (_("back"), self.cancelClick)))
+ self["menu"] = ChoiceList(menu)
def okbuttonClick(self):
- self["menu"].getCurrent()[1]()
+ self["menu"].getCurrent()[0][1]()
def cancelClick(self):
self.close(False)
@@ -189,6 +197,23 @@ class ChannelContextMenu(Screen):
self.close()
else:
self.session.openWithCallback(self.close, MessageBox, _("The pin code you entered is wrong."), MessageBox.TYPE_ERROR)
+
+ def showServiceInPiP(self):
+ if not self.pipAvailable:
+ return
+ if self.session.pipshown:
+ del self.session.pip
+ self.session.pip = self.session.instantiateDialog(PictureInPicture)
+ self.session.pip.show()
+ newservice = self.csel.servicelist.getCurrent()
+ if self.session.pip.playService(newservice):
+ self.session.pipshown = True
+ self.session.pip.servicePath = self.csel.getCurrentServicePath()
+ self.close(True)
+ else:
+ self.session.pipshown = False
+ del self.session.pip
+ self.session.openWithCallback(self.close, MessageBox, _("Could not open Picture in Picture"), MessageBox.TYPE_ERROR)
def addServiceToBouquetSelected(self):
bouquets = self.csel.getBouquetList()
@@ -648,7 +673,11 @@ class ChannelSelectionEdit:
self.entry_marked = True
def doContext(self):
- self.session.open(ChannelContextMenu, self)
+ self.session.openWithCallback(self.exitContext, ChannelContextMenu, self)
+
+ def exitContext(self, close = False):
+ if close:
+ self.cancel()
MODE_TV = 0
MODE_RADIO = 1
diff --git a/lib/python/Screens/InfoBar.py b/lib/python/Screens/InfoBar.py
index a15c7ac1..5b061245 100644
--- a/lib/python/Screens/InfoBar.py
+++ b/lib/python/Screens/InfoBar.py
@@ -12,7 +12,7 @@ profile("LOAD:InfoBarGenerics")
from Screens.InfoBarGenerics import InfoBarShowHide, \
InfoBarNumberZap, InfoBarChannelSelection, InfoBarMenu, InfoBarRdsDecoder, \
InfoBarEPG, InfoBarSeek, InfoBarInstantRecord, \
- InfoBarAudioSelection, InfoBarAdditionalInfo, InfoBarNotifications, InfoBarDish, \
+ InfoBarAudioSelection, InfoBarAdditionalInfo, InfoBarNotifications, InfoBarDish, InfoBarUnhandledKey, \
InfoBarSubserviceSelection, InfoBarShowMovies, InfoBarTimeshift, \
InfoBarServiceNotifications, InfoBarPVRState, InfoBarCueSheetSupport, InfoBarSimpleEventView, \
InfoBarSummarySupport, InfoBarMoviePlayerSummarySupport, InfoBarTimeshiftState, InfoBarTeletextPlugin, InfoBarExtensions, \
@@ -29,7 +29,7 @@ from Screens.HelpMenu import HelpableScreen
class InfoBar(InfoBarBase, InfoBarShowHide,
InfoBarNumberZap, InfoBarChannelSelection, InfoBarMenu, InfoBarEPG, InfoBarRdsDecoder,
InfoBarInstantRecord, InfoBarAudioSelection,
- HelpableScreen, InfoBarAdditionalInfo, InfoBarNotifications, InfoBarDish,
+ HelpableScreen, InfoBarAdditionalInfo, InfoBarNotifications, InfoBarDish, InfoBarUnhandledKey,
InfoBarSubserviceSelection, InfoBarTimeshift, InfoBarSeek,
InfoBarSummarySupport, InfoBarTimeshiftState, InfoBarTeletextPlugin, InfoBarExtensions,
InfoBarPiP, InfoBarPlugins, InfoBarSubtitleSupport, InfoBarServiceErrorPopupSupport, InfoBarJobman,
@@ -52,7 +52,7 @@ class InfoBar(InfoBarBase, InfoBarShowHide,
for x in HelpableScreen, \
InfoBarBase, InfoBarShowHide, \
InfoBarNumberZap, InfoBarChannelSelection, InfoBarMenu, InfoBarEPG, InfoBarRdsDecoder, \
- InfoBarInstantRecord, InfoBarAudioSelection, \
+ InfoBarInstantRecord, InfoBarAudioSelection, InfoBarUnhandledKey, \
InfoBarAdditionalInfo, InfoBarNotifications, InfoBarDish, InfoBarSubserviceSelection, \
InfoBarTimeshift, InfoBarSeek, InfoBarSummarySupport, InfoBarTimeshiftState, \
InfoBarTeletextPlugin, InfoBarExtensions, InfoBarPiP, InfoBarSubtitleSupport, InfoBarJobman, \
diff --git a/lib/python/Screens/InfoBarGenerics.py b/lib/python/Screens/InfoBarGenerics.py
index a3e56a40..7ae0b123 100644
--- a/lib/python/Screens/InfoBarGenerics.py
+++ b/lib/python/Screens/InfoBarGenerics.py
@@ -26,13 +26,14 @@ from Screens.PictureInPicture import PictureInPicture
from Screens.SubtitleDisplay import SubtitleDisplay
from Screens.RdsDisplay import RdsInfoDisplay, RassInteractive
from Screens.TimeDateInput import TimeDateInput
+from Screens.UnhandledKey import UnhandledKey
from ServiceReference import ServiceReference
from Tools import Notifications
from Tools.Directories import fileExists
from enigma import eTimer, eServiceCenter, eDVBServicePMTHandler, iServiceInformation, \
- iPlayableService, eServiceReference, eEPGCache
+ iPlayableService, eServiceReference, eEPGCache, eActionMap
from time import time, localtime, strftime
from os import stat as os_stat
@@ -47,6 +48,39 @@ class InfoBarDish:
def __init__(self):
self.dishDialog = self.session.instantiateDialog(Dish)
+class InfoBarUnhandledKey:
+ def __init__(self):
+ self.unhandledKeyDialog = self.session.instantiateDialog(UnhandledKey)
+ self.hideUnhandledKeySymbolTimer = eTimer()
+ self.hideUnhandledKeySymbolTimer.callback.append(self.unhandledKeyDialog.hide)
+ self.checkUnusedTimer = eTimer()
+ self.checkUnusedTimer.callback.append(self.checkUnused)
+ self.onLayoutFinish.append(self.unhandledKeyDialog.hide)
+ eActionMap.getInstance().bindAction('', -0x7FFFFFFF, self.actionA) #highest prio
+ eActionMap.getInstance().bindAction('', 0x7FFFFFFF, self.actionB) #lowest prio
+ self.flags = (1<<1);
+ self.uflags = 0;
+
+ #this function is called on every keypress!
+ def actionA(self, key, flag):
+ if flag != 4:
+ if self.flags & (1<<1):
+ self.flags = self.uflags = 0
+ self.flags |= (1<<flag)
+ if flag == 1: # break
+ self.checkUnusedTimer.start(0, True)
+ return 0
+
+ #this function is only called when no other action has handled this key
+ def actionB(self, key, flag):
+ if flag != 4:
+ self.uflags |= (1<<flag)
+
+ def checkUnused(self):
+ if self.flags == self.uflags:
+ self.unhandledKeyDialog.show()
+ self.hideUnhandledKeySymbolTimer.start(2000, True)
+
class InfoBarShowHide:
""" InfoBar show/hide control, accepts toggleShow and hide actions, might start
fancy animations. """
@@ -691,6 +725,7 @@ class InfoBarSeek:
iPlayableService.evEOF: self.__evEOF,
iPlayableService.evSOF: self.__evSOF,
})
+ self.fast_winding_hint_message_showed = False
class InfoBarSeekActionMap(HelpableActionMap):
def __init__(self, screen, *args, **kwargs):
@@ -817,6 +852,7 @@ class InfoBarSeek:
# print "seekable"
def __serviceStarted(self):
+ self.fast_winding_hint_message_showed = False
self.seekstate = self.SEEK_STATE_PLAY
self.__seekableStatusChanged()
@@ -907,6 +943,13 @@ class InfoBarSeek:
self.showAfterSeek()
def seekFwd(self):
+ seek = self.getSeek()
+ if seek and not (seek.isCurrentlySeekable() & 2):
+ if not self.fast_winding_hint_message_showed and (seek.isCurrentlySeekable() & 1):
+ self.session.open(MessageBox, _("No fast winding possible yet.. but you can use the number buttons to skip forward/backward!"), MessageBox.TYPE_INFO, timeout=10)
+ self.fast_winding_hint_message_showed = True
+ return
+ return 0 # trade as unhandled action
if self.seekstate == self.SEEK_STATE_PLAY:
self.setSeekState(self.makeStateForward(int(config.seek.enter_forward.value)))
elif self.seekstate == self.SEEK_STATE_PAUSE:
@@ -936,6 +979,13 @@ class InfoBarSeek:
self.setSeekState(self.makeStateSlowMotion(speed))
def seekBack(self):
+ seek = self.getSeek()
+ if seek and not (seek.isCurrentlySeekable() & 2):
+ if not self.fast_winding_hint_message_showed and (seek.isCurrentlySeekable() & 1):
+ self.session.open(MessageBox, _("No fast winding possible yet.. but you can use the number buttons to skip forward/backward!"), MessageBox.TYPE_INFO, timeout=10)
+ self.fast_winding_hint_message_showed = True
+ return
+ return 0 # trade as unhandled action
seekstate = self.seekstate
if seekstate == self.SEEK_STATE_PLAY:
self.setSeekState(self.makeStateBackward(int(config.seek.enter_backward.value)))
diff --git a/lib/python/Screens/Makefile.am b/lib/python/Screens/Makefile.am
index 585983c2..5457bf64 100755
--- a/lib/python/Screens/Makefile.am
+++ b/lib/python/Screens/Makefile.am
@@ -14,5 +14,5 @@ install_PYTHON = \
SubtitleDisplay.py SubservicesQuickzap.py ParentalControlSetup.py NumericalTextInputHelpDialog.py \
SleepTimerEdit.py Ipkg.py RdsDisplay.py Globals.py DefaultWizard.py \
SessionGlobals.py LocationBox.py WizardLanguage.py TaskView.py Rc.py VirtualKeyBoard.py \
- TextBox.py FactoryReset.py RecordPaths.py
+ TextBox.py FactoryReset.py RecordPaths.py UnhandledKey.py
diff --git a/lib/python/Screens/PluginBrowser.py b/lib/python/Screens/PluginBrowser.py
index 61bb7d0a..cce08aed 100755
--- a/lib/python/Screens/PluginBrowser.py
+++ b/lib/python/Screens/PluginBrowser.py
@@ -9,7 +9,7 @@ from Components.Label import Label
from Screens.MessageBox import MessageBox
from Screens.Console import Console
from Plugins.Plugin import PluginDescriptor
-from Tools.Directories import resolveFilename, SCOPE_PLUGINS, SCOPE_SKIN_IMAGE
+from Tools.Directories import resolveFilename, fileExists, SCOPE_PLUGINS, SCOPE_SKIN_IMAGE
from Tools.LoadPixmap import LoadPixmap
from time import time
@@ -22,19 +22,23 @@ class PluginBrowser(Screen):
def __init__(self, session):
Screen.__init__(self, session)
- self["red"] = Label(_("Remove Plugins"))
- self["green"] = Label(_("Download Plugins"))
+ self["red"] = Label()
+ self["green"] = Label()
self.list = []
self["list"] = PluginList(self.list)
- self["actions"] = ActionMap(["WizardActions", "ColorActions"],
+ self["actions"] = ActionMap(["WizardActions"],
{
"ok": self.save,
"back": self.close,
+ })
+ self["PluginDownloadActions"] = ActionMap(["ColorActions"],
+ {
"red": self.delete,
"green": self.download
})
+ self["PluginDownloadActions"].setEnabled(False)
self.onFirstExecBegin.append(self.checkWarnings)
self.onShown.append(self.updateList)
@@ -47,7 +51,6 @@ class PluginBrowser(Screen):
self.session.open(MessageBox, text = text, type = MessageBox.TYPE_WARNING)
def save(self):
- #self.close()
self.run()
def run(self):
@@ -58,7 +61,15 @@ class PluginBrowser(Screen):
self.pluginlist = plugins.getPlugins(PluginDescriptor.WHERE_PLUGINMENU)
self.list = [PluginEntryComponent(plugin) for plugin in self.pluginlist]
self["list"].l.setList(self.list)
-
+ if fileExists(resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/plugin.py")):
+ self["red"].setText("")
+ self["green"].setText("")
+ self["PluginDownloadActions"].setEnabled(False)
+ else:
+ self["red"].setText(_("Remove Plugins"))
+ self["green"].setText(_("Download Plugins"))
+ self["PluginDownloadActions"].setEnabled(True)
+
def delete(self):
self.session.openWithCallback(self.PluginDownloadBrowserClosed, PluginDownloadBrowser, PluginDownloadBrowser.REMOVE)
diff --git a/lib/python/Screens/Satconfig.py b/lib/python/Screens/Satconfig.py
index e24e4636..d5249b99 100644
--- a/lib/python/Screens/Satconfig.py
+++ b/lib/python/Screens/Satconfig.py
@@ -5,7 +5,8 @@ from Components.ActionMap import ActionMap
from Components.ConfigList import ConfigListScreen
from Components.MenuList import MenuList
from Components.NimManager import nimmanager
-from Components.config import getConfigListEntry, config, ConfigNothing, ConfigSelection, updateConfigElement
+from Components.config import getConfigListEntry, config, ConfigNothing, ConfigSelection, updateConfigElement,\
+ ConfigSatlist
from Components.Sources.List import List
from Screens.MessageBox import MessageBox
from Screens.ChoiceBox import ChoiceBox
@@ -145,6 +146,8 @@ class NimSetup(Screen, ConfigListScreen):
currSat = self.nimConfig.advanced.sat[cur_orb_pos]
self.fillListWithAdvancedSatEntrys(currSat)
self.have_advanced = True
+ if self.nim.description == "Alps BSBE2" and config.usage.setup_level.index >= 2: # expert
+ self.list.append(getConfigListEntry(_("Tone Amplitude"), self.nimConfig.toneAmplitude))
elif self.nim.isCompatible("DVB-C"):
self.configMode = getConfigListEntry(_("Configuration Mode"), self.nimConfig.configMode)
self.list.append(self.configMode)
@@ -381,10 +384,11 @@ class NimSetup(Screen, ConfigListScreen):
ConfigListScreen.__init__(self, self.list)
- self["actions"] = ActionMap(["SetupActions"],
+ self["actions"] = ActionMap(["SetupActions", "SatlistShortcutAction"],
{
"ok": self.keySave,
"cancel": self.keyCancel,
+ "nothingconnected": self.nothingConnectedShortcut
}, -2)
self.slotid = slotid
@@ -421,6 +425,11 @@ class NimSetup(Screen, ConfigListScreen):
# we need to call saveAll to reset the connectedTo choices
self.saveAll()
self.close()
+
+ def nothingConnectedShortcut(self):
+ if type(self["config"].getCurrent()[1]) is ConfigSatlist:
+ self["config"].getCurrent()[1].setValue("3601")
+ self["config"].invalidateCurrent()
class NimSelection(Screen):
def __init__(self, session):
diff --git a/lib/python/Screens/UnhandledKey.py b/lib/python/Screens/UnhandledKey.py
new file mode 100644
index 00000000..63bfed5b
--- /dev/null
+++ b/lib/python/Screens/UnhandledKey.py
@@ -0,0 +1,7 @@
+from Screen import Screen
+from Components.Pixmap import Pixmap
+
+class UnhandledKey(Screen):
+ def __init__(self, session):
+ Screen.__init__(self, session)
+ self["UnhandledKeyPixmap"] = Pixmap()
diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp
index a6b6cc6f..69329ce0 100644
--- a/lib/service/servicedvb.cpp
+++ b/lib/service/servicedvb.cpp
@@ -1029,6 +1029,9 @@ void eDVBServicePlay::serviceEvent(int event)
m_event((iPlayableService*)this, evUpdatedInfo);
break;
}
+ case eDVBServicePMTHandler::eventPreStart:
+ loadCuesheet();
+ break;
case eDVBServicePMTHandler::eventEOF:
m_event((iPlayableService*)this, evEOF);
break;
@@ -1095,7 +1098,6 @@ RESULT eDVBServicePlay::start()
m_event_handler.inject(event, 0);
m_event_handler.inject(empty, 1);
}
- loadCuesheet();
m_event(this, evStart);
}
return 0;
@@ -1385,7 +1387,14 @@ RESULT eDVBServicePlay::setTrickmode(int trick)
RESULT eDVBServicePlay::isCurrentlySeekable()
{
- return m_is_pvr || m_timeshift_active;
+ int ret = 0;
+ if (m_decoder)
+ {
+ ret = (m_is_pvr || m_timeshift_active) ? 3 : 0; // fast forward/backward possible and seeking possible
+ if (m_decoder->getVideoWidth() == -1)
+ ret &= ~2;
+ }
+ return ret;
}
RESULT eDVBServicePlay::frontendInfo(ePtr<iFrontendInformation> &ptr)
diff --git a/lib/service/servicemp3.cpp b/lib/service/servicemp3.cpp
index 47511f78..2c84f7be 100644
--- a/lib/service/servicemp3.cpp
+++ b/lib/service/servicemp3.cpp
@@ -659,7 +659,31 @@ RESULT eServiceMP3::setTrickmode(int trick)
RESULT eServiceMP3::isCurrentlySeekable()
{
- return 1;
+ int ret = 3; // seeking and fast/slow winding possible
+ GstElement *sink;
+
+ if (!m_gst_playbin)
+ return 0;
+ if (m_state != stRunning)
+ return 0;
+
+ g_object_get (G_OBJECT (m_gst_playbin), "video-sink", &sink, NULL);
+
+ // disable fast winding yet when a dvbvideosink or dvbaudiosink is used
+ // for this we must do some changes on different places.. (gstreamer.. our sinks.. enigma2)
+ if (sink) {
+ ret &= ~2; // only seeking possible
+ gst_object_unref(sink);
+ }
+ else {
+ g_object_get (G_OBJECT (m_gst_playbin), "audio-sink", &sink, NULL);
+ if (sink) {
+ ret &= ~2; // only seeking possible
+ gst_object_unref(sink);
+ }
+ }
+
+ return ret;
}
RESULT eServiceMP3::info(ePtr<iServiceInformation>&i)
diff --git a/lib/service/servicexine.cpp b/lib/service/servicexine.cpp
index 44e6a6e0..6b9adfb9 100644
--- a/lib/service/servicexine.cpp
+++ b/lib/service/servicexine.cpp
@@ -315,7 +315,7 @@ RESULT eServiceXine::setTrickmode(int trick)
RESULT eServiceXine::isCurrentlySeekable()
{
- return 1;
+ return 3;
}
RESULT eServiceXine::info(ePtr<iServiceInformation>&i)
diff --git a/tools/genmetaindex.py b/tools/genmetaindex.py
index 82e79616..f7dc5b98 100755
--- a/tools/genmetaindex.py
+++ b/tools/genmetaindex.py
@@ -24,7 +24,7 @@ for file in sys.argv[2:]:
assert info
for i in info[:]:
- if i.tag not in ["name", "packagename", "shortdescription"]:
+ if i.tag not in ["name", "packagename", "packagetype", "shortdescription"]:
info.remove(i)
for i in info[:]: