Merge branch 'bug_271_ac3pcm_delay_servicemp3'
authorghost <andreas.monzner@multimedia-labs.de>
Tue, 22 Dec 2009 15:08:24 +0000 (16:08 +0100)
committerghost <andreas.monzner@multimedia-labs.de>
Tue, 22 Dec 2009 15:08:24 +0000 (16:08 +0100)
94 files changed:
RecordTimer.py
configure.ac
data/encoding.conf
data/menu.xml
data/setup.xml
data/skin_default.xml
doc/DEFAULTS
lib/dvb/decoder.cpp
lib/dvb/dvb.cpp
lib/dvb/epgcache.cpp
lib/dvb/epgcache.h
lib/dvb/lowlevel/mhw.h
lib/dvb/pvrparse.cpp
lib/dvb/tstools.cpp
lib/python/Components/AVSwitch.py
lib/python/Components/About.py
lib/python/Components/FileList.py
lib/python/Components/Harddisk.py
lib/python/Components/Lcd.py
lib/python/Components/NimManager.py
lib/python/Components/SystemInfo.py
lib/python/Components/UsageConfig.py
lib/python/Components/config.py
lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py
lib/python/Plugins/Extensions/MediaPlayer/plugin.py
lib/python/Plugins/Plugin.py
lib/python/Plugins/SystemPlugins/Makefile.am
lib/python/Plugins/SystemPlugins/NetworkWizard/LICENSE [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/NetworkWizard/Makefile.am [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/NetworkWizard/NetworkWizard.py [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/NetworkWizard/__init__.py [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/NetworkWizard/meta/Makefile.am [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/NetworkWizard/meta/plugin_networkwizard.xml [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/NetworkWizard/networkwizard.xml [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/NetworkWizard/plugin.py [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/Videomode/VideoWizard.py
lib/python/Plugins/SystemPlugins/WirelessLan/LICENSE [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/WirelessLan/Makefile.am [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/WirelessLan/Wlan.py [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/WirelessLan/__init__.py [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/WirelessLan/flags.py [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/WirelessLan/iwlibs.py [new file with mode: 0755]
lib/python/Plugins/SystemPlugins/WirelessLan/plugin.py [new file with mode: 0755]
lib/python/Plugins/newplugin.py
lib/python/Screens/EpgSelection.py
lib/python/Screens/EventView.py
lib/python/Screens/InfoBar.py
lib/python/Screens/InfoBarGenerics.py
lib/python/Screens/LocationBox.py
lib/python/Screens/Makefile.am
lib/python/Screens/Menu.py
lib/python/Screens/MovieSelection.py
lib/python/Screens/RecordPaths.py [new file with mode: 0644]
lib/python/Screens/ScanSetup.py
lib/python/Screens/SleepTimerEdit.py
lib/python/Screens/TaskView.py
lib/python/Screens/TimerEdit.py
lib/python/Screens/TimerEntry.py
lib/service/servicedvb.cpp
lib/service/servicedvb.h
lib/service/servicemp3.cpp
main/Makefile.am
main/enigma.cpp
po/Makefile.am
po/ar.po [changed mode: 0644->0755]
po/ca.po [changed mode: 0644->0755]
po/cs.po [changed mode: 0644->0755]
po/da.po [changed mode: 0644->0755]
po/de.po [changed mode: 0755->0644]
po/el.po [changed mode: 0644->0755]
po/en.po
po/enigma2.pot
po/es.po
po/et.po [changed mode: 0644->0755]
po/fi.po
po/fr.po
po/fy.po [changed mode: 0644->0755]
po/hr.po [changed mode: 0644->0755]
po/hu.po [changed mode: 0644->0755]
po/is.po [changed mode: 0644->0755]
po/it.po
po/lt.po [changed mode: 0644->0755]
po/lv.po [changed mode: 0644->0755]
po/nl.po
po/no.po [changed mode: 0644->0755]
po/pl.po
po/pt.po [changed mode: 0644->0755]
po/ru.po
po/sk.po [changed mode: 0644->0755]
po/sl.po [changed mode: 0644->0755]
po/sr.po [changed mode: 0644->0755]
po/sv.po
po/tr.po [changed mode: 0644->0755]
po/uk.po [changed mode: 0644->0755]

index 4907f64..f670417 100644 (file)
@@ -2,6 +2,7 @@ from enigma import eEPGCache, getBestPlayableServiceReference, \
        eServiceReference, iRecordableService, quitMainloop
 
 from Components.config import config
+from Components.UsageConfig import defaultMoviePath
 from Components.TimerSanityCheck import TimerSanityCheck
 
 from Screens.MessageBox import MessageBox
@@ -141,11 +142,13 @@ class RecordTimerEntry(timer.TimerEntry, object):
                if config.recording.ascii_filenames.value:
                        filename = ASCIItranslit.legacyEncode(filename)
 
-               if self.dirname and not Directories.fileExists(self.dirname, 'w'):
-                       self.dirnameHadToFallback = True
-                       self.Filename = Directories.getRecordingFilename(filename, None)
+               if not self.dirname or not Directories.fileExists(self.dirname, 'w'):
+                       if self.dirname:
+                               self.dirnameHadToFallback = True
+                       dirname = defaultMoviePath()
                else:
-                       self.Filename = Directories.getRecordingFilename(filename, self.dirname)
+                       dirname = self.dirname
+               self.Filename = Directories.getRecordingFilename(filename, dirname)
                self.log(0, "Filename calculated as: '%s'" % self.Filename)
                #begin_date + " - " + service_name + description)
 
index 2b557fc..5e403de 100755 (executable)
@@ -155,6 +155,8 @@ lib/python/Plugins/SystemPlugins/FrontprocessorUpgrade/meta/Makefile
 lib/python/Plugins/SystemPlugins/Hotplug/Makefile
 lib/python/Plugins/SystemPlugins/Hotplug/meta/Makefile
 lib/python/Plugins/SystemPlugins/Makefile
+lib/python/Plugins/SystemPlugins/NetworkWizard/Makefile
+lib/python/Plugins/SystemPlugins/NetworkWizard/meta/Makefile
 lib/python/Plugins/SystemPlugins/NFIFlash/Makefile
 lib/python/Plugins/SystemPlugins/NFIFlash/meta/Makefile
 lib/python/Plugins/SystemPlugins/PositionerSetup/Makefile
@@ -173,6 +175,7 @@ lib/python/Plugins/SystemPlugins/VideoTune/Makefile
 lib/python/Plugins/SystemPlugins/VideoTune/meta/Makefile
 lib/python/Plugins/SystemPlugins/Videomode/Makefile
 lib/python/Plugins/SystemPlugins/Videomode/meta/Makefile
+lib/python/Plugins/SystemPlugins/WirelessLan/Makefile
 lib/python/Tools/Makefile
 lib/service/Makefile
 lib/components/Makefile
index 14eeaef..9383317 100644 (file)
@@ -1,5 +1,6 @@
 #Fallback encoding when in dvb-text no encoding table is given
 #Countycode ISO8859-X or ISO6397
+ara ISO8859-6
 tur ISO8859-9
 gre ISO8859-7
 pol ISO8859-2
index c7fb889..59195f1 100644 (file)
@@ -70,7 +70,7 @@
                                        <item level="1" text="Device Setup..." entryID="device_setup"><screen module="NetworkSetup" screen="NetworkAdapterSelection"/></item>
                                        <item level="1" text="Nameserver Setup..." entryID="dns_setup"><screen module="NetworkSetup" screen="NameserverSetup"/></item>
                                </menu>-->
-                               <item level="2" text="Timeshift path..." entryId="timeshift_path"><screen module="LocationBox" screen="TimeshiftLocationBox" /></item>
+                               <item level="2" text="Recording paths..." entryId="RecordPaths"><screen module="RecordPaths" screen="RecordPathsSettings" /></item>
                        </menu>
                        <item weight="10" level="1" text="Common Interface" entryID="ci_setup" requires="CommonInterface"><screen module="Ci" screen="CiSelection" /></item>
                        <item weight="15" level="0" text="Parental control" entryID="parental_setup"><screen module="ParentalControlSetup" screen="ParentalControlSetup" /></item>
@@ -104,6 +104,7 @@ self.session.openWithCallback(msgClosed, FactoryReset)
                        <item text="Standby" entryID="standby"><screen module="Standby" screen="Standby"/></item>
                        <item text="Restart" entryID="restart"><screen module="Standby" screen="TryQuitMainloop">2</screen></item>
                        <item level="2" text="Restart GUI" entryID="restart_enigma"><screen module="Standby" screen="TryQuitMainloop">3</screen></item>
-                       <item text="Deep Standby" entryID="deep_standby"><screen module="Standby" screen="TryQuitMainloop">1</screen></item>
+                       <item text="Deep Standby" requires="DeepstandbySupport" entryID="deep_standby"><screen module="Standby" screen="TryQuitMainloop">1</screen></item>
+                       <item text="Shutdown" requires="!DeepstandbySupport" entryID="deep_standby"><screen module="Standby" screen="TryQuitMainloop">1</screen></item>
                </menu>
 </menu>
index 22705f0..9425afd 100644 (file)
@@ -13,8 +13,8 @@
                        <item level="0" text="TV System">config.av.tvsystem</item>
                        <item level="1" text="WSS on 4:3">config.av.wss</item>
                        <item level="1" text="AC3 default">config.av.defaultac3</item>
-                       <item level="1" text="General AC3 delay">config.av.generalAC3delay</item>
-                       <item level="1" text="General PCM delay">config.av.generalPCMdelay</item>
+                       <item level="1" text="General AC3 delay (ms)">config.av.generalAC3delay</item>
+                       <item level="1" text="General PCM delay (ms)">config.av.generalPCMdelay</item>
                        <item level="1" text="AC3 downmix" requires="CanDownmixAC3">config.av.downmix_ac3</item>
                        <item level="1" text="Auto scart switching" requires="ScartSwitch">config.av.vcrswitch</item>
                </setup>
index 72dc357..16504ab 100755 (executable)
@@ -803,9 +803,9 @@ self.instance.move(ePoint(orgpos.x() + (orgwidth - newwidth)/2, orgpos.y()))
                <widget name="config" position="10,165" size="500,225" scrollbarMode="showOnDemand" />
        </screen>
        <!-- Scan setup -->
-       <screen name="ScanSetup" position="center,center" size="520,390" title="Service scan">
+       <screen name="ScanSetup" position="center,center" size="520,450" title="Service scan">
                <widget name="config" position="10,10" size="500,350" scrollbarMode="showOnDemand" />
-               <widget name="introduction" position="10,365" size="500,25" font="Regular;20" halign="center" />
+               <widget name="introduction" position="10,365" size="500,75" font="Regular;20" halign="center" />
        </screen>
        <!-- Scan simple -->
        <screen name="ScanSimple" position="center,center" size="420,350" title="Service scan">
index b61696f..669652e 100644 (file)
@@ -92,7 +92,7 @@ So this would only install the lamedb.192 file, if you have a DVB-S NIM in your
 - "image default"
   An image default is stored in /usr/share/enigma2/defaults. You can have several defaults at the same time, but you should keep
   in mind, that these defaults are all installed without user interaction. So defaults with contrary contents should be avoided
-  (e.g. setting a default parameter in one settings file an setting another setting for the same parameter in another could lead
+  (e.g. setting a default parameter in one settings file and setting another setting for the same parameter in another could lead
   to unexpected behaviour, since the installation order is undetermined and completely random. so use prerequisites insted)
   The "image default" is also used to set box specific config elements (for example show the new RC on a dm8000) and install the
   default bouquets.
index 0935069..ef8dadc 100644 (file)
@@ -222,9 +222,6 @@ int eDVBAudio::startPid(int pid, int type)
 
 void eDVBAudio::stop()
 {
-#if HAVE_DVB_API_VERSION > 2
-       flush();
-#endif
        eDebugNoNewLine("AUDIO_STOP - ");
        if (::ioctl(m_fd, AUDIO_STOP) < 0)
                eDebug("failed (%m)");
index 894287e..a8dfb19 100644 (file)
@@ -1462,12 +1462,7 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off
                        continue;
                }
                
-               size_t iframe_len;
-                       /* try to align to iframe */
-               int direction = pts < 0 ? -1 : 1;
-               m_tstools.findFrame(offset, iframe_len, direction);
-
-               eDebug("ok, resolved skip (rel: %d, diff %lld), now at %08llx (skipped additional %d frames due to iframe re-align)", relative, pts, offset, direction);
+               eDebug("ok, resolved skip (rel: %d, diff %lld), now at %08llx", relative, pts, offset);
                current_offset = align(offset, blocksize); /* in case tstools return non-aligned offset */
        }
 
index f80e177..48cbfbf 100644 (file)
@@ -255,6 +255,11 @@ void eEPGCache::DVBChannelAdded(eDVBChannel *chan)
 #ifdef ENABLE_PRIVATE_EPG
                data->m_PrivatePid = -1;
 #endif
+#ifdef ENABLE_MHW_EPG
+               data->m_mhw2_channel_pid = 0x231; // defaults for astra 19.2 D+
+               data->m_mhw2_title_pid = 0x234; // defaults for astra 19.2 D+
+               data->m_mhw2_summary_pid = 0x236; // defaults for astra 19.2 D+
+#endif
                singleLock s(channel_map_lock);
                m_knownChannels.insert( std::pair<iDVBChannel*, channel_data* >(chan, data) );
                chan->connectStateChange(slot(*this, &eEPGCache::DVBChannelStateChanged), data->m_stateChangedConn);
@@ -880,6 +885,62 @@ void eEPGCache::gotMessage( const Message &msg )
                        break;
                }
 #endif
+#ifdef ENABLE_MHW_EPG
+               case Message::got_mhw2_channel_pid:
+               {
+                       singleLock s(channel_map_lock);
+                       for (channelMapIterator it(m_knownChannels.begin()); it != m_knownChannels.end(); ++it)
+                       {
+                               eDVBChannel *channel = (eDVBChannel*) it->first;
+                               channel_data *data = it->second;
+                               eDVBChannelID chid = channel->getChannelID();
+                               if ( chid.transport_stream_id.get() == msg.service.tsid &&
+                                       chid.original_network_id.get() == msg.service.onid )
+                               {
+                                       data->m_mhw2_channel_pid = msg.pid;
+                                       eDebug("[EPGC] got mhw2 channel pid %04x", msg.pid);
+                                       break;
+                               }
+                       }
+                       break;
+               }
+               case Message::got_mhw2_title_pid:
+               {
+                       singleLock s(channel_map_lock);
+                       for (channelMapIterator it(m_knownChannels.begin()); it != m_knownChannels.end(); ++it)
+                       {
+                               eDVBChannel *channel = (eDVBChannel*) it->first;
+                               channel_data *data = it->second;
+                               eDVBChannelID chid = channel->getChannelID();
+                               if ( chid.transport_stream_id.get() == msg.service.tsid &&
+                                       chid.original_network_id.get() == msg.service.onid )
+                               {
+                                       data->m_mhw2_title_pid = msg.pid;
+                                       eDebug("[EPGC] got mhw2 title pid %04x", msg.pid);
+                                       break;
+                               }
+                       }
+                       break;
+               }
+               case Message::got_mhw2_summary_pid:
+               {
+                       singleLock s(channel_map_lock);
+                       for (channelMapIterator it(m_knownChannels.begin()); it != m_knownChannels.end(); ++it)
+                       {
+                               eDVBChannel *channel = (eDVBChannel*) it->first;
+                               channel_data *data = it->second;
+                               eDVBChannelID chid = channel->getChannelID();
+                               if ( chid.transport_stream_id.get() == msg.service.tsid &&
+                                       chid.original_network_id.get() == msg.service.onid )
+                               {
+                                       data->m_mhw2_summary_pid = msg.pid;
+                                       eDebug("[EPGC] got mhw2 summary pid %04x", msg.pid);
+                                       break;
+                               }
+                       }
+                       break;
+               }
+#endif
                case Message::timeChanged:
                        cleanLoop();
                        break;
@@ -1175,7 +1236,7 @@ void eEPGCache::channel_data::startEPG()
        isRunning |= MHW;
        memcpy(&m_MHWFilterMask, &mask, sizeof(eDVBSectionFilterMask));
 
-       mask.pid = 0x231;
+       mask.pid = m_mhw2_channel_pid;
        mask.data[0] = 0xC8;
        mask.mask[0] = 0xFF;
        mask.data[1] = 0;
@@ -1186,6 +1247,7 @@ void eEPGCache::channel_data::startEPG()
        memcpy(&m_MHWFilterMask2, &mask, sizeof(eDVBSectionFilterMask));
        mask.data[1] = 0;
        mask.mask[1] = 0;
+       m_MHWTimeoutet=false;
 #endif
 
        mask.pid = 0x12;
@@ -1717,6 +1779,7 @@ void fillTuple(ePyObject tuple, const char *argstring, int argcount, ePyObject s
                                ++argcount;
                                continue;
                        default:  // ignore unknown
+                               tmp = ePyObject();
                                eDebug("fillTuple unknown '%c'... insert 'None' in result", c);
                }
                if (!tmp)
@@ -2061,6 +2124,7 @@ void fillTuple2(ePyObject tuple, const char *argstring, int argcount, eventData
                                inc_refcount = true;
                                break;
                        default:  // ignore unknown
+                               tmp = ePyObject();
                                eDebug("fillTuple2 unknown '%c'... insert None in Result", argstring[pos]);
                }
                if (!tmp)
@@ -2487,6 +2551,50 @@ void eEPGCache::PMTready(eDVBServicePMTHandler *pmthandler)
                                int tmp=0;
                                switch ((*es)->getType())
                                {
+                               case 0xC1: // user private
+                                       for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin();
+                                               desc != (*es)->getDescriptors()->end(); ++desc)
+                                       {
+                                               switch ((*desc)->getTag())
+                                               {
+                                                       case 0xC2: // user defined
+                                                               if ((*desc)->getLength() == 8) 
+                                                               {
+                                                                       __u8 buffer[10];
+                                                                       (*desc)->writeToBuffer(buffer);
+                                                                       if (!strncmp((unsigned char*)buffer+2, "EPGDATA", 7))
+                                                                       {
+                                                                               eServiceReferenceDVB ref;
+                                                                               if (!pmthandler->getServiceReference(ref))
+                                                                               {
+                                                                                       int pid = (*es)->getPid();
+                                                                                       messages.send(Message(Message::got_mhw2_channel_pid, ref, pid));
+                                                                               }
+                                                                       }
+                                                                       else if(!strncmp((unsigned char*)buffer+2, "FICHAS", 6))
+                                                                       {
+                                                                               eServiceReferenceDVB ref;
+                                                                               if (!pmthandler->getServiceReference(ref))
+                                                                               {
+                                                                                       int pid = (*es)->getPid();
+                                                                                       messages.send(Message(Message::got_mhw2_summary_pid, ref, pid));
+                                                                               }
+                                                                       }
+                                                                       else if(!strncmp((unsigned char*)buffer+2, "GENEROS", 7))
+                                                                       {
+                                                                               eServiceReferenceDVB ref;
+                                                                               if (!pmthandler->getServiceReference(ref))
+                                                                               {
+                                                                                       int pid = (*es)->getPid();
+                                                                                       messages.send(Message(Message::got_mhw2_title_pid, ref, pid));
+                                                                               }
+                                                                       }
+                                                               }
+                                                               break;
+                                                       default:
+                                                               break;
+                                               }
+                                       }
                                case 0x05: // private
                                        for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin();
                                                desc != (*es)->getDescriptors()->end(); ++desc)
@@ -2891,7 +2999,7 @@ void eEPGCache::channel_data::storeTitle(std::map<__u32, mhw_title_t>::iterator
        packet->segment_last_table_id = 0x50;
 
        __u8 *title = isMHW2 ? ((__u8*)(itTitle->second.title))-4 : (__u8*)itTitle->second.title;
-       std::string prog_title = (char *) delimitName( title, name, isMHW2 ? 33 : 23 );
+       std::string prog_title = (char *) delimitName( title, name, isMHW2 ? 35 : 23 );
        int prog_title_length = prog_title.length();
 
        int packet_length = EIT_SIZE + EIT_LOOP_SIZE + EIT_SHORT_EVENT_DESCRIPTOR_SIZE +
@@ -3220,14 +3328,14 @@ void eEPGCache::channel_data::readMHWData2(const __u8 *data)
        {
                eDebug("[EPGC] mhw2 aborted %d", state);
        }
-       else if (m_MHWFilterMask2.pid == 0x231 && m_MHWFilterMask2.data[0] == 0xC8 && m_MHWFilterMask2.data[1] == 0)
+       else if (m_MHWFilterMask2.pid == m_mhw2_channel_pid && m_MHWFilterMask2.data[0] == 0xC8 && m_MHWFilterMask2.data[1] == 0)
        // Channels table
        {
-               int num_channels = data[119];
+               int num_channels = data[120];
                m_channels.resize(num_channels);
-               if(dataLen > 119)
+               if(dataLen > 120)
                {
-                       int ptr = 120 + 8 * num_channels;
+                       int ptr = 121 + 8 * num_channels;
                        if( dataLen > ptr )
                        {
                                for( int chid = 0; chid < num_channels; ++chid )
@@ -3243,7 +3351,7 @@ void eEPGCache::channel_data::readMHWData2(const __u8 *data)
                else
                        goto abort;
                // data seems consistent...
-               const __u8 *tmp = data+120;
+               const __u8 *tmp = data+121;
                for (int i=0; i < num_channels; ++i)
                {
                        mhw_channel_name_t channel;
@@ -3254,6 +3362,7 @@ void eEPGCache::channel_data::readMHWData2(const __u8 *data)
                        channel.channel_id_hi = *(tmp++);
                        channel.channel_id_lo = *(tmp++);
                        m_channels[i]=channel;
+//                     eDebug("%d(%02x) %04x: %02x %02x", i, i, (channel.channel_id_hi << 8) | channel.channel_id_lo, *tmp, *(tmp+1));
                        tmp+=2;
                }
                for (int i=0; i < num_channels; ++i)
@@ -3264,83 +3373,86 @@ void eEPGCache::channel_data::readMHWData2(const __u8 *data)
                        for (; x < channel_name_len; ++x)
                                channel.name[x]=*(tmp++);
                        channel.name[x+1]=0;
+//                     eDebug("%d(%02x) %s", i, i, channel.name);
                }
                haveData |= MHW;
                eDebug("[EPGC] mhw2 %d channels found", m_channels.size());
        }
-       else if (m_MHWFilterMask2.pid == 0x231 && m_MHWFilterMask2.data[0] == 0xC8 && m_MHWFilterMask2.data[1] == 1)
+       else if (m_MHWFilterMask2.pid == m_mhw2_channel_pid && m_MHWFilterMask2.data[0] == 0xC8 && m_MHWFilterMask2.data[1] == 1)
        {
                // Themes table
                eDebug("[EPGC] mhw2 themes nyi");
        }
-       else if (m_MHWFilterMask2.pid == 0x234 && m_MHWFilterMask2.data[0] == 0xe6)
+       else if (m_MHWFilterMask2.pid == m_mhw2_title_pid && m_MHWFilterMask2.data[0] == 0xe6)
        // Titles table
        {
                int pos=18;
-               bool valid=true;
-               int len = ((data[1]&0xf)<<8) + data[2] - 16;
+               bool valid=false;
                bool finish=false;
-               if(data[dataLen-1] != 0xff)
-                       return;
-               while( pos < dataLen )
+
+//             eDebug("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
+//                     data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10],
+//                     data[11], data[12], data[13], data[14], data[15], data[16], data[17] );
+
+               while( pos < dataLen && !valid)
                {
-                       valid = false;
-                       pos += 7;
-                       if( pos < dataLen )
-                       {
-                               pos += 3;
-                               if( pos < dataLen )
-                               {
-                                       if( data[pos] > 0xc0 )
-                                       {
-                                               pos += ( data[pos] - 0xc0 );
-                                               pos += 4;
-                                               if( pos < dataLen )
-                                               {
-                                                       if( data[pos] == 0xff )
-                                                       {
-                                                               ++pos;
-                                                               valid = true;
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-                       if( !valid )
-                       {
-                               if (checkTimeout())
-                                       goto start_summary;
-                               return;
-                       }
+                       pos += 18;
+                       pos += (data[pos] & 0x3F) + 4;
+                       if( pos == dataLen )
+                               valid = true;
                }
+
+               if (!valid)
+               {
+                       if (dataLen > 18)
+                               eDebug("mhw2 title table invalid!!");
+                       if (checkTimeout())
+                               goto abort;
+                       if (!m_MHWTimeoutTimer->isActive())
+                               startTimeout(5000);
+                       return; // continue reading
+               }
+
                // data seems consistent...
                mhw_title_t title;
                pos = 18;
-               while (pos < len)
+               while (pos < dataLen)
                {
+//                     eDebugNoNewLine("    [%02x] %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x [%02x %02x %02x %02x %02x %02x %02x] LL - DESCR - ",
+//                             data[pos], data[pos+1], data[pos+2], data[pos+3], data[pos+4], data[pos+5], data[pos+6], data[pos+7], 
+//                             data[pos+8], data[pos+9], data[pos+10], data[pos+11], data[pos+12], data[pos+13], data[pos+14], data[pos+15], data[pos+16], data[pos+17]);
                        title.channel_id = data[pos]+1;
-                       title.program_id_ml = data[pos+1];
-                       title.program_id_lo = data[pos+2];
-                       title.mhw2_mjd_hi = data[pos+3];
-                       title.mhw2_mjd_lo = data[pos+4];
-                       title.mhw2_hours = data[pos+5];
-                       title.mhw2_minutes = data[pos+6];
-                       title.mhw2_seconds = data[pos+7];
-                       int duration = ((data[pos+8] << 8)|data[pos+9]) >> 4;
+                       title.mhw2_mjd_hi = data[pos+11];
+                       title.mhw2_mjd_lo = data[pos+12];
+                       title.mhw2_hours = data[pos+13];
+                       title.mhw2_minutes = data[pos+14];
+                       title.mhw2_seconds = data[pos+15];
+                       int duration = ((data[pos+16] << 8)|data[pos+17]) >> 4;
                        title.mhw2_duration_hi = (duration&0xFF00) >> 8;
                        title.mhw2_duration_lo = duration&0xFF;
-                       __u8 slen = data[pos+10] & 0x3f;
+
+                       // Create unique key per title
+                       __u32 title_id = (data[pos+7] << 24) | (data[pos+8] << 16) | (data[pos+9] << 8) | data[pos+10];
+
+                       __u8 slen = data[pos+18] & 0x3f;
                        __u8 *dest = ((__u8*)title.title)-4;
-                       memcpy(dest, &data[pos+11], slen>33 ? 33 : slen);
-                       memset(dest+slen, 0, 33-slen);
-                       pos += 11 + slen;
+                       memcpy(dest, &data[pos+19], slen>35 ? 35 : slen);
+                       memset(dest+slen, 0, 35-slen);
+                       pos += 19 + slen;
+//                     eDebug("%02x [%02x %02x]: %s", data[pos], data[pos+1], data[pos+2], dest);
+
 //                     not used theme id (data[7] & 0x3f) + (data[pos] & 0x3f);
                        __u32 summary_id = (data[pos+1] << 8) | data[pos+2];
 
-                       // Create unique key per title
-                       __u32 title_id = (title.channel_id<<16) | (title.program_id_ml<<8) | title.program_id_lo;
+//                     if (title.channel_id > m_channels.size())
+//                             eDebug("channel_id(%d %02x) to big!!", title.channel_id);
+
+//                     eDebug("pos %d prog_id %02x %02x chid %02x summary_id %04x dest %p len %d\n",
+//                             pos, title.program_id_ml, title.program_id_lo, title.channel_id, summary_id, dest, slen);
 
-                       pos += 4;
+//                     eDebug("title_id %08x -> summary_id %04x\n", title_id, summary_id);
+
+                       pos += 3;
 
                        std::map<__u32, mhw_title_t>::iterator it = m_titles.find( title_id );
                        if ( it == m_titles.end() )
@@ -3379,7 +3491,7 @@ start_summary:
                        {
                                // Titles table has been read, there are summaries to read.
                                // Start reading summaries, store corresponding titles on the fly.
-                               startMHWReader2(0x236, 0x96);
+                               startMHWReader2(m_mhw2_summary_pid, 0x96);
                                startTimeout(15000);
                                return;
                        }
@@ -3387,7 +3499,7 @@ start_summary:
                else
                        return;
        }
-       else if (m_MHWFilterMask2.pid == 0x236 && m_MHWFilterMask2.data[0] == 0x96)
+       else if (m_MHWFilterMask2.pid == m_mhw2_summary_pid && m_MHWFilterMask2.data[0] == 0x96)
        // Summaries table
        {
                if (!checkTimeout())
@@ -3421,10 +3533,13 @@ start_summary:
                        }
                        else
                                return;  // continue reading
+
                        if (valid)
                        {
                                // data seems consistent...
                                __u32 summary_id = (data[3]<<8)|data[4];
+//                             eDebug ("summary id %04x\n", summary_id);
+//                             eDebug("[%02x %02x] %02x %02x %02x %02x %02x %02x %02x %02x XX\n", data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11], data[12], data[13] );
 
                                // ugly workaround to convert const __u8* to char*
                                char *tmp=0;
@@ -3442,7 +3557,7 @@ start_summary:
                                        len += lenline + 1;
                                }
                                if( len > 0 )
-                                   tmp[pos+len] = 0;
+                                       tmp[pos+len] = 0;
                                else
                                        tmp[pos+1] = 0;
 
@@ -3458,8 +3573,11 @@ start_summary:
                                        startTimeout(15000);
                                        std::string the_text = (char *) (data + pos + 1);
 
+//                                     eDebug ("summary id %04x : %s\n", summary_id, data+pos+1);
+
                                        while( itProgId != m_program_ids.end() && itProgId->first == summary_id )
                                        {
+//                                             eDebug(".");
                                                // Find corresponding title, store title and summary in epgcache.
                                                std::map<__u32, mhw_title_t>::iterator itTitle( m_titles.find( itProgId->second ) );
                                                if ( itTitle != m_titles.end() )
@@ -3479,16 +3597,16 @@ start_summary:
        }
        if (isRunning & eEPGCache::MHW)
        {
-               if ( m_MHWFilterMask2.pid == 0x231 && m_MHWFilterMask2.data[0] == 0xC8 && m_MHWFilterMask2.data[1] == 0)
+               if ( m_MHWFilterMask2.pid == m_mhw2_channel_pid && m_MHWFilterMask2.data[0] == 0xC8 && m_MHWFilterMask2.data[1] == 0)
                {
                        // Channels table has been read, start reading the themes table.
-                       startMHWReader2(0x231, 0xC8, 1);
+                       startMHWReader2(m_mhw2_channel_pid, 0xC8, 1);
                        return;
                }
-               else if ( m_MHWFilterMask2.pid == 0x231 && m_MHWFilterMask2.data[0] == 0xC8 && m_MHWFilterMask2.data[1] == 1)
+               else if ( m_MHWFilterMask2.pid == m_mhw2_channel_pid && m_MHWFilterMask2.data[0] == 0xC8 && m_MHWFilterMask2.data[1] == 1)
                {
                        // Themes table has been read, start reading the titles table.
-                       startMHWReader2(0x234, 0xe6);
+                       startMHWReader2(m_mhw2_title_pid, 0xe6);
                        return;
                }
                else
index 7d1b163..4d45d87 100644 (file)
@@ -202,6 +202,7 @@ class eEPGCache: public eMainloop, private eThread, public Object
                ePtr<iDVBSectionReader> m_MHWReader, m_MHWReader2;
                eDVBSectionFilterMask m_MHWFilterMask, m_MHWFilterMask2;
                ePtr<eTimer> m_MHWTimeoutTimer;
+               __u16 m_mhw2_channel_pid, m_mhw2_title_pid, m_mhw2_summary_pid;
                bool m_MHWTimeoutet;
                void MHWTimeout() { m_MHWTimeoutet=true; }
                void readMHWData(const __u8 *data);
@@ -242,6 +243,9 @@ public:
                        leaveChannel,
                        quit,
                        got_private_pid,
+                       got_mhw2_channel_pid,
+                       got_mhw2_title_pid,
+                       got_mhw2_summary_pid,
                        timeChanged
                };
                int type;
index 0b4904f..f06c86e 100644 (file)
@@ -78,9 +78,9 @@ typedef struct {
    u_char ppv_id_ml                              :8;
    u_char ppv_id_lo                              :8;
    u_char program_id_hi                          :8;
-   u_char program_id_mh                          :8; // mhw2_title end (33chars max)
+   u_char program_id_mh                          :8;
    u_char program_id_ml                          :8;
-   u_char program_id_lo                          :8;
+   u_char program_id_lo                          :8; // mhw2_title end (35chars max)
    u_char mhw2_mjd_hi                            :8;
    u_char mhw2_mjd_lo                            :8;
    u_char mhw2_duration_hi                       :8;
index 1393bf7..5cdecbd 100644 (file)
@@ -244,6 +244,7 @@ off_t eMPEGStreamInformation::getAccessPoint(pts_t ts, int marg)
        off_t last = 0;
        off_t last2 = 0;
        pts_t lastc = 0;
+       ts += 1; // Add rounding error margin
        for (std::map<off_t, pts_t>::const_iterator i(m_access_points.begin()); i != m_access_points.end(); ++i)
        {
                pts_t delta = getDelta(i->first);
index a9eef40..b7ea945 100644 (file)
@@ -134,7 +134,7 @@ int eDVBTSTools::getPTS(off_t &offset, pts_t &pts, int fixed)
                                        pts |= ((unsigned long long)(packet[ 9]&0xFF)) << 1;
                                        pts |= ((unsigned long long)(packet[10]&0x80)) >> 7;
                                        offset -= 188;
-                                       eDebug("PCR  found at %llx: %16llx", offset, pts);
+                                       eDebug("PCR %16llx found at %lld pid %02x (%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x)", pts, offset, pid, packet[0], packet[1], packet[2], packet[3], packet[4], packet[5], packet[6], packet[7], packet[8], packet[9], packet[10]);
                                        if (fixed && fixupPTS(offset, pts))
                                                return -1;
                                        return 0;
@@ -171,11 +171,11 @@ int eDVBTSTools::getPTS(off_t &offset, pts_t &pts, int fixed)
                        pts |= ((unsigned long long)(payload[13]&0xFE)) >> 1;
                        offset -= 188;
 
-//                     eDebug("found pts %08llx at %08llx pid %02x stream: %02x", pts, offset, pid, payload[3]);
-                       
+                       eDebug("PTS %16llx found at %lld pid %02x stream: %02x", pts, offset, pid, payload[3]);
+
                                /* convert to zero-based */
                        if (fixed && fixupPTS(offset, pts))
-                                       return -1;
+                               return -1;
                        return 0;
                }
        }
@@ -212,10 +212,13 @@ int eDVBTSTools::fixupPTS(const off_t &offset, pts_t &now)
                        now -= pos;
                return 0;
        }
+       eDebug("eDVBTSTools::fixupPTS failed!");
+       return -1;
 }
 
 int eDVBTSTools::getOffset(off_t &offset, pts_t &pts, int marg)
 {
+       eDebug("getOffset for pts 0x%llx", pts);
        if (m_use_streaminfo)
        {
                if (pts >= m_pts_end && marg > 0 && m_end_valid)
@@ -440,6 +443,8 @@ void eDVBTSTools::takeSamples()
        m_samples_taken = 1;
        m_samples.clear();
        pts_t dummy;
+       int retries=2;
+
        if (calcLen(dummy) == -1)
                return;
        
@@ -449,21 +454,27 @@ void eDVBTSTools::takeSamples()
                bytes_per_sample = 40*1024*1024;
 
        bytes_per_sample -= bytes_per_sample % 188;
-       
-       for (off_t offset = m_offset_begin; offset < m_offset_end; offset += bytes_per_sample)
+
+       eDebug("samples step %lld, pts begin %llx, pts end %llx, offs begin %lld, offs end %lld:",
+               bytes_per_sample, m_pts_begin, m_pts_end, m_offset_begin, m_offset_end);
+
+       for (off_t offset = m_offset_begin; offset < m_offset_end;)
        {
                pts_t p;
-               takeSample(offset, p);
+               if (takeSample(offset, p) && retries--)
+                       continue;
+               retries = 2;
+               offset += bytes_per_sample;
        }
        m_samples[0] = m_offset_begin;
        m_samples[m_pts_end - m_pts_begin] = m_offset_end;
-       
-//     eDebug("begin, end: %llx %llx", m_offset_begin, m_offset_end); 
 }
 
        /* returns 0 when a sample was taken. */
 int eDVBTSTools::takeSample(off_t off, pts_t &p)
 {
+       off_t offset_org = off;
+
        if (!eDVBTSTools::getPTS(off, p, 1))
        {
                        /* as we are happily mixing PTS and PCR values (no comment, please), we might
@@ -481,18 +492,18 @@ int eDVBTSTools::takeSample(off_t off, pts_t &p)
                        {
                                if ((l->second > off) || (u->second < off))
                                {
-                                       eDebug("ignoring sample %llx %llx %llx (%lld %lld %lld)",
+                                       eDebug("ignoring sample %lld %lld %lld (%llx %llx %llx)",
                                                l->second, off, u->second, l->first, p, u->first);
                                        return 1;
                                }
                        }
                }
 
-               
+               eDebug("adding sample %lld: pts 0x%llx -> pos %lld (diff %lld bytes)", offset_org, p, off, off-offset_org);
                m_samples[p] = off;
                return 0;
        }
-       return 1;
+       return -1;
 }
 
 int eDVBTSTools::findPMT(int &pmt_pid, int &service_id)
@@ -652,18 +663,23 @@ int eDVBTSTools::findFrame(off_t &_offset, size_t &len, int &direction, int fram
 
 int eDVBTSTools::findNextPicture(off_t &offset, size_t &len, int &distance, int frame_types)
 {
-       int nr_frames = 0;
+       int nr_frames, direction;
 //     eDebug("trying to move %d frames at %llx", distance, offset);
        
        frame_types = frametypeI; /* TODO: intelligent "allow IP frames when not crossing an I-Frame */
 
-       int direction = distance > 0 ? 0 : -1;
-       distance = abs(distance);
-       
        off_t new_offset = offset;
        size_t new_len = len;
        int first = 1;
 
+       if (distance > 0) {
+               direction = 0;
+                nr_frames = 0;
+        } else {
+               direction = -1;
+                nr_frames = -1;
+               distance = -distance+1;
+        }      
        while (distance > 0)
        {
                int dir = direction;
@@ -677,12 +693,18 @@ int eDVBTSTools::findNextPicture(off_t &offset, size_t &len, int &distance, int
                
 //             eDebug("we moved %d, %d to go frames (now at %llx)", dir, distance, new_offset);
 
-               if (distance >= 0 || first)
+               if (distance >= 0 || direction == 0)
                {
                        first = 0;
                        offset = new_offset;
                        len = new_len;
                        nr_frames += abs(dir);
+               } 
+               else if (first) {
+                       first = 0;
+                       offset = new_offset;
+                       len = new_len;
+                       nr_frames += abs(dir) + distance; // never jump forward during rewind
                }
        }
 
index bc2a66a..2658f9b 100644 (file)
@@ -1,5 +1,5 @@
 from config import config, ConfigSlider, ConfigSelection, ConfigYesNo, \
-       ConfigEnableDisable, ConfigSubsection, ConfigBoolean, ConfigNumber, ConfigNothing, NoSave
+       ConfigEnableDisable, ConfigSubsection, ConfigBoolean, ConfigSelectionNumber, ConfigNothing, NoSave
 from enigma import eAVSwitch, getDesktop
 from SystemInfo import SystemInfo
 from os import path as os_path
@@ -112,8 +112,8 @@ def InitAVSwitch():
        config.av.tvsystem = ConfigSelection(choices = {"pal": _("PAL"), "ntsc": _("NTSC"), "multinorm": _("multinorm")}, default="pal")
        config.av.wss = ConfigEnableDisable(default = True)
        config.av.defaultac3 = ConfigYesNo(default = False)
-       config.av.generalAC3delay = ConfigNumber(default = 0)
-       config.av.generalPCMdelay = ConfigNumber(default = 0)
+       config.av.generalAC3delay = ConfigSelectionNumber(-1000, 1000, 25, default = 0)
+       config.av.generalPCMdelay = ConfigSelectionNumber(-1000, 1000, 25, default = 0)
        config.av.vcrswitch = ConfigEnableDisable(default = False)
 
        iAVSwitch = AVSwitch()
index bb2d756..8e332e3 100644 (file)
@@ -19,11 +19,21 @@ class About:
                                        #0120 2005 11 29 01 16
                                        #0123 4567 89 01 23 45
                                        version = splitted[1]
+                                       image_type = version[0] # 0 = release, 1 = experimental
+                                       major = version[1]
+                                       minor = version[2]
+                                       revision = version[3]
                                        year = version[4:8]
                                        month = version[8:10]
                                        day = version[10:12]
-
-                                       return '-'.join(("dev", year, month, day))
+                                       date = '-'.join((year, month, day))
+                                       if image_type == '0':
+                                               image_type = "Release"
+                                               version = '.'.join((major, minor, revision))
+                                               return ' '.join((image_type, version, date))
+                                       else:
+                                               image_type = "Experimental"
+                                               return ' '.join((image_type, date))
                        file.close()
                except IOError:
                        pass
index 54bb1ac..b187ee3 100755 (executable)
@@ -3,7 +3,7 @@ from os import path as os_path, listdir
 from MenuList import MenuList
 from Components.Harddisk import harddiskmanager
 
-from Tools.Directories import SCOPE_SKIN_IMAGE, resolveFilename
+from Tools.Directories import SCOPE_SKIN_IMAGE, resolveFilename, fileExists
 
 from enigma import RT_HALIGN_LEFT, eListboxPythonMultiContent, \
        eServiceReference, eServiceCenter, gFont
@@ -23,6 +23,7 @@ EXTENSIONS = {
                "ts": "movie",
                "avi": "movie",
                "divx": "movie",
+               "m4v": "movie",
                "mpg": "movie",
                "mpeg": "movie",
                "mkv": "movie",
@@ -159,8 +160,11 @@ class FileList(MenuList):
                        directories.sort()
                        files.sort()
                else:
-                       if os_path.exists(directory):
-                               files = listdir(directory)
+                       if fileExists(directory):
+                               try:
+                                       files = listdir(directory)
+                               except:
+                                       files = []
                                files.sort()
                                tmpfiles = files[:]
                                for x in tmpfiles:
@@ -373,8 +377,11 @@ class MultiFileSelectList(FileList):
                        directories.sort()
                        files.sort()
                else:
-                       if os_path.exists(directory):
-                               files = listdir(directory)
+                       if fileExists(directory):
+                               try:
+                                       files = listdir(directory)
+                               except:
+                                       files = []
                                files.sort()
                                tmpfiles = files[:]
                                for x in tmpfiles:
index 2efdb68..03f574f 100755 (executable)
@@ -290,7 +290,10 @@ class Harddisk:
        # any access has been made to the disc. If there has been no access over a specifed time,
        # we set the hdd into standby.
        def readStats(self):
-               l = readFile("/sys/block/%s/stat" % self.device)
+               try:
+                       l = open("/sys/block/%s/stat" % self.device).read()
+               except IOError:
+                       return -1,-1
                (nr_read, _, _, _, nr_write) = l.split()[:5]
                return int(nr_read), int(nr_write)
 
@@ -319,7 +322,7 @@ class Harddisk:
                l = sum(stats)
                print "sum", l, "prev_sum", self.last_stat
 
-               if l != self.last_stat: # access
+               if l != self.last_stat and l >= 0: # access
                        print "hdd was accessed since previous check!"
                        self.last_stat = l
                        self.last_access = t
index 0e50123..7d27c09 100644 (file)
@@ -42,9 +42,18 @@ def InitLcd():
                def setLCDinverted(configElement):
                        ilcd.setInverted(configElement.value);
 
+               standby_default = 0
+
                ilcd = LCD()
 
-               config.lcd.standby = ConfigSlider(default=0, limits=(0, 10))
+               if not ilcd.isOled():
+                       config.lcd.contrast = ConfigSlider(default=5, limits=(0, 20))
+                       config.lcd.contrast.addNotifier(setLCDcontrast);
+               else:
+                       config.lcd.contrast = ConfigNothing()
+                       standby_default = 1
+
+               config.lcd.standby = ConfigSlider(default=standby_default, limits=(0, 10))
                config.lcd.standby.addNotifier(setLCDbright);
                config.lcd.standby.apply = lambda : setLCDbright(config.lcd.standby)
 
@@ -53,12 +62,6 @@ def InitLcd():
                config.lcd.bright.apply = lambda : setLCDbright(config.lcd.bright)
                config.lcd.bright.callNotifiersOnSaveAndCancel = True
 
-               if not ilcd.isOled():
-                       config.lcd.contrast = ConfigSlider(default=5, limits=(0, 20))
-                       config.lcd.contrast.addNotifier(setLCDcontrast);
-               else:
-                       config.lcd.contrast = ConfigNothing()
-
                config.lcd.invert = ConfigYesNo(default=False)
                config.lcd.invert.addNotifier(setLCDinverted);
        else:
index 5154e2b..7d148f3 100644 (file)
@@ -554,6 +554,13 @@ class NimManager:
        def getSatDescription(self, pos):
                return self.satellites[pos]
 
+       def sortFunc(self, x):
+               orbpos = x[0]
+               if orbpos > 1800:
+                       return orbpos - 3600
+               else:
+                       return orbpos + 1800
+
        def readTransponders(self):
                # read initial networks from file. we only read files which we are interested in,
                # which means only these where a compatible tuner exists.
@@ -565,9 +572,10 @@ class NimManager:
                if self.hasNimType("DVB-S"):
                        print "Reading satellites.xml"
                        db.readSatellites(self.satList, self.satellites, self.transponders)
-#                      print "SATLIST", self.satList
-#                      print "SATS", self.satellites
-#                      print "TRANSPONDERS", self.transponders
+                       self.satList.sort(key = self.sortFunc) # sort by orbpos
+                       #print "SATLIST", self.satList
+                       #print "SATS", self.satellites
+                       #print "TRANSPONDERS", self.transponders
 
                if self.hasNimType("DVB-C"):
                        print "Reading cables.xml"
@@ -891,7 +899,7 @@ def InitSecParams():
        x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_VOLTAGE_CHANGE_BEFORE_MEASURE_IDLE_INPUTPOWER, configElement.value))
        config.sec.delay_after_voltage_change_before_measure_idle_inputpower = x
 
-       x = ConfigInteger(default=750, limits = (0, 9999))
+       x = ConfigInteger(default=900, limits = (0, 9999))
        x.addNotifier(lambda configElement: secClass.setParam(secClass.DELAY_AFTER_ENABLE_VOLTAGE_BEFORE_MOTOR_CMD, configElement.value))
        config.sec.delay_after_enable_voltage_before_motor_command = x
 
index d2b405a..f9c4065 100644 (file)
@@ -1,5 +1,6 @@
 from enigma import eDVBResourceManager
 from Tools.Directories import fileExists
+from Tools.HardwareInfo import HardwareInfo
 
 SystemInfo = { }
 
@@ -27,3 +28,4 @@ def countFrontpanelLEDs():
 SystemInfo["NumFrontpanelLEDs"] = countFrontpanelLEDs()
 SystemInfo["FrontpanelDisplay"] = fileExists("/dev/dbox/oled0") or fileExists("/dev/dbox/lcd0")
 SystemInfo["FrontpanelDisplayGrayscale"] = fileExists("/dev/dbox/oled0")
+SystemInfo["DeepstandbySupport"] = HardwareInfo().get_device_name() != "dm800"
index 6fcab8b..680b594 100644 (file)
@@ -1,5 +1,6 @@
 from Components.Harddisk import harddiskmanager
 from config import ConfigSubsection, ConfigYesNo, config, ConfigSelection, ConfigText, ConfigNumber, ConfigSet, ConfigLocations
+from Tools.Directories import resolveFilename, SCOPE_HDD
 from enigma import Misc_Options, setTunerTypePriorityOrder;
 from SystemInfo import SystemInfo
 import os
@@ -30,8 +31,11 @@ def InitUsageConfig():
                ("standard", _("standard")), ("swap", _("swap PiP and main picture")),
                ("swapstop", _("move PiP to main picture")), ("stop", _("stop PiP")) ])
 
+       config.usage.default_path = ConfigText(default = resolveFilename(SCOPE_HDD))
+       config.usage.timer_path = ConfigText(default = "<default>")
+       config.usage.instantrec_path = ConfigText(default = "<default>")
+       config.usage.timeshift_path = ConfigText(default = "/media/hdd/")
        config.usage.allowed_timeshift_paths = ConfigLocations(default = ["/media/hdd/"])
-       config.usage.timeshift_path = ConfigText(default = "/media/hdd")
 
        config.usage.on_movie_start = ConfigSelection(default = "ask", choices = [
                ("ask", _("Ask user")), ("resume", _("Resume from last position")), ("beginning", _("Start from the beginning")) ])
@@ -65,19 +69,19 @@ def InitUsageConfig():
        
        def TunerTypePriorityOrderChanged(configElement):
                setTunerTypePriorityOrder(int(configElement.value))
-       config.usage.alternatives_priority.addNotifier(TunerTypePriorityOrderChanged)
+       config.usage.alternatives_priority.addNotifier(TunerTypePriorityOrderChanged, immediate_feedback=False)
 
        def setHDDStandby(configElement):
                for hdd in harddiskmanager.HDDList():
                        hdd[1].setIdleTime(int(configElement.value))
-       config.usage.hdd_standby.addNotifier(setHDDStandby)
+       config.usage.hdd_standby.addNotifier(setHDDStandby, immediate_feedback=False)
 
        def set12VOutput(configElement):
                if configElement.value == "on":
                        Misc_Options.getInstance().set_12V_output(1)
                elif configElement.value == "off":
                        Misc_Options.getInstance().set_12V_output(0)
-       config.usage.output_12V.addNotifier(set12VOutput)
+       config.usage.output_12V.addNotifier(set12VOutput, immediate_feedback=False)
 
        SystemInfo["12V_Output"] = Misc_Options.getInstance().detected_12V_output()
 
@@ -128,3 +132,23 @@ def updateChoices(sel, choices):
                                        defval = str(x)
                                        break
                sel.setChoices(map(str, choices), defval)
+
+def preferredPath(path):
+       if config.usage.setup_level.index < 2 or path == "<default>":
+               return None  # config.usage.default_path.value, but delay lookup until usage
+       elif path == "<current>":
+               return config.movielist.last_videodir.value
+       elif path == "<timer>":
+               return config.movielist.last_timer_videodir.value
+       else:
+               return path
+
+def preferredTimerPath():
+       return preferredPath(config.usage.timer_path.value)
+
+def preferredInstantRecordPath():
+       return preferredPath(config.usage.instantrec_path.value)
+
+def defaultMoviePath():
+       return config.usage.default_path.value
+
index e249caf..a6007b1 100755 (executable)
@@ -1,6 +1,6 @@
 from enigma import getPrevAsciiCode
 from Tools.NumericalTextInput import NumericalTextInput
-from Tools.Directories import resolveFilename, SCOPE_CONFIG
+from Tools.Directories import resolveFilename, SCOPE_CONFIG, fileExists
 from Components.Harddisk import harddiskmanager
 from copy import copy as copy_copy
 from os import path as os_path
@@ -1017,6 +1017,40 @@ class ConfigPassword(ConfigText):
                ConfigText.onDeselect(self, session)
                self.hidden = True
 
+# lets the user select between [min, min+stepwidth, min+(stepwidth*2)..., maxval] with maxval <= max depending
+# on the stepwidth
+# min, max, stepwidth, default are int values
+# wraparound: pressing RIGHT key at max value brings you to min value and vice versa if set to True
+class ConfigSelectionNumber(ConfigSelection):
+       def __init__(self, min, max, stepwidth, default = None, wraparound = False):
+               self.wraparound = wraparound
+               if default is None:
+                       default = min
+               default = str(default)
+               choices = []
+               step = min
+               while step <= max:
+                       choices.append(str(step))
+                       step += stepwidth
+               
+               ConfigSelection.__init__(self, choices, default)
+
+       def getValue(self):
+               return int(ConfigSelection.getValue(self))
+
+       def setValue(self, val):
+               ConfigSelection.setValue(self, str(val))
+
+       def handleKey(self, key):
+               if not self.wraparound:
+                       if key == KEY_RIGHT:
+                               if len(self.choices) == (self.choices.index(self.value) + 1):
+                                       return
+                       if key == KEY_LEFT:
+                               if self.choices.index(self.value) == 0:
+                                       return
+               ConfigSelection.handleKey(self, key)
+
 class ConfigNumber(ConfigText):
        def __init__(self, default = 0):
                ConfigText.__init__(self, str(default), fixed_size = False)
@@ -1249,7 +1283,6 @@ class ConfigLocations(ConfigElement):
                self.default = default
                self.locations = []
                self.mountpoints = []
-               harddiskmanager.on_partition_list_change.append(self.mountpointsChanged)
                self.value = default[:]
 
        def setValue(self, value):
@@ -1286,7 +1319,7 @@ class ConfigLocations(ConfigElement):
                locations = [[x, None, False, False] for x in tmp]
                self.refreshMountpoints()
                for x in locations:
-                       if os_path.exists(x[0]):
+                       if fileExists(x[0]):
                                x[1] = self.getMountpoint(x[0])
                                x[2] = True
                self.locations = locations
@@ -1305,20 +1338,11 @@ class ConfigLocations(ConfigElement):
                        return False
                return self.tostring([x[0] for x in locations]) != sv
 
-       def mountpointsChanged(self, action, dev):
-               print "Mounts changed: ", action, dev
-               mp = dev.mountpoint+"/"
-               if action == "add":
-                       self.addedMount(mp)
-               elif action == "remove":
-                       self.removedMount(mp)
-               self.refreshMountpoints()
-
        def addedMount(self, mp):
                for x in self.locations:
                        if x[1] == mp:
                                x[2] = True
-                       elif x[1] == None and os_path.exists(x[0]):
+                       elif x[1] == None and fileExists(x[0]):
                                x[1] = self.getMountpoint(x[0])
                                x[2] = True
 
@@ -1328,7 +1352,7 @@ class ConfigLocations(ConfigElement):
                                x[2] = False
 
        def refreshMountpoints(self):
-               self.mountpoints = [p.mountpoint + "/" for p in harddiskmanager.getMountedPartitions() if p.mountpoint != "/"]
+               self.mountpoints = [p.mountpoint for p in harddiskmanager.getMountedPartitions() if p.mountpoint != "/"]
                self.mountpoints.sort(key = lambda x: -len(x))
 
        def checkChangedMountpoints(self):
index feb39a9..53287a3 100755 (executable)
@@ -82,7 +82,9 @@ class DVDToolbox(Screen):
                self.update()
 
        def mediainfoCB(self, mediuminfo, retval, extra_args):
-               capacity = 1
+               formatted_capacity = 0
+               read_capacity = 0
+               capacity = 0
                used = 0
                infotext = ""
                mediatype = ""
@@ -93,21 +95,17 @@ class DVDToolbox(Screen):
                                        self.formattable = True
                                else:
                                        self.formattable = False
-                       if line.find("Legacy lead-out at:") > -1:
+                       elif line.find("Legacy lead-out at:") > -1:
                                used = int(line.rsplit('=',1)[1]) / 1048576.0
-                               print "[lead out] used =", used
+                               print "[dvd+rw-mediainfo] lead out used =", used
                        elif line.find("formatted:") > -1:
-                               capacity = int(line.rsplit('=',1)[1]) / 1048576.0
-                               print "[formatted] capacity =", capacity
-                       elif capacity == 1 and line.find("READ CAPACITY:") > -1:
-                               capacity = int(line.rsplit('=',1)[1]) / 1048576.0
-                               print "[READ CAP] capacity =", capacity
-                       elif line.find("Disc status:") > -1:
-                               if line.find("blank") > -1:
-                                       print "[Disc status] capacity=%d, used=0" % (capacity)
-                                       capacity = used
-                                       used = 0
-                       elif line.find("Free Blocks:") > -1:
+                               formatted_capacity = int(line.rsplit('=',1)[1]) / 1048576.0
+                               print "[dvd+rw-mediainfo] formatted capacity =", formatted_capacity
+                       elif formatted_capacity == 0 and line.find("READ CAPACITY:") > -1:
+                               read_capacity = int(line.rsplit('=',1)[1]) / 1048576.0
+                               print "[dvd+rw-mediainfo] READ CAPACITY =", read_capacity
+               for line in mediuminfo.splitlines():
+                       if line.find("Free Blocks:") > -1:
                                try:
                                        size = eval(line[14:].replace("KB","*1024"))
                                except:
@@ -116,8 +114,22 @@ class DVDToolbox(Screen):
                                        capacity = size / 1048576
                                        if used:
                                                used = capacity-used
-                                       print "[free blocks] capacity=%d, used=%d" % (capacity, used)
+                                       print "[dvd+rw-mediainfo] free blocks capacity=%d, used=%d" % (capacity, used)
+                       elif line.find("Disc status:") > -1:
+                               if line.find("blank") > -1:
+                                       print "[dvd+rw-mediainfo] Disc status blank capacity=%d, used=0" % (capacity)
+                                       capacity = used
+                                       used = 0
+                               elif line.find("complete") > -1 and formatted_capacity == 0:
+                                       print "[dvd+rw-mediainfo] Disc status complete capacity=0, used=%d" % (capacity)
+                                       used = read_capacity
+                                       capacity = 1
+                               else:
+                                       capacity = formatted_capacity
                        infotext += line+'\n'
+               if capacity and used > capacity:
+                       used = read_capacity or capacity
+                       capacity = formatted_capacity or capacity
                self["details"].setText(infotext)
                if self.formattable:
                        self["key_yellow"].text = _("Format")
index 0e3bdf0..98bc060 100644 (file)
@@ -110,7 +110,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB
 
                # 'None' is magic to start at the list of mountpoints
                defaultDir = config.mediaplayer.defaultDir.getValue()
-               self.filelist = FileList(defaultDir, matchingPattern = "(?i)^.*\.(mp2|mp3|ogg|ts|wav|wave|m3u|pls|e2pls|mpg|vob|avi|divx|mkv|mp4|m4a|dat|flac|mov)", useServiceRef = True, additionalExtensions = "4098:m3u 4098:e2pls 4098:pls")
+               self.filelist = FileList(defaultDir, matchingPattern = "(?i)^.*\.(mp2|mp3|ogg|ts|wav|wave|m3u|pls|e2pls|mpg|vob|avi|divx|m4v|mkv|mp4|m4a|dat|flac|mov)", useServiceRef = True, additionalExtensions = "4098:m3u 4098:e2pls 4098:pls")
                self["filelist"] = self.filelist
 
                self.playlist = MyPlayList()
index d7fc689..dc68ebf 100755 (executable)
@@ -52,6 +52,8 @@ class PluginDescriptor:
        # reason (True: Networkconfig read finished, False: Networkconfig reload initiated )
        WHERE_NETWORKCONFIG_READ = 12
 
+       WHERE_AUDIOMENU = 13
+
        def __init__(self, name = "Plugin", where = [ ], description = "", icon = None, fnc = None, wakeupfnc = None, internal = False):
                self.name = name
                self.internal = internal
index db71c31..a8b187d 100755 (executable)
@@ -3,7 +3,7 @@ installdir = $(pkglibdir)/python/Plugins/SystemPlugins
 SUBDIRS = SoftwareManager FrontprocessorUpgrade PositionerSetup Satfinder \
        SkinSelector SatelliteEquipmentControl Videomode VideoTune Hotplug \
        DefaultServicesScanner NFIFlash DiseqcTester CommonInterfaceAssignment \
-       CrashlogAutoSubmit CleanupWizard VideoEnhancement
+       CrashlogAutoSubmit CleanupWizard VideoEnhancement WirelessLan NetworkWizard
 
 install_PYTHON =       \
        __init__.py
diff --git a/lib/python/Plugins/SystemPlugins/NetworkWizard/LICENSE b/lib/python/Plugins/SystemPlugins/NetworkWizard/LICENSE
new file mode 100755 (executable)
index 0000000..9970059
--- /dev/null
@@ -0,0 +1,12 @@
+This plugin is licensed under the Creative Commons 
+Attribution-NonCommercial-ShareAlike 3.0 Unported 
+License. To view a copy of this license, visit
+http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative
+Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
+
+Alternatively, this plugin may be distributed and executed on hardware which
+is licensed by Dream Multimedia GmbH.
+
+This plugin is NOT free software. It is open source, you are allowed to
+modify it (if you keep the license), but it may not be commercially 
+distributed other than under the conditions noted above.
diff --git a/lib/python/Plugins/SystemPlugins/NetworkWizard/Makefile.am b/lib/python/Plugins/SystemPlugins/NetworkWizard/Makefile.am
new file mode 100755 (executable)
index 0000000..2a71bb2
--- /dev/null
@@ -0,0 +1,12 @@
+installdir = $(pkglibdir)/python/Plugins/SystemPlugins/NetworkWizard\r
+\r
+SUBDIRS = meta\r
+\r
+install_PYTHON =       \\r
+       __init__.py \\r
+       NetworkWizard.py \\r
+       plugin.py\r
+\r
+dist_install_DATA = \\r
+       LICENSE \\r
+       networkwizard.xml
\ No newline at end of file
diff --git a/lib/python/Plugins/SystemPlugins/NetworkWizard/NetworkWizard.py b/lib/python/Plugins/SystemPlugins/NetworkWizard/NetworkWizard.py
new file mode 100755 (executable)
index 0000000..4d36115
--- /dev/null
@@ -0,0 +1,244 @@
+from Screens.Wizard import wizardManager, WizardSummary
+from Screens.WizardLanguage import WizardLanguage
+from Screens.Rc import Rc
+from Screens.MessageBox import MessageBox
+
+from Components.Pixmap import Pixmap, MovingPixmap, MultiPixmap
+from Components.config import config, ConfigBoolean, configfile, ConfigYesNo, NoSave, ConfigSubsection, ConfigText, getConfigListEntry, ConfigSelection, ConfigPassword
+from Components.Network import iNetwork
+
+#from Components.Label import Label
+#from Components.MenuList import MenuList
+#from Components.PluginComponent import plugins
+#from Plugins.Plugin import PluginDescriptor
+from Tools.Directories import resolveFilename, SCOPE_PLUGINS, SCOPE_SKIN_IMAGE
+#import time, os, re
+
+
+config.misc.firstrun = ConfigBoolean(default = True)
+list = []
+list.append("WEP")
+list.append("WPA")
+list.append("WPA2")
+list.append("WPA/WPA2")
+
+weplist = []
+weplist.append("ASCII")
+weplist.append("HEX")
+
+config.plugins.wlan = ConfigSubsection()
+config.plugins.wlan.essid = NoSave(ConfigText(default = "home", fixed_size = False))
+config.plugins.wlan.hiddenessid = NoSave(ConfigText(default = "home", fixed_size = False))
+
+config.plugins.wlan.encryption = ConfigSubsection()
+config.plugins.wlan.encryption.enabled = NoSave(ConfigYesNo(default = False))
+config.plugins.wlan.encryption.type = NoSave(ConfigSelection(list, default = "WPA/WPA2" ))
+config.plugins.wlan.encryption.wepkeytype = NoSave(ConfigSelection(weplist, default = "ASCII"))
+config.plugins.wlan.encryption.psk = NoSave(ConfigPassword(default = "mysecurewlan", fixed_size = False))
+
+class NetworkWizard(WizardLanguage, Rc):
+       skin = """
+               <screen position="0,0" size="720,576" title="Welcome..." flags="wfNoBorder" >
+                       <widget name="text" position="153,40" size="340,330" font="Regular;22" />
+                       <widget source="list" render="Listbox" position="53,340" size="440,180" scrollbarMode="showOnDemand" >
+                               <convert type="StringList" />
+                       </widget>
+                       <widget name="config" position="53,340" zPosition="1" size="440,180" transparent="1" scrollbarMode="showOnDemand" />
+                       <ePixmap pixmap="skin_default/buttons/button_red.png" position="40,225" zPosition="0" size="15,16" transparent="1" alphatest="on" />
+                       <widget name="languagetext" position="55,225" size="95,30" font="Regular;18" />
+                       <widget name="wizard" pixmap="skin_default/wizard.png" position="40,50" zPosition="10" size="110,174" alphatest="on" />
+                       <widget name="rc" pixmaps="skin_default/rc.png,skin_default/rcold.png" position="500,50" zPosition="10" size="154,500" alphatest="on" />
+                       <widget name="arrowdown" pixmap="skin_default/arrowdown.png" position="-100,-100" zPosition="11" size="37,70" alphatest="on" />
+                       <widget name="arrowdown2" pixmap="skin_default/arrowdown.png" position="-100,-100" zPosition="11" size="37,70" alphatest="on" />
+                       <widget name="arrowup" pixmap="skin_default/arrowup.png" position="-100,-100" zPosition="11" size="37,70" alphatest="on" />
+                       <widget name="arrowup2" pixmap="skin_default/arrowup.png" position="-100,-100" zPosition="11" size="37,70" alphatest="on" />
+               </screen>"""
+       def __init__(self, session):
+               self.xmlfile = resolveFilename(SCOPE_PLUGINS, "SystemPlugins/NetworkWizard/networkwizard.xml")
+               WizardLanguage.__init__(self, session, showSteps = False, showStepSlider = False)
+               Rc.__init__(self)
+               self.session = session
+               self["wizard"] = Pixmap()
+               
+               self.InterfaceState = None
+               self.isInterfaceUp = None
+               self.WlanPluginInstalled = None
+               self.ap = None
+               self.selectedInterface = None
+               self.NextStep = None
+               self.myref = None
+               self.checkRef = None
+               self.AdapterRef = None
+               self.WlanList = None
+               self.isWlanPluginInstalled()
+
+       def listInterfaces(self):
+               list = [(iNetwork.getFriendlyAdapterName(x),x) for x in iNetwork.getAdapterList()]
+               list.append((_("Exit network wizard"), "end"))
+               return list
+
+       def InterfaceSelectionMade(self, index):
+               self.selectedInterface = index
+               self.InterfaceSelect(index)
+
+       def InterfaceSelect(self, index):
+               if index == 'end':
+                       self.NextStep = 'end'
+               elif index == 'eth0':
+                       self.NextStep = 'nwconfig'
+               else:
+                       self.NextStep = 'scanwlan'
+
+       def InterfaceSelectionMoved(self):
+               self.InterfaceSelect(self.selection)
+               
+       def checkInterface(self,iface):
+               self.Adapterlist = iNetwork.getAdapterList()
+               if self.NextStep is not 'end':
+                       if len(self.Adapterlist) == 0:
+                               #Reset Network to defaults if network broken
+                               iNetwork.resetNetworkConfig('lan', self.checkInterfaceCB)
+                               self.myref = self.session.openWithCallback(self.resetfinishedCB, MessageBox, _("Please wait while we prepare your network interfaces..."), type = MessageBox.TYPE_INFO, enable_input = False)
+                       if iface == 'eth0':
+                               if iface in iNetwork.configuredNetworkAdapters and len(iNetwork.configuredNetworkAdapters) == 1:
+                                       if iNetwork.getAdapterAttribute(iface, 'up') is True:
+                                               self.isInterfaceUp = True
+                                       else:
+                                               self.isInterfaceUp = False
+                                       self.resetfinishedCB(False)
+                               else:
+                                       iNetwork.resetNetworkConfig('lan',self.checkInterfaceCB)
+                                       self.myref = self.session.openWithCallback(self.resetfinishedCB, MessageBox, _("Please wait while we prepare your network interfaces..."), type = MessageBox.TYPE_INFO, enable_input = False)
+                       elif iface == 'wlan0':
+                               if iface in iNetwork.configuredNetworkAdapters and len(iNetwork.configuredNetworkAdapters) == 1:
+                                       if iNetwork.getAdapterAttribute(iface, 'up') is True:
+                                               self.isInterfaceUp = True
+                                       else:
+                                               self.isInterfaceUp = False
+                                       self.resetfinishedCB(False)
+                               else:
+                                       iNetwork.resetNetworkConfig('wlan',self.checkInterfaceCB)
+                                       self.myref = self.session.openWithCallback(self.resetfinishedCB, MessageBox, _("Please wait while we prepare your network interfaces..."), type = MessageBox.TYPE_INFO, enable_input = False)
+                       elif iface == 'ath0':
+                               if iface in iNetwork.configuredNetworkAdapters and len(iNetwork.configuredNetworkAdapters) == 1:
+                                       if iNetwork.getAdapterAttribute(iface, 'up') is True:
+                                               self.isInterfaceUp = True
+                                       else:
+                                               self.isInterfaceUp = False
+                                       self.resetfinishedCB(False)
+                               else:
+                                       iNetwork.resetNetworkConfig('wlan-mpci',self.checkInterfaceCB)
+                                       self.myref = self.session.openWithCallback(self.resetfinishedCB, MessageBox, _("Please wait while we prepare your network interfaces..."), type = MessageBox.TYPE_INFO, enable_input = False)
+               else:
+                       self.resetfinishedCB(False)
+                       
+       def resetfinishedCB(self,data):
+               if data is True:
+                       self.currStep = self.getStepWithID(self.NextStep)
+                       self.afterAsyncCode()
+               else:
+                       self.currStep = self.getStepWithID(self.NextStep)
+                       self.afterAsyncCode()
+
+       def checkInterfaceCB(self,callback,iface):
+               if callback is not None:
+                       if callback is True:
+                               iNetwork.getInterfaces(self.getInterfacesDataAvail)
+                               
+
+       def getInterfacesDataAvail(self, data):
+               if data is True:
+                       if iNetwork.getAdapterAttribute(self.selectedInterface, 'up') is True:
+                               self.isInterfaceUp = True
+                       else:
+                               self.isInterfaceUp = False
+                       self.myref.close(True)
+
+       def AdapterSetupEnd(self, iface):
+               if iNetwork.getAdapterAttribute(iface, "dhcp") is True:
+                       iNetwork.checkNetworkState(self.AdapterSetupEndFinished)
+                       self.AdapterRef = self.session.openWithCallback(self.AdapterSetupEndCB, MessageBox, _("Please wait while we test your network..."), type = MessageBox.TYPE_INFO, enable_input = False)
+
+               else:
+                       self.currStep = self.getStepWithID("confdns")
+                       self.afterAsyncCode()
+
+       def AdapterSetupEndCB(self,data):
+               if data is True:
+                       self.currStep = self.getStepWithID("checklanstatusend")
+                       self.afterAsyncCode()
+
+       def AdapterSetupEndFinished(self,data):
+               if data <= 2:
+                       self.InterfaceState = True
+               else:
+                       self.InterfaceState = False
+               self.AdapterRef.close(True)
+                       
+       def checkNetwork(self):
+               iNetwork.checkNetworkState(self.checkNetworkStateFinished)
+               self.checkRef = self.session.openWithCallback(self.checkNetworkCB, MessageBox, _("Please wait while we test your network..."), type = MessageBox.TYPE_INFO, enable_input = False)
+
+       def checkNetworkCB(self,data):
+               if data is True:
+                       self.currStep = self.getStepWithID("checklanstatusend")
+                       self.afterAsyncCode()
+
+       def checkNetworkStateFinished(self,data):
+               if data <= 2:
+                       self.InterfaceState = True
+               else:
+                       self.InterfaceState = False
+               self.checkRef.close(True)
+       
+       def markDone(self):
+               pass
+
+       def listModes(self):
+               list = []
+               self.WlanList = []
+               try:
+                       from Plugins.SystemPlugins.WirelessLan.Wlan import Wlan
+               except ImportError:
+                       list.append( ( _("No networks found"),_("unavailable") ) )
+                       self.WlanList.append(_("No networks found"))
+                       return list
+               else:   
+                       self.w = Wlan(self.selectedInterface)
+                       aps = self.w.getNetworkList()
+                       if aps is not None:
+                               print "[NetworkWizard.py] got Accespoints!"
+                               for ap in aps:
+                                       a = aps[ap]
+                                       if a['active']:
+                                               if a['essid'] != "":
+                                                       #a['essid'] = a['bssid']
+                                                       list.append( (a['essid'], a['essid']) )
+                                                       self.WlanList.append(a['essid'])        
+                       if "hidden..." not in list:
+                               list.append( ( _("enter hidden network SSID"),_("hidden...") ) )
+                               self.WlanList.append(_("hidden..."))    
+                       return list
+
+       def modeSelectionMade(self, index):
+               self.modeSelect(index)
+               
+       def modeSelectionMoved(self):
+               self.modeSelect(self.selection)
+               
+       def modeSelect(self, mode):
+               self.ap = mode
+               print "ModeSelected:", mode
+
+       def restartNetwork(self):
+               iNetwork.restartNetwork()
+               self.checkNetwork()
+       
+       def isWlanPluginInstalled(self):                
+               try:
+                       from Plugins.SystemPlugins.WirelessLan.Wlan import Wlan
+               except ImportError:
+                       self.WlanPluginInstalled = False
+               else:
+                       self.WlanPluginInstalled = True
+
diff --git a/lib/python/Plugins/SystemPlugins/NetworkWizard/__init__.py b/lib/python/Plugins/SystemPlugins/NetworkWizard/__init__.py
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/lib/python/Plugins/SystemPlugins/NetworkWizard/meta/Makefile.am b/lib/python/Plugins/SystemPlugins/NetworkWizard/meta/Makefile.am
new file mode 100755 (executable)
index 0000000..98dbe80
--- /dev/null
@@ -0,0 +1,3 @@
+installdir = $(datadir)/meta/
+
+dist_install_DATA = plugin_networkwizard.xml
diff --git a/lib/python/Plugins/SystemPlugins/NetworkWizard/meta/plugin_networkwizard.xml b/lib/python/Plugins/SystemPlugins/NetworkWizard/meta/plugin_networkwizard.xml
new file mode 100755 (executable)
index 0000000..660bbcd
--- /dev/null
@@ -0,0 +1,25 @@
+<default>
+         <prerequisites>
+                    <tag type="System" />
+         </prerequisites>
+          <info language="en">
+                    <author>Dream Multimedia</author>
+                    <name>NetworkWizard</name>
+                    <packagename>enigma2-plugin-systemplugins-networkwizard</packagename>
+                    <shortdescription>Step by step network configuration</shortdescription>
+                    <description>With the NetworkWizard you can easy configure your network step by step.
+                    </description>
+          </info>
+          <info language="de">
+                    <author>Dream Multimedia</author>
+                    <name>NetzwerkWizard</name>
+                    <packagename>enigma2-plugin-systemplugins-networkwizard</packagename>
+                    <shortdescription>Schritt für Schritt Netzwerk konfiguration</shortdescription>
+                    <description>Mit dem NetzwerkWizard können Sie Ihr Netzwerk konfigurieren. Sie werden Schritt
+                       für Schritt durch die Konfiguration geleitet.
+                    </description>
+          </info>
+         <files type="package"> <!-- without version, without .ipk -->
+               <file type="package" name="enigma2-plugin-systemplugins-networkwizard" />
+         </files>
+</default>
diff --git a/lib/python/Plugins/SystemPlugins/NetworkWizard/networkwizard.xml b/lib/python/Plugins/SystemPlugins/NetworkWizard/networkwizard.xml
new file mode 100755 (executable)
index 0000000..134797a
--- /dev/null
@@ -0,0 +1,172 @@
+<wizard>
+               <step id="welcome" nextstep="selectinterface">
+                       <text value="Welcome.\n\nIf you want to connect your Dreambox to the Internet, this wizard will guide you through the basic network setup of your Dreambox.\n\nPress OK to start configuring your network" />
+                       <displaytext value="Network Wizard" />
+                       <code>
+self.clearSelectedKeys()
+self.selectKey("OK")
+                       </code>
+               </step>
+
+               <step id="selectinterface">
+                       <text value="Please select the network interface that you want to use for your internet connection.\n\nPlease press OK to continue." />
+                       <displaytext value="Select interface" />
+                       <list type="dynamic" source="listInterfaces" evaluation="InterfaceSelectionMade" onselect="InterfaceSelectionMoved" />
+                       <code>
+self.clearSelectedKeys()
+self.selectKey("OK")
+self.selectKey("UP")
+self.selectKey("DOWN")
+                       </code>
+                       <code pos="after" async="yes">
+self.checkInterface(self.selectedInterface)
+                       </code> 
+               </step>
+
+               <step id="nwconfig">
+                       <text value="Please configure your internet connection by filling out the required values.\nWhen you are ready press OK to continue." />
+                       <displaytext value="Configure interface" />
+                       <config screen="AdapterSetup" module="NetworkSetup" args="self.selectedInterface" type="ConfigList" />
+                       <code>
+self.clearSelectedKeys()
+self.selectKey("OK")
+self.selectKey("UP")
+self.selectKey("DOWN")
+self.selectKey("LEFT")
+self.selectKey("RIGHT")
+                       </code>
+                       <code pos="after" async="yes">
+self.AdapterSetupEnd(self.selectedInterface)
+                       </code>                 
+               </step>
+
+               <step id="confdns" nextstep="checklanstatusend">
+                       <text value="Please configure or verify your Nameservers by filling out the required values.\nWhen you are ready press OK to continue." />
+                       <displaytext value="Configure nameservers" />
+                       <config screen="NameserverSetup" module="NetworkSetup" type="ConfigList" />
+                       <code>
+self.clearSelectedKeys()
+self.selectKey("OK")
+                       </code>
+                       <code pos="after" async="yes">
+self.checkNetwork()
+                       </code> 
+               </step>
+
+               <step id="checklanstatusend" nextstep="end">
+               <condition>
+self.condition = (self.InterfaceState == True )
+               </condition>
+                       <text value="Your Dreambox is now ready to use.\n\nYour internet connection is working now.\n\nPlease press OK to continue." />
+                       <displaytext value="Please follow the instructions on the TV" />
+                       <code>
+self.clearSelectedKeys()
+self.selectKey("OK")
+                       </code>
+                       <code pos="after">
+currStep = self.numSteps                               
+self.wizard[currStep]["nextstep"] = None
+self.markDone()
+self.close()
+                       </code> 
+               </step>
+
+               <step id="checklanstatusend">
+               <condition>
+self.condition = (self.InterfaceState == False )
+               </condition>
+                       <text value="Your internet connection is not working!\nPlease choose what you want to do next." />
+                       <displaytext value="Please follow the instructions on the TV" />
+                       <code>
+self.clearSelectedKeys()
+self.selectKey("OK")
+self.selectKey("UP")
+self.selectKey("DOWN")
+                       </code>
+                       <list>
+                               <listentry caption="Configure your network again" step="selectinterface" />
+                               <listentry caption="Exit network wizard" step="end" />
+                       </list>
+               </step>
+
+               <step id="scanwlan" nextstep="wlanconfig">
+               <condition>
+self.condition = (self.isInterfaceUp == True and self.WlanPluginInstalled == True)
+               </condition>
+                       <text value="Please select the wireless network that you want to connect to.\n\nPlease press OK to continue." />
+                       <displaytext value="Select wireless network" />
+                       <list type="dynamic" source="listModes" evaluation="modeSelectionMade" onselect="modeSelectionMoved" />
+                       <code>
+self.clearSelectedKeys()
+self.selectKey("OK")
+self.selectKey("UP")
+self.selectKey("DOWN")
+self.selectKey("LEFT")
+self.selectKey("RIGHT")
+                       </code>
+               </step>
+
+               <step id="scanwlan">
+               <condition>
+self.condition = (self.isInterfaceUp == False and self.WlanPluginInstalled == True)
+               </condition>
+                       <text value="Your wireless LAN internet connection could not be started!\nHave you attached your USB WLAN Stick?\n\nPlease choose what you want to do next." />
+                       <displaytext value="Please follow the instructions on the TV" />
+                       <list>
+                               <listentry caption="Configure your wireless LAN again" step="scanwlan" />
+                               <listentry caption="Configure your internal LAN" step="selectinterface" />
+                               <listentry caption="Exit network wizard" step="end" />
+                       </list>
+                       <code>
+self.clearSelectedKeys()
+self.selectKey("OK")
+self.selectKey("UP")
+self.selectKey("DOWN")
+                       </code>
+               </step>
+
+               <step id="scanwlan">
+               <condition>
+self.condition = (self.isInterfaceUp == True and self.WlanPluginInstalled == False)
+               </condition>
+                       <text value="The wireless LAN plugin is not installed!\nPlease install it and choose what you want to do next." />
+                       <displaytext value="Please follow the instructions on the TV" />
+                       <list>
+                               <listentry caption="Configure your internal LAN" step="selectinterface" />
+                               <listentry caption="Exit network wizard" step="end" />
+                       </list>
+                       <code>
+self.clearSelectedKeys()
+self.selectKey("OK")
+self.selectKey("UP")
+self.selectKey("DOWN")
+                       </code>
+               </step>
+
+               <step id="wlanconfig">
+                       <text value="Please configure your internet connection by filling out the required values.\nWhen you are ready press OK to continue." />
+                       <displaytext value="Configure interface" />
+                       <config screen="AdapterSetup" module="NetworkSetup" args="(self.selectedInterface,self.ap,self.WlanList)" type="ConfigList" />
+                       <code>
+self.clearSelectedKeys()
+self.selectKey("OK")
+self.selectKey("UP")
+self.selectKey("DOWN")
+self.selectKey("LEFT")
+self.selectKey("RIGHT")
+                       </code>
+                       <code pos="after" async="yes">
+self.AdapterSetupEnd(self.selectedInterface)
+                       </code>                 
+               </step>
+
+               <step id="end">
+                       <text value="Thank you for using the wizard.\nPlease press OK to continue." />
+                       <code>
+self.clearSelectedKeys()
+self.selectKey("OK")
+                       </code>
+               </step>
+</wizard>
+
+
diff --git a/lib/python/Plugins/SystemPlugins/NetworkWizard/plugin.py b/lib/python/Plugins/SystemPlugins/NetworkWizard/plugin.py
new file mode 100755 (executable)
index 0000000..dc3beca
--- /dev/null
@@ -0,0 +1,22 @@
+from Screens.Screen import Screen
+from Plugins.Plugin import PluginDescriptor
+from Components.config import getConfigListEntry, config
+
+def NetworkWizardMain(session, **kwargs):
+       session.open(NetworkWizard)
+
+def startSetup(menuid):
+       if menuid != "system": 
+               return [ ]
+
+       return [(_("Network Wizard") + "...", NetworkWizardMain, "nw_wizard", 40)]
+
+def NetworkWizard(*args, **kwargs):
+       from NetworkWizard import NetworkWizard
+       return NetworkWizard(*args, **kwargs)
+
+def Plugins(**kwargs):
+       list = []
+       if config.misc.firstrun.value:
+               list.append(PluginDescriptor(name=_("Network Wizard"), where = PluginDescriptor.WHERE_WIZARD, fnc=(25, NetworkWizard)))
+       return list
index 3759c21..cd1529a 100644 (file)
@@ -84,7 +84,8 @@ class VideoWizard(WizardLanguage, Rc):
                                descr = port
                                if descr == 'DVI' and hw_type == 'dm500hd':
                                        descr = 'HDMI'
-                               list.append((descr,port))
+                               if port != "DVI-PC":
+                                       list.append((descr,port))
                list.sort(key = lambda x: x[0])
                print "listInputChannels:", list
                return list
diff --git a/lib/python/Plugins/SystemPlugins/WirelessLan/LICENSE b/lib/python/Plugins/SystemPlugins/WirelessLan/LICENSE
new file mode 100755 (executable)
index 0000000..9970059
--- /dev/null
@@ -0,0 +1,12 @@
+This plugin is licensed under the Creative Commons 
+Attribution-NonCommercial-ShareAlike 3.0 Unported 
+License. To view a copy of this license, visit
+http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to Creative
+Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
+
+Alternatively, this plugin may be distributed and executed on hardware which
+is licensed by Dream Multimedia GmbH.
+
+This plugin is NOT free software. It is open source, you are allowed to
+modify it (if you keep the license), but it may not be commercially 
+distributed other than under the conditions noted above.
diff --git a/lib/python/Plugins/SystemPlugins/WirelessLan/Makefile.am b/lib/python/Plugins/SystemPlugins/WirelessLan/Makefile.am
new file mode 100755 (executable)
index 0000000..365372c
--- /dev/null
@@ -0,0 +1,13 @@
+installdir = $(pkglibdir)/python/Plugins/SystemPlugins/WirelessLan
+
+#SUBDIRS = meta
+
+install_PYTHON =       \
+       __init__.py \
+       flags.py \
+       iwlibs.py \
+       plugin.py \
+       Wlan.py
+
+dist_install_DATA = \
+       LICENSE
diff --git a/lib/python/Plugins/SystemPlugins/WirelessLan/Wlan.py b/lib/python/Plugins/SystemPlugins/WirelessLan/Wlan.py
new file mode 100755 (executable)
index 0000000..ba1e13d
--- /dev/null
@@ -0,0 +1,612 @@
+from enigma import eListboxPythonMultiContent, eListbox, gFont, RT_HALIGN_LEFT, RT_HALIGN_RIGHT, RT_HALIGN_CENTER
+from Components.MultiContent import MultiContentEntryText
+from Components.GUIComponent import GUIComponent
+from Components.HTMLComponent import HTMLComponent
+from Components.config import config, ConfigYesNo, NoSave, ConfigSubsection, ConfigText, ConfigSelection, ConfigPassword
+from Components.Console import Console
+
+from os import system
+from string import maketrans, strip
+import sys
+import types
+from re import compile as re_compile, search as re_search
+from iwlibs import getNICnames, Wireless, Iwfreq
+
+list = []
+list.append("WEP")
+list.append("WPA")
+list.append("WPA2")
+list.append("WPA/WPA2")
+
+weplist = []
+weplist.append("ASCII")
+weplist.append("HEX")
+
+config.plugins.wlan = ConfigSubsection()
+config.plugins.wlan.essid = NoSave(ConfigText(default = "home", fixed_size = False))
+config.plugins.wlan.hiddenessid = NoSave(ConfigText(default = "home", fixed_size = False))
+
+config.plugins.wlan.encryption = ConfigSubsection()
+config.plugins.wlan.encryption.enabled = NoSave(ConfigYesNo(default = True))
+config.plugins.wlan.encryption.type = NoSave(ConfigSelection(list, default = "WPA/WPA2"))
+config.plugins.wlan.encryption.wepkeytype = NoSave(ConfigSelection(weplist, default = "ASCII"))
+config.plugins.wlan.encryption.psk = NoSave(ConfigPassword(default = "mysecurewlan", fixed_size = False))
+
+class Wlan:
+       def __init__(self, iface):
+               a = ''; b = ''
+               
+               for i in range(0, 255):
+                   a = a + chr(i)
+                   if i < 32 or i > 127:
+                       b = b + ' '
+                   else:
+                       b = b + chr(i)
+               
+               self.iface = iface
+               self.wlaniface = {}
+               self.WlanConsole = Console()
+               self.asciitrans = maketrans(a, b)
+
+       def stopWlanConsole(self):
+               if self.WlanConsole is not None:
+                       print "killing self.WlanConsole"
+                       self.WlanConsole = None
+                       del self.WlanConsole
+                       
+       def getDataForInterface(self, callback = None):
+               #get ip out of ip addr, as avahi sometimes overrides it in ifconfig.
+               print "self.iface im getDataForInterface",self.iface
+               if len(self.WlanConsole.appContainers) == 0:
+                       self.WlanConsole = Console()
+                       cmd = "iwconfig " + self.iface
+                       self.WlanConsole.ePopen(cmd, self.iwconfigFinished, callback)
+
+       def iwconfigFinished(self, result, retval, extra_args):
+               print "self.iface im iwconfigFinished",self.iface
+               callback = extra_args
+               data = { 'essid': False, 'frequency': False, 'acesspoint': False, 'bitrate': False, 'encryption': False, 'quality': False, 'signal': False }
+               #print "result im iwconfigFinished",result
+               
+               for line in result.splitlines():
+                       #print "line",line
+                       line = line.strip()
+                       if "ESSID" in line:
+                               if "off/any" in line:
+                                       ssid = _("No Connection")
+                               else:
+                                       tmpssid=(line[line.index('ESSID')+7:len(line)-1])
+                                       if tmpssid == '':
+                                               ssid = _("Hidden networkname")
+                                       elif tmpssid ==' ':
+                                               ssid = _("Hidden networkname")
+                                       else:
+                                           ssid = tmpssid
+                               #print "SSID->",ssid
+                               if ssid is not None:
+                                       data['essid'] = ssid
+                       if 'Frequency' in line:
+                               frequency = line[line.index('Frequency')+10 :line.index(' GHz')]
+                               #print "Frequency",frequency   
+                               if frequency is not None:
+                                       data['frequency'] = frequency
+                       if "Access Point" in line:
+                               ap=line[line.index('Access Point')+14:len(line)-1]
+                               #print "AP",ap
+                               if ap is not None:
+                                       data['acesspoint'] = ap
+                       if "Bit Rate" in line:
+                               br = line[line.index('Bit Rate')+9 :line.index(' Mb/s')]
+                               #print "Bitrate",br
+                               if br is not None:
+                                       data['bitrate'] = br
+                       if 'Encryption key' in line:
+                               if ":off" in line:
+                                   enc = _("Disabled")
+                               else:
+                                   enc = line[line.index('Encryption key')+15 :line.index('   Security')]
+                               #print "Encryption key",enc 
+                               if enc is not None:
+                                       data['encryption'] = _("Enabled")
+                       if 'Quality' in line:
+                               if "/100" in line:
+                                       qual = line[line.index('Quality')+8:line.index('/100')]
+                               else:
+                                       qual = line[line.index('Quality')+8:line.index('Sig')]
+                               #print "Quality",qual
+                               if qual is not None:
+                                       data['quality'] = qual
+                       if 'Signal level' in line:
+                               signal = line[line.index('Signal level')+14 :line.index(' dBm')]
+                               #print "Signal level",signal            
+                               if signal is not None:
+                                       data['signal'] = signal
+
+               self.wlaniface[self.iface] = data
+               
+               if len(self.WlanConsole.appContainers) == 0:
+                       print "self.wlaniface after loading:", self.wlaniface
+                       self.WlanConsole = None
+                       if callback is not None:
+                               callback(True,self.wlaniface)
+
+       def getAdapterAttribute(self, attribute):
+               print "im getAdapterAttribute"
+               if self.wlaniface.has_key(self.iface):
+                       print "self.wlaniface.has_key",self.iface
+                       if self.wlaniface[self.iface].has_key(attribute):
+                               return self.wlaniface[self.iface][attribute]
+               return None
+               
+       def asciify(self, str):
+               return str.translate(self.asciitrans)
+
+       
+       def getWirelessInterfaces(self):
+               iwifaces = None
+               try:
+                       iwifaces = getNICnames()
+               except:
+                       print "[Wlan.py] No Wireless Networkcards could be found"
+               
+               return iwifaces
+
+       
+       def getNetworkList(self):
+               system("ifconfig "+self.iface+" up")
+               ifobj = Wireless(self.iface) # a Wireless NIC Object
+               
+               #Association mappings
+               stats, quality, discard, missed_beacon = ifobj.getStatistics()
+               snr = quality.signallevel - quality.noiselevel
+
+               try:
+                       scanresults = ifobj.scan()
+               except:
+                       scanresults = None
+                       print "[Wlan.py] No Wireless Networks could be found"
+               
+               if scanresults is not None:
+                       aps = {}
+                       for result in scanresults:
+                       
+                               bssid = result.bssid
+               
+                               encryption = map(lambda x: hex(ord(x)), result.encode)
+               
+                               if encryption[-1] == "0x8":
+                                       encryption = True
+                               else:
+                                       encryption = False
+               
+                               extra = []
+                               for element in result.custom:
+                                       element = element.encode()
+                                       extra.append( strip(self.asciify(element)) )
+                               
+                               if result.quality.sl is 0 and len(extra) > 0:
+                                       begin = extra[0].find('SignalStrength=')+15
+                                                                       
+                                       done = False
+                                       end = begin+1
+                                       
+                                       while not done:
+                                               if extra[0][begin:end].isdigit():
+                                                       end += 1
+                                               else:
+                                                       done = True
+                                                       end -= 1
+                                       
+                                       signal = extra[0][begin:end]
+                                       #print "[Wlan.py] signal is:" + str(signal)
+
+                               else:
+                                       signal = str(result.quality.sl)
+                               
+                               aps[bssid] = {
+                                       'active' : True,
+                                       'bssid': result.bssid,
+                                       'channel': result.frequency.getChannel(result.frequency.getFrequency()),
+                                       'encrypted': encryption,
+                                       'essid': strip(self.asciify(result.essid)),
+                                       'iface': self.iface,
+                                       'maxrate' : result.rate[-1],
+                                       'noise' : result.quality.getNoiselevel(),
+                                       'quality' : str(result.quality.quality),
+                                       'signal' : signal,
+                                       'custom' : extra,
+                               }
+                               print aps[bssid]
+                       return aps
+
+               
+       def getStatus(self):
+               ifobj = Wireless(self.iface)
+               fq = Iwfreq()
+               try:
+                       self.channel = str(fq.getChannel(str(ifobj.getFrequency()[0:-3])))
+               except:
+                       self.channel = 0
+               #print ifobj.getStatistics()
+               status = {
+                                 'BSSID': str(ifobj.getAPaddr()),
+                                 'ESSID': str(ifobj.getEssid()),
+                                 'quality': str(ifobj.getStatistics()[1].quality),
+                                 'signal': str(ifobj.getStatistics()[1].sl),
+                                 'bitrate': str(ifobj.getBitrate()),
+                                 'channel': str(self.channel),
+                                 #'channel': str(fq.getChannel(str(ifobj.getFrequency()[0:-3]))),
+               }
+               
+               for (key, item) in status.items():
+                       if item is "None" or item is "":
+                                       status[key] = _("N/A")
+                               
+               return status
+
+
+
+class WlanList(HTMLComponent, GUIComponent):
+       def __init__(self, session, iface):
+               
+               GUIComponent.__init__(self)
+               self.w = Wlan(iface)
+               self.iface = iface
+               
+               self.length = 0
+               self.aplist = None
+               self.list = None
+               self.oldlist = None
+               self.l = None
+               self.l = eListboxPythonMultiContent()
+               
+               self.l.setFont(0, gFont("Regular", 32))
+               self.l.setFont(1, gFont("Regular", 18))
+               self.l.setFont(2, gFont("Regular", 16))
+               self.l.setBuildFunc(self.buildWlanListEntry)            
+                               
+               self.reload()
+       
+       def buildWlanListEntry(self, essid, bssid, encrypted, iface, maxrate, signal):                                                                                                 
+               
+               res = [ (essid, encrypted, iface) ]
+               
+               if essid == "":
+                       essid = bssid
+               
+               e = encrypted and _("Yes") or _("No")
+               res.append( MultiContentEntryText(pos=(0, 0), size=(470, 35), font=0, flags=RT_HALIGN_LEFT, text=essid) )
+               res.append( MultiContentEntryText(pos=(425, 0), size=(60, 20), font=1, flags=RT_HALIGN_LEFT, text=_("Signal: ")))
+               res.append( MultiContentEntryText(pos=(480, 0), size=(70, 35), font=0, flags=RT_HALIGN_RIGHT, text="%s" %signal))
+               res.append( MultiContentEntryText(pos=(0, 40), size=(180, 20), font=1, flags=RT_HALIGN_LEFT, text=_("Max. Bitrate: %s") %maxrate ))
+               res.append( MultiContentEntryText(pos=(190, 40), size=(180, 20), font=1, flags=RT_HALIGN_CENTER, text=_("Encrypted: %s") %e ))
+               res.append( MultiContentEntryText(pos=(345, 40), size=(190, 20), font=1, flags=RT_HALIGN_RIGHT, text=_("Interface: %s") %iface ))
+               return res
+               
+                       
+       def reload(self):
+               aps = self.w.getNetworkList()
+
+               self.list = []
+               self.aplist = []
+               if aps is not None:
+                       print "[Wlan.py] got Accespoints!"
+                       for ap in aps:
+                               a = aps[ap]
+                               if a['active']:
+                                       if a['essid'] != '':
+                                       #       a['essid'] = a['bssid']
+                                               self.list.append( (a['essid'], a['bssid'], a['encrypted'], a['iface'], a['maxrate'], a['signal']) )
+                                       #self.aplist.append( a['essid'])
+               if self.oldlist is not None:
+                       for entry in self.oldlist:
+                               if entry not in self.list:
+                                       self.list.append(entry)
+               
+               if len(self.list):
+                       for entry in self.list:
+                               self.aplist.append( entry[0])
+               self.length = len(self.list)
+               self.oldlist = self.list
+               self.l.setList([])
+               self.l.setList(self.list)
+                       
+       GUI_WIDGET = eListbox
+
+
+       def getCurrent(self):
+               return self.l.getCurrentSelection()
+       
+       
+       def postWidgetCreate(self, instance):
+               instance.setContent(self.l)
+               instance.setItemHeight(60)
+       
+       
+       def getLength(self):
+               return self.length
+       
+       def getList(self):
+               return self.aplist
+
+
+class wpaSupplicant:
+       def __init__(self):
+               pass
+       
+               
+       def writeConfig(self):  
+                       
+                       essid = config.plugins.wlan.essid.value
+                       hiddenessid = config.plugins.wlan.hiddenessid.value
+                       encrypted = config.plugins.wlan.encryption.enabled.value
+                       encryption = config.plugins.wlan.encryption.type.value
+                       wepkeytype = config.plugins.wlan.encryption.wepkeytype.value
+                       psk = config.plugins.wlan.encryption.psk.value
+                       fp = file('/etc/wpa_supplicant.conf', 'w')
+                       fp.write('#WPA Supplicant Configuration by enigma2\n')
+                       fp.write('ctrl_interface=/var/run/wpa_supplicant\n')
+                       fp.write('eapol_version=1\n')
+                       fp.write('fast_reauth=1\n')     
+                       if essid == 'hidden...':
+                               fp.write('ap_scan=2\n')
+                       else:
+                               fp.write('ap_scan=1\n')
+                       fp.write('network={\n')
+                       if essid == 'hidden...':
+                               fp.write('\tssid="'+hiddenessid+'"\n')
+                       else:
+                               fp.write('\tssid="'+essid+'"\n')
+                       fp.write('\tscan_ssid=0\n')                     
+                       if encrypted:
+                               if encryption == 'WPA' or encryption == 'WPA2' or encryption == 'WPA/WPA2' :
+                                       fp.write('\tkey_mgmt=WPA-PSK\n')
+                                       
+                                       if encryption == 'WPA':
+                                               fp.write('\tproto=WPA\n')
+                                               fp.write('\tpairwise=TKIP\n')
+                                               fp.write('\tgroup=TKIP\n')
+                                       elif encryption == 'WPA2':
+                                               fp.write('\tproto=WPA RSN\n')
+                                               fp.write('\tpairwise=CCMP TKIP\n')
+                                               fp.write('\tgroup=CCMP TKIP\n')                                         
+                                       else:
+                                               fp.write('\tproto=WPA WPA2\n')
+                                               fp.write('\tpairwise=CCMP\n')
+                                               fp.write('\tgroup=TKIP\n')                                      
+                                       fp.write('\tpsk="'+psk+'"\n')
+                                               
+                               elif encryption == 'WEP':
+                                       fp.write('\tkey_mgmt=NONE\n')
+                                       if wepkeytype == 'ASCII':
+                                               fp.write('\twep_key0="'+psk+'"\n')
+                                       else:
+                                               fp.write('\twep_key0='+psk+'\n')
+                       else:
+                               fp.write('\tkey_mgmt=NONE\n')                   
+                       fp.write('}')
+                       fp.write('\n')
+                       fp.close()
+                       system("cat /etc/wpa_supplicant.conf")
+               
+       def loadConfig(self):
+               try:
+                       #parse the wpasupplicant configfile
+                       fp = file('/etc/wpa_supplicant.conf', 'r')
+                       supplicant = fp.readlines()
+                       fp.close()
+                       ap_scan = False
+                       essid = None
+
+                       for s in supplicant:
+                               split = s.strip().split('=',1)
+                               if split[0] == 'ap_scan':
+                                       print "[Wlan.py] Got Hidden SSID Scan  Value "+split[1]
+                                       if split[1] == '2':
+                                               ap_scan = True
+                                       else:
+                                               ap_scan = False
+                                               
+                               elif split[0] == 'ssid':
+                                       print "[Wlan.py] Got SSID "+split[1][1:-1]
+                                       essid = split[1][1:-1]
+                                       
+                               elif split[0] == 'proto':
+                                       print "split[1]",split[1]
+                                       config.plugins.wlan.encryption.enabled.value = True
+                                       if split[1] == "WPA" :
+                                               mode = 'WPA'
+                                       if split[1] == "WPA WPA2" :
+                                               mode = 'WPA/WPA2'
+                                       if split[1] == "WPA RSN" :
+                                               mode = 'WPA2'
+                                       config.plugins.wlan.encryption.type.value = mode
+                                       print "[Wlan.py] Got Encryption: "+mode
+                                       
+                               #currently unused !
+                               #elif split[0] == 'key_mgmt':
+                               #       print "split[1]",split[1]
+                               #       if split[1] == "WPA-PSK" :
+                               #               config.plugins.wlan.encryption.enabled.value = True
+                               #               config.plugins.wlan.encryption.type.value = "WPA/WPA2"
+                               #       print "[Wlan.py] Got Encryption: "+ config.plugins.wlan.encryption.type.value
+                                       
+                               elif split[0] == 'wep_key0':
+                                       config.plugins.wlan.encryption.enabled.value = True
+                                       config.plugins.wlan.encryption.type.value = 'WEP'
+                                       if split[1].startswith('"') and split[1].endswith('"'):
+                                               config.plugins.wlan.encryption.wepkeytype.value = 'ASCII'
+                                               config.plugins.wlan.encryption.psk.value = split[1][1:-1]
+                                       else:
+                                               config.plugins.wlan.encryption.wepkeytype.value = 'HEX'
+                                               config.plugins.wlan.encryption.psk.value = split[1]                                             
+                                       print "[Wlan.py] Got Encryption: WEP - keytype is: "+config.plugins.wlan.encryption.wepkeytype.value
+                                       print "[Wlan.py] Got Encryption: WEP - key0 is: "+config.plugins.wlan.encryption.psk.value
+                                       
+                               elif split[0] == 'psk':
+                                       config.plugins.wlan.encryption.psk.value = split[1][1:-1]
+                                       print "[Wlan.py] Got PSK: "+split[1][1:-1]
+                               else:
+                                       pass
+                               
+                       if ap_scan is True:
+                               config.plugins.wlan.hiddenessid.value = essid
+                               config.plugins.wlan.essid.value = 'hidden...'
+                       else:
+                               config.plugins.wlan.hiddenessid.value = essid
+                               config.plugins.wlan.essid.value = essid
+                       wsconfig = {
+                                       'hiddenessid': config.plugins.wlan.hiddenessid.value,
+                                       'ssid': config.plugins.wlan.essid.value,
+                                       'encryption': config.plugins.wlan.encryption.enabled.value,
+                                       'encryption_type': config.plugins.wlan.encryption.type.value,
+                                       'encryption_wepkeytype': config.plugins.wlan.encryption.wepkeytype.value,
+                                       'key': config.plugins.wlan.encryption.psk.value,
+                               }
+               
+                       for (key, item) in wsconfig.items():
+                               if item is "None" or item is "":
+                                       if key == 'hiddenessid':
+                                               wsconfig['hiddenessid'] = "home"
+                                       if key == 'ssid':
+                                               wsconfig['ssid'] = "home"
+                                       if key == 'encryption':
+                                               wsconfig['encryption'] = True                           
+                                       if key == 'encryption':
+                                               wsconfig['encryption_type'] = "WPA/WPA2"
+                                       if key == 'encryption':
+                                               wsconfig['encryption_wepkeytype'] = "ASCII"
+                                       if key == 'encryption':
+                                               wsconfig['key'] = "mysecurewlan"
+
+               except:
+                       print "[Wlan.py] Error parsing /etc/wpa_supplicant.conf"
+                       wsconfig = {
+                                       'hiddenessid': "home",
+                                       'ssid': "home",
+                                       'encryption': True,
+                                       'encryption_type': "WPA/WPA2",
+                                       'encryption_wepkeytype': "ASCII",
+                                       'key': "mysecurewlan",
+                               }
+               print "[Wlan.py] WS-CONFIG-->",wsconfig
+               return wsconfig
+
+       
+       def restart(self, iface):
+               system("start-stop-daemon -K -x /usr/sbin/wpa_supplicant")
+               system("start-stop-daemon -S -x /usr/sbin/wpa_supplicant -- -B -i"+iface+" -c/etc/wpa_supplicant.conf")
+
+class Status:
+       def __init__(self):
+               self.wlaniface = {}
+               self.backupwlaniface = {}
+               self.WlanConsole = Console()
+
+       def stopWlanConsole(self):
+               if self.WlanConsole is not None:
+                       print "killing self.WlanConsole"
+                       self.WlanConsole = None
+                       
+       def getDataForInterface(self, iface, callback = None):
+               self.WlanConsole = Console()
+               cmd = "iwconfig " + iface
+               self.WlanConsole.ePopen(cmd, self.iwconfigFinished, [iface, callback])
+
+       def iwconfigFinished(self, result, retval, extra_args):
+               (iface, callback) = extra_args
+               data = { 'essid': False, 'frequency': False, 'acesspoint': False, 'bitrate': False, 'encryption': False, 'quality': False, 'signal': False }
+               for line in result.splitlines():
+                       line = line.strip()
+                       if "ESSID" in line:
+                               if "off/any" in line:
+                                       ssid = _("No Connection")
+                               else:
+                                       tmpssid=(line[line.index('ESSID')+7:len(line)-1])
+                                       if tmpssid == '':
+                                               ssid = _("Hidden networkname")
+                                       elif tmpssid ==' ':
+                                               ssid = _("Hidden networkname")
+                                       else:
+                                           ssid = tmpssid
+                               #print "SSID->",ssid
+                               if ssid is not None:
+                                       data['essid'] = ssid
+                       if 'Frequency' in line:
+                               frequency = line[line.index('Frequency')+10 :line.index(' GHz')]
+                               #print "Frequency",frequency   
+                               if frequency is not None:
+                                       data['frequency'] = frequency
+                       if "Access Point" in line:
+                               ap=line[line.index('Access Point')+14:len(line)]
+                               #print "AP",ap
+                               if ap is not None:
+                                       data['acesspoint'] = ap
+                                       if ap == "Not-Associated":
+                                               data['essid'] = _("No Connection")
+                       if "Bit Rate" in line:
+                               if "kb" in line:
+                                       br = line[line.index('Bit Rate')+9 :line.index(' kb/s')]
+                                       if br == '0':
+                                               br = _("Unsupported")
+                                       else:
+                                               br += " Mb/s"
+                               else:
+                                       br = line[line.index('Bit Rate')+9 :line.index(' Mb/s')] + " Mb/s"
+                               #print "Bitrate",br
+                               if br is not None:
+                                       data['bitrate'] = br
+                       if 'Encryption key' in line:
+                               if ":off" in line:
+                                       if data['acesspoint'] is not "Not-Associated":
+                                               enc = _("Unsupported")
+                                       else:
+                                               enc = _("Disabled")
+                               else:
+                                       enc = line[line.index('Encryption key')+15 :line.index('   Security')]
+                                       if enc is not None:
+                                               enc = _("Enabled")
+                               #print "Encryption key",enc 
+                               if enc is not None:
+                                       data['encryption'] = enc
+                       if 'Quality' in line:
+                               if "/100" in line:
+                                       qual = line[line.index('Quality')+8:line.index('/100')]
+                               else:
+                                       qual = line[line.index('Quality')+8:line.index('Sig')]
+                               #print "Quality",qual
+                               if qual is not None:
+                                       data['quality'] = qual
+                       if 'Signal level' in line:
+                               if "dBm" in line:
+                                       signal = line[line.index('Signal level')+14 :line.index(' dBm')]
+                                       signal += " dBm"
+                               elif "/100" in line:
+                                       signal = line[line.index('Signal level')+13:line.index('/100  Noise')]
+                                       signal += "%"
+                               else:
+                                       signal = line[line.index('Signal level')+13:line.index('  Noise')]
+                                       signal += "%"
+                               #print "Signal level",signal            
+                               if signal is not None:
+                                       data['signal'] = signal
+
+               self.wlaniface[iface] = data
+               self.backupwlaniface = self.wlaniface
+               
+               if self.WlanConsole is not None:
+                       if len(self.WlanConsole.appContainers) == 0:
+                               print "self.wlaniface after loading:", self.wlaniface
+                               if callback is not None:
+                                       callback(True,self.wlaniface)
+
+       def getAdapterAttribute(self, iface, attribute):
+               print "im getAdapterAttribute"
+               self.iface = iface
+               if self.wlaniface.has_key(self.iface):
+                       print "self.wlaniface.has_key",self.iface
+                       if self.wlaniface[self.iface].has_key(attribute):
+                               return self.wlaniface[self.iface][attribute]
+               return None
+       
+iStatus = Status()
\ No newline at end of file
diff --git a/lib/python/Plugins/SystemPlugins/WirelessLan/__init__.py b/lib/python/Plugins/SystemPlugins/WirelessLan/__init__.py
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/lib/python/Plugins/SystemPlugins/WirelessLan/flags.py b/lib/python/Plugins/SystemPlugins/WirelessLan/flags.py
new file mode 100755 (executable)
index 0000000..4435f84
--- /dev/null
@@ -0,0 +1,104 @@
+# -*- coding: ISO-8859-1 -*-
+# python-wifi -- a wireless library to access wireless cards via python
+# Copyright (C) 2004, 2005, 2006 Róman Joost
+#
+#    This library is free software; you can redistribute it and/or
+#    modify it under the terms of the GNU Lesser General Public License
+#    as published by the Free Software Foundation; either version 2.1 of
+#    the License, or (at your option) any later version.
+#
+#    This library is distributed in the hope that it will be useful, but
+#    WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+#    Lesser General Public License for more details.
+#
+#    You should have received a copy of the GNU Lesser General Public
+#    License along with this library; if not, write to the Free Software
+#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+#    USA 
+
+modes = ['Auto', 
+         'Ad-Hoc',
+         'Managed',
+         'Master', 
+         'Repeat',
+         'Second',
+         'Monitor']
+
+IFNAMSIZE = 16
+IW_ESSID_MAX_SIZE = 16
+
+KILO = 10**3
+MEGA = 10**6
+GIGA = 10**9
+
+# ioctl calls for the Linux/i386 kernel
+SIOCIWFIRST   = 0x8B00    # FIRST ioctl identifier
+SIOCGIFCONF   = 0x8912    # ifconf struct
+SIOCGIWNAME   = 0x8B01    # get name == wireless protocol
+SIOCGIWFREQ   = 0x8B05    # get channel/frequency
+SIOCSIWMODE   = 0x8B06    # set the operation mode
+SIOCGIWMODE   = 0x8B07    # get operation mode
+SIOCGIWSENS   = 0x8B09    # get sensitivity
+SIOCGIWAP     = 0x8B15    # get AP MAC address
+SIOCSIWSCAN   = 0x8B18    # set scanning off
+SIOCGIWSCAN   = 0x8B19    # get scanning results
+SIOCGIWRATE   = 0x8B21    # get default bit rate
+SIOCGIWRTS    = 0x8B23    # get rts/cts threshold
+SIOCGIWFRAG   = 0x8B25    # get fragmention thrh
+SIOCGIWTXPOW  = 0x8B27    # get transmit power (dBm)
+SIOCGIWRETRY  = 0x8B29    # get retry limit
+SIOCGIWRANGE  = 0x8B0B    # range
+SIOCGIWSTATS  = 0x8B0F    # get wireless statistics
+SIOCSIWESSID  = 0x8B1A    # set essid
+SIOCGIWESSID  = 0x8B1B    # get essid
+SIOCGIWPOWER  = 0x8B2D    # get power managment settings
+SIOCGIWENCODE = 0x8B2B    # get encryption information
+SIOCIWLAST    = 0x8BFF    # LAST ioctl identifier
+
+# Power management flags
+IW_POWER_ON = 0x0000        # No details ...
+IW_POWER_TYPE = 0xF000      # Type of parameter
+IW_POWER_PERIOD = 0x1000    # Value is a period/duration of
+IW_POWER_TIMEOUT = 0x2000   # Value is a timeout
+IW_POWER_MODE = 0x0F00      # Power management mode
+IW_POWER_MIN = 0x0001       # Value is a minimum
+IW_POWER_MAX = 0x0002       # Value is a maximum
+IW_POWER_RELATIVE = 0x0004  # Value is not in seconds/ms/us
+
+# Retry limits 
+IW_RETRY_TYPE = 0xF000      # Type of parameter
+
+# encoding stuff
+IW_ENCODE_DISABLED = 0x8000     # encoding is disabled
+IW_ENCODE_NOKEY = 0x0800      # key is write only, not present
+
+# constants responsible for scanning
+IW_SCAN_MAX_DATA = 4096
+
+IW_EV_LCP_LEN = 4
+IW_EV_CHAR_LEN = IW_EV_LCP_LEN + IFNAMSIZE
+IW_EV_UINT_LEN = IW_EV_LCP_LEN + 4
+IW_EV_FREQ_LEN = IW_EV_LCP_LEN + 8
+IW_EV_ADDR_LEN = IW_EV_LCP_LEN + 16
+IW_EV_POINT_LEN = IW_EV_LCP_LEN + 4
+IW_EV_PARAM_LEN = IW_EV_LCP_LEN + 8
+IW_EV_QUAL_LEN = IW_EV_LCP_LEN + 4
+
+EPERM = 1
+E2BIG = 7
+EAGAIN = 11
+
+IWHT_NULL = 0
+IWHT_CHAR = 2
+IWHT_UINT = 4
+IWHT_FREQ = 5
+IWHT_ADDR = 6
+IWHT_POINT = 8
+IWHT_PARAM = 9
+IWHT_QUAL = 10
+
+IWEVFIRST     = 0x8C00    # FIRST event identifier
+IWEVQUAL      = 0x8C01    # Quality statistics from scan
+IWEVCUSTOM    = 0x8C02    # Custom Ascii string from Driver
+IWEVLAST      = 0x8C0A    # LAST event identifier
diff --git a/lib/python/Plugins/SystemPlugins/WirelessLan/iwlibs.py b/lib/python/Plugins/SystemPlugins/WirelessLan/iwlibs.py
new file mode 100755 (executable)
index 0000000..c5f9c6d
--- /dev/null
@@ -0,0 +1,1114 @@
+# -*- coding: ISO-8859-1 -*-
+# python-wifi -- a wireless library to access wireless cards via python
+# Copyright (C) 2004, 2005, 2006 Róman Joost
+# 
+# Contributions from:
+#   Mike Auty <m.auty@softhome.net> (Iwscanresult, Iwscan)
+#
+#    This library is free software; you can redistribute it and/or
+#    modify it under the terms of the GNU Lesser General Public License
+#    as published by the Free Software Foundation; either version 2.1 of
+#    the License, or (at your option) any later version.
+#
+#    This library is distributed in the hope that it will be useful, but
+#    WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+#    Lesser General Public License for more details.
+#
+#    You should have received a copy of the GNU Lesser General Public
+#    License along with this library; if not, write to the Free Software
+#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+#    USA 
+
+from struct import pack as struct_pack, \
+       unpack as struct_unpack, \
+       calcsize as struct_calcsize
+
+from array import array
+from math import ceil, log10
+from fcntl import ioctl
+from socket import AF_INET, SOCK_DGRAM, socket
+from time import sleep
+from re import compile
+
+from flags import *    
+
+def getNICnames():
+    """ extract wireless device names of /proc/net/wireless 
+        
+        returns empty list if no devices are present
+
+        >>> getNICnames()
+        ['eth1', 'wifi0']
+    """
+    device = compile('[a-z]+[0-9]+')
+    ifnames = []
+    
+    f = open('/proc/net/wireless', 'r')
+    data = f.readlines()
+    for line in data:
+        try:
+            ifnames.append(device.search(line).group())
+        except AttributeError:
+            pass 
+    # if we couldn't lookup the devices, try to ask the kernel
+    if ifnames == []:
+        ifnames = getConfiguredNICnames()
+    
+    return ifnames
+
+def getConfiguredNICnames():
+    """get the *configured* ifnames by a systemcall
+       
+       >>> getConfiguredNICnames()
+       []
+    """
+    iwstruct = Iwstruct()
+    ifnames = []
+    buff = array('c', '\0'*1024)
+    caddr_t, length = buff.buffer_info()
+    s = iwstruct.pack('iP', length, caddr_t)
+    try:
+        result = iwstruct._fcntl(SIOCGIFCONF, s)
+    except IOError, (i, e):
+        return i, e
+   
+    # get the interface names out of the buffer
+    for i in range(0, 1024, 32):
+        ifname = buff.tostring()[i:i+32]
+        ifname = struct_unpack('32s', ifname)[0]
+        ifname = ifname.split('\0', 1)[0]
+        if ifname:
+            # verify if ifnames are really wifi devices
+            wifi = Wireless(ifname)
+            result = wifi.getAPaddr()
+            if result[0] == 0:
+                ifnames.append(ifname)
+
+    return ifnames  
+
+def makedict(**kwargs):
+    return kwargs
+
+
+class Wireless(object):
+    """Access to wireless interfaces"""
+    
+    def __init__(self, ifname):
+        self.sockfd = socket(AF_INET, SOCK_DGRAM)
+        self.ifname = ifname
+        self.iwstruct = Iwstruct()
+    
+    def getAPaddr(self):
+        """ returns accesspoint mac address 
+        
+            >>> from iwlibs import Wireless, getNICnames
+            >>> ifnames = getNICnames()
+            >>> ifnames
+            ['eth1', 'wifi0']
+            >>> wifi = Wireless(ifnames[0])
+            >>> wifi.getAPaddr()
+            '00:0D:88:8E:4E:93'
+
+            Test with non-wifi card:
+            >>> wifi = Wireless('eth0')
+            >>> wifi.getAPaddr()
+            (95, 'Operation not supported')
+
+            Test with non-existant card:
+            >>> wifi = Wireless('eth2')
+            >>> wifi.getAPaddr()
+            (19, 'No such device')
+        """
+        buff, s = self.iwstruct.pack_wrq(32)
+        i, result = self.iwstruct.iw_get_ext(self.ifname, 
+                                             SIOCGIWAP,
+                                             data=s)
+        if i > 0:
+            return result
+
+        return self.iwstruct.getMAC(result)
+   
+    def getBitrate(self):
+        """returns device currently set bit rate 
+        
+            >>> from iwlibs import Wireless
+            >>> wifi = Wireless('eth1')
+            >>> wifi.getBitrate()
+            '11 Mb/s'
+        """
+        i, result = self.iwstruct.iw_get_ext(self.ifname, 
+                                            SIOCGIWRATE)
+        if i > 0:
+            return result
+        iwfreq = Iwfreq(result)
+        return iwfreq.getBitrate()
+    
+    def getBitrates(self):
+        """returns the number of available bitrates for the device
+           
+            >>> from iwlibs import Wireless
+            >>> wifi = Wireless('eth1')
+            >>> num, rates = wifi.getBitrates()
+            >>> num == len(rates)
+            True
+        """
+        range = Iwrange(self.ifname)
+        if range.errorflag:
+            return (range.errorflag, range.error)
+        return (range.num_bitrates, range.bitrates)
+
+    def getChannelInfo(self):
+        """returns the number of channels and available frequency for
+           the device
+
+            >>> from iwlibs import Wireless
+            >>> wifi = Wireless('eth1')
+            >>> num, rates = wifi.getChannelInfo()
+            >>> num == len(rates)
+            True
+            """
+        range = Iwrange(self.ifname)
+        if range.errorflag:
+            return (range.errorflag, range.error)
+        return (range.num_channels, range.frequencies)
+
+    def getEssid(self):
+        """get essid information
+            
+            >>> from iwlibs import Wireless
+            >>> wifi = Wireless('eth1')
+            >>> wifi.getEssid()
+            'romanofski'
+        """
+        essid = ""
+        buff, s = self.iwstruct.pack_wrq(32)
+        i, result = self.iwstruct.iw_get_ext(self.ifname, 
+                                             SIOCGIWESSID, 
+                                             data=s)
+        if i > 0:
+            return result
+        str = buff.tostring()
+        return str.strip('\x00')
+
+    def setEssid(self, essid):
+        """set essid """
+        raise NotImplementedError
+        if len(essid) > IW_ESSID_MAX_SIZE:
+            return "essid to big"
+        buff, s = self.iwstruct.pack_test(essid, 32)
+        i, result = self.iwstruct.iw_get_ext(self.ifname, 
+                                             SIOCSIWESSID, 
+                                             data=s)
+        if i > 0:
+            return result
+
+    def getEncryption(self):
+        """get encryption information which is probably a string of '*',
+        'open', 'private'
+            
+            as a normal user, you will get a 'Operation not permitted'
+            error:
+        
+            >>> from iwlibs import Wireless
+            >>> wifi = Wireless('eth1')
+            >>> wifi.getEncryption()
+            (1, 'Operation not permitted')
+        """
+        iwpoint = Iwpoint(self.ifname)
+        if iwpoint.errorflag:
+            return (iwpoint.errorflag, iwpoint.error)
+        return iwpoint.getEncryptionKey()
+
+    def getFragmentation(self):
+        """returns fragmentation threshold 
+           
+           It depends on what the driver says. If you have fragmentation
+           threshold turned on, you'll get an int. If it's turned of
+           you'll get a string: 'off'.
+            >>> from iwlibs import Wireless
+            >>> wifi = Wireless('eth1')
+            >>> wifi.getFragmentation()
+            'off'
+        """
+        iwparam = Iwparam(self.ifname, SIOCGIWFRAG)
+        if iwparam.errorflag:
+            return (iwparam.errorflag, iwparam.error)
+        return iwparam.getValue()
+        
+    def getFrequency(self):
+        """returns currently set frequency of the card 
+            
+            >>> from iwlibs import Wireless
+            >>> wifi = Wireless('eth1')
+            >>> wifi.getFrequency()
+            '2.417GHz' 
+        """
+        i, r = self.iwstruct.iw_get_ext(self.ifname, 
+                                        SIOCGIWFREQ)
+        if i > 0:
+            return (i, r)
+        iwfreq = Iwfreq(r)
+        return iwfreq.getFrequency()
+    
+        
+    def getMode(self):
+        """returns currently set operation mode 
+            
+            >>> from iwlibs import Wireless
+            >>> wifi = Wireless('eth1')
+            >>> wifi.getMode()
+            'Managed' 
+        """
+        i, result = self.iwstruct.iw_get_ext(self.ifname, 
+                                             SIOCGIWMODE)
+        if i > 0:
+            return result
+        mode = self.iwstruct.unpack('i', result[:4])[0]
+        return modes[mode]
+
+    def setMode(self, mode):
+        """sets the operation mode """
+        try:
+            this_modes = [x.lower() for x in modes]
+            mode = mode.lower()
+            wifimode = this_modes.index(mode)
+        except ValueError:
+            return "Invalid operation mode!"
+        
+        s = self.iwstruct.pack('I', wifimode)
+        i, result = self.iwstruct.iw_get_ext(self.ifname, 
+                                             SIOCSIWMODE, 
+                                             data=s)
+        if i > 0:
+            return result
+    
+    def getWirelessName(self):
+        """ returns wireless name 
+            
+            >>> from iwlibs import Wireless
+            >>> wifi = Wireless('eth1')
+            >>> wifi.getWirelessName()
+            'IEEE 802.11-DS'
+        """
+        i, result = self.iwstruct.iw_get_ext(self.ifname, 
+                                             SIOCGIWNAME)
+        if i > 0:
+            return result
+        return result.split('\0')[0]
+    
+    def getPowermanagement(self):
+        """returns power management settings 
+            
+            >>> from iwlibs import Wireless
+            >>> wifi = Wireless('eth1')
+            >>> wifi.getPowermanagement()
+            'off'
+        """
+        iwparam = Iwparam(self.ifname, SIOCGIWPOWER)
+        if iwparam.errorflag:
+            return (iwparam.errorflag, iwparam.error)
+        return iwparam.getValue()
+
+    
+    def getRetrylimit(self):
+        """returns limit retry/lifetime
+
+            man iwconfig:
+            Most cards have MAC retransmissions, and some  allow  to set
+            the behaviour of the retry mechanism.
+                     
+            >>> from iwlibs import Wireless
+            >>> wifi = Wireless('eth1')
+            >>> wifi.getRetrylimit()
+            16
+        """
+        iwparam = Iwparam(self.ifname, SIOCGIWRETRY)
+        if iwparam.errorflag:
+            return (iwparam.errorflag, iwparam.error)
+        return iwparam.getValue()
+    
+    def getRTS(self):
+        """returns rts threshold 
+            
+            returns int, 'auto', 'fixed', 'off'
+        
+            man iwconfig:
+            RTS/CTS adds a handshake before each packet transmission to
+            make sure that the channel is clear. This adds overhead, but
+            increases performance in case of hidden  nodes or  a large
+            number of active nodes. This parameter sets the size of the
+            smallest packet for which the node sends RTS;  a value equal
+            to the maximum packet size disable the mechanism. 
+            
+            >>> from iwlibs import Wireless
+            >>> wifi = Wireless('eth1')
+            >>> wifi.getRTS()
+            'off'
+        """
+        iwparam = Iwparam(self.ifname, SIOCGIWRTS)
+        if iwparam.errorflag:
+            return (iwparam.errorflag, iwparam.error)
+        return iwparam.getValue()
+    
+    def getSensitivity(self):
+        """returns sensitivity information 
+        
+            man iwconfig:
+            This is the lowest signal level for which the hardware
+            attempt  packet  reception, signals  weaker  than  this are
+            ignored. This is used to avoid receiving background noise,
+            so you should  set  it according  to  the  average noise
+            level. Positive values are assumed to be the raw value used
+            by the hardware  or a percentage, negative values are
+            assumed to be dBm.
+        
+            >>> from iwlibs import Wireless
+            >>> wifi = Wireless('eth1')
+            >>> wifi.getSensitivity()
+            'off'
+            
+        """
+        iwparam = Iwparam(self.ifname, SIOCGIWSENS)
+        if iwparam.errorflag:
+            return (iwparam.errorflag, iwparam.error)
+        return iwparam.getValue()
+        
+    def getTXPower(self):
+        """returns transmit power in dBm 
+        
+            >>> from iwlibs import Wireless
+            >>> wifi = Wireless('eth1')
+            >>> wifi.getTXPower()
+            '17 dBm'
+        """
+        i, r = self.iwstruct.iw_get_ext(self.ifname, 
+                                        SIOCGIWTXPOW)
+        if i > 0:
+            return (i, r)
+        iwfreq = Iwfreq(r)
+        return iwfreq.getTransmitPower()
+         
+    def getStatistics(self):
+        """returns statistics information which can also be found in
+           /proc/net/wireless 
+        """
+        iwstats = Iwstats(self.ifname)
+        if iwstats.errorflag > 0:
+            return (iwstats.errorflag, iwstats.error)
+        return [iwstats.status, iwstats.qual, iwstats.discard,
+            iwstats.missed_beacon]
+
+    def scan(self):
+        """returns Iwscanresult objects, after a successful scan"""
+        iwscan = Iwscan(self.ifname)
+        return iwscan.scan()
+
+
+class Iwstruct(object):
+    """basic class to handle iwstruct data """
+    
+    def __init__(self):
+        self.idx = 0
+        self.sockfd = socket(AF_INET, SOCK_DGRAM)
+
+    def parse_data(self, fmt, data):
+        """ unpacks raw C data """
+        size = struct_calcsize(fmt)
+        idx = self.idx
+
+        str = data[idx:idx + size]
+        self.idx = idx+size
+        value = struct_unpack(fmt, str)
+
+        # take care of a tuple like (int, )
+        if len(value) == 1:
+            return value[0]
+        else:
+            return value
+    
+    def pack(self, fmt, *args):
+        """ calls struct_pack and returns the result """
+        return struct_pack(fmt, *args)
+
+    def pack_wrq(self, buffsize):
+        """ packs wireless request data for sending it to the kernel """
+        # Prepare a buffer
+        # We need the address of our buffer and the size for it. The
+        # ioctl itself looks for the pointer to the address in our
+        # memory and the size of it.
+        # Dont change the order how the structure is packed!!!
+        buff = array('c', '\0'*buffsize)
+        caddr_t, length = buff.buffer_info()
+        s = struct_pack('Pi', caddr_t, length)
+        return buff, s
+    
+    def pack_test(self, string, buffsize):
+        """ packs wireless request data for sending it to the kernel """
+        buffsize = buffsize - len(string)
+        buff = array('c', string+'\0'*buffsize)
+        caddr_t, length = buff.buffer_info()
+        s = struct_pack('Pii', caddr_t, length, 1)
+        return buff, s
+
+    def unpack(self, fmt, packed_data):
+        """ unpacks data with given format """
+        return struct_unpack(fmt, packed_data)
+
+    def _fcntl(self, request, args):
+        return ioctl(self.sockfd.fileno(), request, args)
+    
+    def iw_get_ext(self, ifname, request, data=None):
+        """ read information from ifname """
+        # put some additional data behind the interface name
+        if data is not None:
+            buff = IFNAMSIZE-len(ifname)
+            ifreq = ifname + '\0'*buff
+            ifreq = ifreq + data
+        else:
+            ifreq = (ifname + '\0'*32)
+            
+        try:
+            result = self._fcntl(request, ifreq)
+        except IOError, (i, e):
+            return i, e
+        
+        return (0, result[16:])
+
+    def getMAC(self, packed_data):
+        """ extracts mac addr from packed data and returns it as str """
+        mac_addr = struct_unpack('xxBBBBBB', packed_data[:8])
+        return "%02X:%02X:%02X:%02X:%02X:%02X" % mac_addr
+
+class Iwparam(object):
+    """class to hold iwparam data """
+    
+    def __init__(self, ifname, ioctl):
+        # (i) value, (b) fixed, (b) disabled, (b) flags
+        self.fmt = "ibbH"
+        self.value = 0
+        self.fixed = 0
+        self.disabled = 0
+        self.flags = 0
+        self.errorflag = 0
+        self.error = ""
+        self.ioctl = ioctl 
+        self.ifname = ifname
+        self.update()
+    
+    def getValue(self):
+        """returns the value if not disabled """
+
+        if self.disabled:
+            return 'off'
+        if self.flags & IW_RETRY_TYPE == 0:
+            return self.getRLAttributes()
+        else:
+            return self.getPMAttributes()
+
+    def getRLAttributes(self):
+        """returns a string with attributes determined by self.flags
+        """
+        return self.value
+
+    def getPMAttributes(self):
+        """returns a string with attributes determined by self.flags
+           and IW_POWER*
+        """
+        result = ""
+        
+        # Modifiers
+        if self.flags & IW_POWER_MIN == 0:
+            result = " min"
+        if self.flags & IW_POWER_MAX == 0:
+            result = " max"
+            
+        # Type
+        if self.flags & IW_POWER_TIMEOUT == 0:
+            result = " period:" 
+        else:
+            result = " timeout:"
+        # Value with or without units
+        # IW_POWER_RELATIVE - value is *not* in s/ms/us
+        if self.flags & IW_POWER_RELATIVE:
+            result += "%f" %(float(self.value)/MEGA)
+        else:
+            if self.value >= MEGA:
+                result += "%fs" %(float(self.value)/MEGA)
+            elif self.value >= KILO:
+                result += "%fms" %(float(self.value)/KILO)
+            else:
+                result += "%dus" % self.value
+
+        return result
+        
+    def update(self):
+        iwstruct = Iwstruct()
+        i, r = iwstruct.iw_get_ext(self.ifname, 
+                                   self.ioctl)
+        if i > 0:
+            self.errorflag = i
+            self.error = r
+        self._parse(r)
+    
+    def _parse(self, data):
+        """ unpacks iwparam data """
+        iwstruct = Iwstruct()
+        self.value, self.fixed, self.disabled, self.flags =\
+            iwstruct.parse_data(self.fmt, data)
+        
+class Iwfreq(object):
+    """ class to hold iwfreq data
+        delegates to Iwstruct class
+    """
+    
+    def __init__(self, data=None):
+        self.fmt = "ihbb"
+        if data is not None:
+            self.frequency = self.parse(data)
+        else:
+            self.frequency = 0
+        self.iwstruct = Iwstruct()
+        
+    def __getattr__(self, attr):
+        return getattr(self.iwstruct, attr)
+
+    def parse(self, data):
+        """ unpacks iwparam"""
+        
+        size = struct_calcsize(self.fmt)
+        m, e, i, pad = struct_unpack(self.fmt, data[:size])
+        # XXX well, its not *the* frequency - we need a better name
+        if e == 0:
+            return m
+        else:
+            return float(m)*10**e
+    
+    def getFrequency(self):
+        """returns Frequency (str) 
+            
+           data - binary data returned by systemcall (iw_get_ext())
+        """
+        freq = self.frequency
+        
+        if freq >= GIGA:
+            return "%0.3fGHz" %(freq/GIGA)
+
+        if freq >= MEGA:
+            return "%0.3fMHZ" %(freq/MEGA)
+
+        if freq >= KILO:
+            return "%0.3fKHz" %(freq/KILO)
+    
+    def getBitrate(self):
+        """ returns Bitrate in Mbit 
+        
+           data - binary data returned by systemcall (iw_get_ext())
+        """
+        bitrate = self.frequency
+
+        if bitrate >= GIGA:
+            return "%i Gb/s" %(bitrate/GIGA)
+
+        if bitrate >= MEGA:
+            return "%i Mb/s" %(bitrate/MEGA)
+        
+        if bitrate >= KILO:
+            return "%i Kb/s" %(bitrate/KILO)
+
+    def getTransmitPower(self):
+        """ returns transmit power in dbm """
+        # XXX something flaky is going on with m and e
+        # eg. m = 50 and e should than be 0, because the number is stored in
+        # m and don't needs to be recalculated
+        return "%i dBm" %self.mw2dbm(self.frequency/10)
+    
+    def getChannel(self, freq):
+        """returns channel information given by frequency
+           
+           returns None if frequency can't be converted
+           freq = frequency to convert (int)
+           iwrange = Iwrange object
+        """
+        
+        try:
+            freq = float(freq)
+        except:
+            return None
+        
+        lut = {}
+        #13 Channels beginning at 2.412GHz and inreasing by 0,005 GHz steps
+        for i in range(0,12):
+            cur = float( 2.412 + ( i * 0.005 ) )
+            lut[str(cur)] = i+1
+        # Channel 14 need special actions ;)
+        lut['2.484'] = 14
+        
+        
+        if str(freq) in lut.keys():
+                return lut[str(freq)]
+        
+        return None
+    
+          
+    def mw2dbm(self, mwatt):
+        """ converts mw to dbm(float) """
+        return ceil(10.0 * log10(mwatt))
+        
+    def _setFrequency(self, list):
+        """sets self.frequency by given list 
+           
+           currently only used by Iwrange
+        """
+        assert len(list) == 4
+        m, e, i, pad = list
+        if e == 0:
+            self.frequency = m
+        else:
+            self.frequency = m #float(m)*10**e
+
+class Iwstats(object):
+    """ class to hold iwstat data """
+
+    def __init__(self, ifname):
+        # (2B) status, 4B iw_quality, 6i iw_discarded
+        self.fmt = "2B4B6i"
+        self.status = 0
+        self.qual = Iwquality()
+        self.discard = {}
+        self.missed_beacon = 0
+        self.ifname = ifname
+        self.errorflag = 0
+        self.error = ""
+        self.update()
+
+    def update(self):
+        iwstruct = Iwstruct()
+        buff, s = iwstruct.pack_wrq(32)
+        i, result = iwstruct.iw_get_ext(self.ifname, 
+                                        SIOCGIWSTATS, 
+                                        data=s)
+        if i > 0:
+            self.error = result
+            self.errorflag = i
+        self._parse(buff.tostring())
+    
+    def _parse(self, data):
+        """ unpacks iwstruct data """
+        struct = Iwstruct()
+        iwqual = Iwquality()
+        iwstats_data = struct.parse_data(self.fmt, data)
+        
+        self.status = iwstats_data[0:2]
+        self.qual.quality, self.qual.sl, self.qual.nl,\
+            self.qual.flags = iwstats_data[2:6]
+        nwid, code, frag, retries, flags = iwstats_data[6:11]
+        self.missed_beacon = iwstats_data[11:12][0]
+        self.discard = makedict(nwid=nwid, code=code,
+            fragment=frag, retries=retries, misc=flags)
+
+class Iwquality(object):
+    """ class to hold iwquality data """
+
+    def __init__(self):
+        self.quality = 0
+        self.sl = 0
+        self.nl = 0
+        self.updated = 0
+        self.fmt = "4B"
+
+    def parse(self, data):
+        """ unpacks iwquality data """
+        struct = Iwstruct()
+        qual, sl, nl, flags = struct.parse_data(self.fmt, data)
+
+        # compute signal and noise level
+        self.signal_level = sl
+        self.noise_level = nl
+
+        # asign the other values
+        self.quality = qual
+        self.updated = flags
+
+    def setValues(self, list):
+        """ assigns values given by a list to our attributes """
+        attributes = ["quality", "signallevel", "noise_level",
+            "updated"]
+        assert len(list) == 4
+        
+        for i in range(len(list)):
+            setattr(self, attributes[i], list[i])
+    
+    def getSignallevel(self):
+        """ returns signal level """
+        return self.sl-0x100
+
+    def setSignallevel(self, sl):
+        """ sets signal level """
+        self.sl = sl
+    signallevel = property(getSignallevel, setSignallevel)
+    
+    def getNoiselevel(self):
+        """ returns noise level """
+        return self.nl - 0x100
+
+    def setNoiselevel(self):
+        raise NotImplementedError
+        self.nl = nl
+    noiselevel = property(getNoiselevel, setNoiselevel)
+
+class Iwpoint(object):
+    """ class to hold iwpoint data """
+
+    def __init__(self, ifname):
+        self.key = [0,0,0,0]
+        self.fields = 0
+        self.flags = 0
+        # (4B) pointer to data, H length, H flags
+        self.fmt = "4BHH"
+        self.errorflag = 0
+        self.error = ""
+        self.ifname = ifname
+        self.update()
+
+    def __getattr__(self, attr):
+        return getattr(self.iwstruct, attr)
+    
+    def update(self):
+        iwstruct = Iwstruct()
+        buff, s = iwstruct.pack_wrq(32)
+        i, result = iwstruct.iw_get_ext(self.ifname, 
+                                        SIOCGIWENCODE, 
+                                        data=s)
+        if i > 0:
+            self.errorflag = i
+            self.error = result
+        self._parse(result)
+        
+    def getEncryptionKey(self):
+        """ returns encryption key as '**' or 'off' as str """
+        if self.flags & IW_ENCODE_DISABLED != 0:
+            return 'off'
+        elif self.flags & IW_ENCODE_NOKEY != 0:
+            # a key is set, so print it
+            return '**' * self.fields
+    
+    def _parse(self, data):
+        """ unpacks iwpoint data
+        """
+        iwstruct = Iwstruct()
+        ptr, ptr, ptr, ptr, self.fields, self.flags =\
+            iwstruct.parse_data(self.fmt, data)
+        self.key = [ptr, ptr, ptr, ptr]
+
+class Iwrange(object):
+    """holds iwrange struct """
+    IW_MAX_FREQUENCIES = 32
+
+    def __init__(self, ifname):
+        self.fmt = "iiihb6ii4B4Bi32i2i2i2i2i3h8h2b2bhi8i2b3h2i2ihB17x"\
+            + self.IW_MAX_FREQUENCIES*"ihbb"
+        
+        self.ifname = ifname
+        self.errorflag = 0
+        self.error = ""
+        
+        # informative stuff
+        self.throughput = 0
+        
+        # nwid (or domain id)
+        self.min_nwid = self.max_nwid = 0
+        
+        # frequency for backward compatibility
+        self.old_num_channels = self.old_num_frequency = self.old_freq = 0
+        
+        # signal level threshold
+        self.sensitivity = 0
+        
+        # link quality
+        self.max_qual = Iwquality()
+        self.avg_qual = Iwquality()
+
+        # rates
+        self.num_bitrates = 0
+        self.bitrates = []
+
+        # rts threshold
+        self.min_rts = self.max_rts = 0
+
+        # fragmention threshold
+        self.min_frag = self.max_frag = 0
+
+        # power managment
+        self.min_pmp = self.max_pmp = 0
+        self.min_pmt = self.max_pmt = 0
+        self.pmp_flags = self.pmt_flags = self.pm_capa = 0
+
+        # encoder stuff
+        self.encoding_size = 0
+        self.num_encoding_sizes = self.max_encoding_tokens = 0
+        self.encoding_login_index = 0
+
+        # transmit power
+        self.txpower_capa = self.num_txpower = self.txpower = 0
+
+        # wireless extension version info
+        self.we_vers_compiled = self.we_vers_src = 0
+
+        # retry limits and lifetime
+        self.retry_capa = self.retry_flags = self.r_time_flags = 0
+        self.min_retry = self.max_retry = 0
+        self.min_r_time = self.max_r_time = 0
+
+        # frequency
+        self.num_channels = self.num_frequency = 0
+        self.frequencies = []
+        self.update()
+    
+    def update(self):
+        """updates Iwrange object by a system call to the kernel 
+           and updates internal attributes
+        """
+        iwstruct = Iwstruct()
+        buff, s = iwstruct.pack_wrq(640)
+        i, result = iwstruct.iw_get_ext(self.ifname, 
+                                        SIOCGIWRANGE, 
+                                        data=s)
+        if i > 0:
+            self.errorflag = i
+            self.error = result
+        data = buff.tostring()
+        self._parse(data)
+        
+    def _parse(self, data):
+        struct = Iwstruct()
+        result = struct.parse_data(self.fmt, data)
+        
+        # XXX there is maybe a much more elegant way to do this
+        self.throughput, self.min_nwid, self.max_nwid = result[0:3]
+        self.old_num_channels, self.old_num_frequency = result[3:5]
+        self.old_freq = result[5:11]
+        self.sensitivity = result[11]
+        self.max_qual.setValues(result[12:16])
+        self.avg_qual.setValues(result[16:20])
+        self.num_bitrates = result[20] # <- XXX
+        raw_bitrates = result[21:53]
+        for rate in raw_bitrates:
+            iwfreq = Iwfreq()
+            iwfreq.frequency = rate
+            br = iwfreq.getBitrate()
+            if br is not None:
+                self.bitrates.append(br)
+            
+        self.min_rts, self.max_rts = result[53:55]
+        self.min_frag, self.max_frag = result[55:57]
+        self.min_pmp, self.max_pmp = result[57:59]
+        self.min_pmt, self.max_pmt = result[59:61]
+        self.pmp_flags, self.pmt_flags, self.pm_capa = result[61:64]
+        self.encoding_size = result[64:72]
+        self.num_encoding_sizes, self.max_encoding_tokens = result[72:74]
+        self.encoding_login_index = result[74:76]
+        self.txpower_capa, self.num_txpower = result[76:78]
+        self.txpower = result[78:86]
+        self.we_vers_compiled, self.we_vers_src = result[86:88]
+        self.retry_capa, self.retry_flags, self.r_time_flags = result[88:91]
+        self.min_retry, self.max_retry = result[91:93]
+        self.min_r_time, self.max_r_time = result[93:95]
+        self.num_channels = result[95]
+        self.num_frequency = result[96]
+        freq = result[97:]
+        
+        i = self.num_frequency
+        for x in range(0, len(freq), 4):
+            iwfreq = Iwfreq()
+            iwfreq._setFrequency(freq[x:x+4])
+            fq = iwfreq.getFrequency()
+            if fq is not None:
+                self.frequencies.append(fq)
+            i -= 1
+            if i <= 0:
+                break
+        
+class Iwscan(object):
+    """class to handle AP scanning"""
+    
+    def __init__(self, ifname):
+        self.ifname = ifname
+        self.range = Iwrange(ifname)
+        self.errorflag = 0
+        self.error = ""
+        self.stream = None
+        self.aplist = None
+                
+    def scan(self, fullscan=True):
+        """Completes a scan for available access points,
+           and returns them in Iwscanresult format
+           
+           fullscan: If False, data is read from a cache of the last scan
+                     If True, a scan is conducted, and then the data is read
+        """
+        # By default everything is fine, do not wait
+        result = 1
+        if fullscan:
+            self.setScan()
+            if self.errorflag > EPERM:
+                raise RuntimeError, 'setScan failure ' + str(self.errorflag) + " " + str(self.error)
+                return None
+            elif self.errorflag < EPERM:
+                # Permission was NOT denied, therefore we must WAIT to get results
+                result = 250
+        
+        while (result > 0):
+            sleep(result/1000)
+            result = self.getScan()
+        
+        if result < 0 or self.errorflag != 0:
+            raise RuntimeError, 'getScan failure ' + str(self.errorflag) + " " + str(self.error)
+        
+        return self.aplist
+        
+        
+    def setScan(self):
+        """Triggers the scan, if we have permission
+        """
+        iwstruct = Iwstruct()
+        s = iwstruct.pack('Pii', 0, 0, 0)
+        i, result = iwstruct.iw_get_ext(self.ifname, 
+                                        SIOCSIWSCAN,s)
+        if i > 0:
+            self.errorflag = i
+            self.error = result
+        return result
+        
+    def getScan(self):
+        """Retreives results, stored from the most recent scan
+           Returns 0 if successful, a delay if the data isn't ready yet
+           or -1 if something really nasty happened
+        """
+        iwstruct = Iwstruct()
+        i = E2BIG
+        bufflen = IW_SCAN_MAX_DATA
+        
+        # Keep resizing the buffer until it's large enough to hold the scan
+        while (i == E2BIG):
+            buff, s = iwstruct.pack_wrq(bufflen)
+            i, result = iwstruct.iw_get_ext(self.ifname, 
+                                            SIOCGIWSCAN,
+                                            data=s)
+            if i == E2BIG:
+                pbuff, newlen = iwstruct.unpack('Pi', s)
+                if bufflen < newlen:
+                    bufflen = newlen
+                else:
+                    bufflen = bufflen * 2
+        
+        if i == EAGAIN:
+            return 100
+        if i > 0:
+            self.errorflag = i
+            self.error = result
+            return -1
+        
+        pbuff, reslen = iwstruct.unpack('Pi', s)
+        if reslen > 0:
+            # Initialize the stream, and turn it into an enumerator
+            self.aplist = self._parse(buff.tostring())
+            return 0
+        
+    def _parse(self, data):
+        """Parse the event stream, and return a list of Iwscanresult objects
+        """
+        iwstruct = Iwstruct()
+        scanresult = None
+        aplist = []
+
+        # Run through the stream, until broken
+        while 1:
+            # If we're the stream doesn't have enough space left for a header, break
+            if len(data) < IW_EV_LCP_LEN:
+                break;
+        
+            # Unpack the header
+            length, cmd = iwstruct.unpack('HH', data[:4])
+            # If the header says the following data is shorter than the header, then break
+            if length < IW_EV_LCP_LEN:
+                break;
+
+            # Put the events into their respective result data
+            if cmd == SIOCGIWAP:
+                if scanresult is not None:
+                    aplist.append(scanresult)
+                scanresult = Iwscanresult(data[IW_EV_LCP_LEN:length], self.range)
+            elif scanresult is None:
+                raise RuntimeError, 'Attempting to add an event without AP data'
+            else:
+                scanresult.addEvent(cmd, data[IW_EV_LCP_LEN:length])
+            
+            # We're finished with the preveious event
+            data = data[length:]
+        
+        # Don't forgset the final result
+        if scanresult.bssid != "00:00:00:00:00:00":
+            aplist.append(scanresult)
+        else:
+            raise RuntimeError, 'Attempting to add an AP without a bssid'
+        return aplist
+
+class Iwscanresult(object):
+    """An object to contain all the events associated with a single scanned AP
+    """
+    
+    def __init__(self, data, range):
+        """Initialize the scan result with the access point data"""
+        self.iwstruct = Iwstruct()
+        self.range = range
+        self.bssid = "%02X:%02X:%02X:%02X:%02X:%02X" % struct_unpack('BBBBBB', data[2:8])
+        self.essid = None
+        self.mode = None
+        self.rate = []
+        self.quality = Iwquality() 
+        self.frequency = None
+        self.encode = None
+        self.custom = []
+        self.protocol = None
+
+    def addEvent(self, cmd, data):
+        """Attempts to add the data from an event to a scanresult
+           Only certain data is accept, in which case the result is True
+           If the event data is invalid, None is returned
+           If the data is valid but unused, False is returned
+        """
+        if cmd <= SIOCIWLAST:
+            if cmd < SIOCIWFIRST:
+                return None
+        elif cmd >= IWEVFIRST:
+            if cmd > IWEVLAST:
+                return None
+        else:
+            return None
+            
+        if cmd == SIOCGIWESSID:
+            self.essid = data[4:]
+        elif cmd == SIOCGIWMODE:
+            self.mode = modes[self.iwstruct.unpack('i', data[:4])[0]]
+        elif cmd == SIOCGIWRATE:
+            # TODO, deal with multiple rates, or at least the highest rate
+            freqsize = struct_calcsize("ihbb")
+            while len(data) >= freqsize:
+                iwfreq = Iwfreq(data)
+                self.rate.append(iwfreq.getBitrate())
+                data = data[freqsize:]
+        elif cmd == IWEVQUAL:
+            self.quality.parse(data)
+        elif cmd == SIOCGIWFREQ:
+            self.frequency = Iwfreq(data)
+        elif cmd == SIOCGIWENCODE:
+            self.encode = data
+        elif cmd == IWEVCUSTOM:
+            self.custom.append(data[1:])
+        elif cmd == SIOCGIWNAME:
+            self.protocol = data[:len(data)-2]
+        else:
+            #print "Cmd:", cmd
+            return False
+        return True
\ No newline at end of file
diff --git a/lib/python/Plugins/SystemPlugins/WirelessLan/plugin.py b/lib/python/Plugins/SystemPlugins/WirelessLan/plugin.py
new file mode 100755 (executable)
index 0000000..b7a64b9
--- /dev/null
@@ -0,0 +1,285 @@
+from enigma import eTimer
+from Screens.Screen import Screen
+from Components.ActionMap import ActionMap, NumberActionMap
+from Components.Pixmap import Pixmap,MultiPixmap
+from Components.Label import Label
+from Components.Sources.StaticText import StaticText
+from Components.MenuList import MenuList
+from Components.config import config, getConfigListEntry, ConfigYesNo, NoSave, ConfigSubsection, ConfigText, ConfigSelection, ConfigPassword
+from Components.ConfigList import ConfigListScreen
+from Components.Network import Network, iNetwork
+from Components.Console import Console
+from Plugins.Plugin import PluginDescriptor
+from os import system, path as os_path, listdir
+from Wlan import Wlan, WlanList, wpaSupplicant
+from Wlan import Status, iStatus
+
+plugin_path = "/usr/lib/enigma2/python/Plugins/SystemPlugins/WirelessLan"
+
+list = []
+list.append("WEP")
+list.append("WPA")
+list.append("WPA2")
+list.append("WPA/WPA2")
+
+weplist = []
+weplist.append("ASCII")
+weplist.append("HEX")
+
+config.plugins.wlan = ConfigSubsection()
+config.plugins.wlan.essid = NoSave(ConfigText(default = "home", fixed_size = False))
+config.plugins.wlan.hiddenessid = NoSave(ConfigText(default = "home", fixed_size = False))
+
+config.plugins.wlan.encryption = ConfigSubsection()
+config.plugins.wlan.encryption.enabled = NoSave(ConfigYesNo(default = False))
+config.plugins.wlan.encryption.type = NoSave(ConfigSelection(list, default = "WPA/WPA2" ))
+config.plugins.wlan.encryption.wepkeytype = NoSave(ConfigSelection(weplist, default = "ASCII"))
+config.plugins.wlan.encryption.psk = NoSave(ConfigPassword(default = "mysecurewlan", fixed_size = False))
+
+
+class WlanStatus(Screen):
+       skin = """
+       <screen position="center,center" size="560,400" title="Wireless Network State" >
+               <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="LabelBSSID" render="Label" position="10,60" size="250,25" valign="left" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
+               <widget source="LabelESSID" render="Label" position="10,100" size="250,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
+               <widget source="LabelQuality" render="Label" position="10,140" size="250,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
+               <widget source="LabelSignal" render="Label" position="10,180" size="250,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
+               <widget source="LabelBitrate" render="Label" position="10,220" size="250,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
+               <widget source="LabelEnc" render="Label" position="10,260" size="250,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
+               
+               <widget source="BSSID" render="Label" position="320,60" size="180,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
+               <widget source="ESSID" render="Label" position="320,100" size="180,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
+               <widget source="quality" render="Label" position="320,140" size="180,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
+               <widget source="signal" render="Label" position="320,180" size="180,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
+               <widget source="bitrate" render="Label" position="320,220" size="180,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
+               <widget source="enc" render="Label" position="320,260" size="180,25" valign="center" font="Regular;20" transparent="1" foregroundColor="#FFFFFF" />
+
+               <ePixmap pixmap="skin_default/div-h.png" position="0,350" zPosition="1" size="560,2" />         
+               <widget source="IFtext" render="Label" position="10,355" size="120,21" zPosition="10" font="Regular;20" halign="left" backgroundColor="#25062748" transparent="1" />
+               <widget source="IF" render="Label" position="120,355" size="400,21" zPosition="10" font="Regular;20" halign="left" backgroundColor="#25062748" transparent="1" />
+               <widget source="Statustext" render="Label" position="10,375" size="115,21" zPosition="10" font="Regular;20" halign="left" backgroundColor="#25062748" transparent="1"/>
+               <widget name="statuspic" pixmaps="skin_default/buttons/button_green.png,skin_default/buttons/button_green_off.png" position="130,380" zPosition="10" size="15,16" transparent="1" alphatest="on"/>
+       </screen>
+       """
+       
+       def __init__(self, session, iface):
+               Screen.__init__(self, session)
+               self.session = session
+               self.iface = iface
+               self.skin = WlanStatus.skin
+                                   
+               self["LabelBSSID"] = StaticText(_('Accesspoint:'))
+               self["LabelESSID"] = StaticText(_('SSID:'))
+               self["LabelQuality"] = StaticText(_('Link Quality:'))
+               self["LabelSignal"] = StaticText(_('Signal Strength:'))
+               self["LabelBitrate"] = StaticText(_('Bitrate:'))
+               self["LabelEnc"] = StaticText(_('Encryption:'))
+                       
+               self["BSSID"] = StaticText()
+               self["ESSID"] = StaticText()
+               self["quality"] = StaticText()
+               self["signal"] = StaticText()
+               self["bitrate"] = StaticText()
+               self["enc"] = StaticText()
+
+               self["IFtext"] = StaticText()
+               self["IF"] = StaticText()
+               self["Statustext"] = StaticText()
+               self["statuspic"] = MultiPixmap()
+               self["statuspic"].hide()
+               self["key_red"] = StaticText(_("Close"))
+
+               self.resetList()
+               self.updateStatusbar()
+               
+               self["actions"] = NumberActionMap(["WizardActions", "InputActions", "EPGSelectActions", "ShortcutActions"],
+               {
+                       "ok": self.exit,
+                       "back": self.exit,
+                       "red": self.exit,
+               }, -1)
+               self.timer = eTimer()
+               self.timer.timeout.get().append(self.resetList) 
+               self.onShown.append(lambda: self.timer.start(5000))
+               self.onLayoutFinish.append(self.layoutFinished)
+               self.onClose.append(self.cleanup)
+
+       def cleanup(self):
+               iStatus.stopWlanConsole()
+               
+       def layoutFinished(self):
+               self.setTitle(_("Wireless Network State"))
+               
+       def resetList(self):
+               print "self.iface im resetlist",self.iface
+               iStatus.getDataForInterface(self.iface,self.getInfoCB)
+               
+       def getInfoCB(self,data,status):
+               if data is not None:
+                       if data is True:
+                               if status is not None:
+                                       self["BSSID"].setText(status[self.iface]["acesspoint"])
+                                       self["ESSID"].setText(status[self.iface]["essid"])
+                                       self["quality"].setText(status[self.iface]["quality"]+"%")
+                                       self["signal"].setText(status[self.iface]["signal"])
+                                       self["bitrate"].setText(status[self.iface]["bitrate"])
+                                       self["enc"].setText(status[self.iface]["encryption"])
+                                       self.updateStatusLink(status)
+
+       def exit(self):
+               self.timer.stop()
+               self.close()    
+
+       def updateStatusbar(self):
+               print "self.iface im updateStatusbar",self.iface
+               self["BSSID"].setText(_("Please wait..."))
+               self["ESSID"].setText(_("Please wait..."))
+               self["quality"].setText(_("Please wait..."))
+               self["signal"].setText(_("Please wait..."))
+               self["bitrate"].setText(_("Please wait..."))
+               self["enc"].setText(_("Please wait..."))
+               self["IFtext"].setText(_("Network:"))
+               self["IF"].setText(iNetwork.getFriendlyAdapterName(self.iface))
+               self["Statustext"].setText(_("Link:"))
+
+       def updateStatusLink(self,status):
+               if status is not None:
+                       if status[self.iface]["acesspoint"] == "No Connection" or status[self.iface]["acesspoint"] == "Not-Associated" or status[self.iface]["acesspoint"] == False:
+                               self["statuspic"].setPixmapNum(1)
+                       else:
+                               self["statuspic"].setPixmapNum(0)
+                       self["statuspic"].show()                
+
+class WlanScan(Screen):
+       skin = """
+       <screen position="center,center" size="560,400" title="Choose a Wireless Network" >
+               <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" />
+               <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="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" />
+               <widget name="list" position="5,50" size="550,280" scrollbarMode="showOnDemand" />
+               <ePixmap pixmap="skin_default/div-h.png" position="0,340" zPosition="1" size="560,2" />         
+               <widget source="info" render="Label" position="0,350" size="560,50" font="Regular;24" halign="center" valign="center" backgroundColor="#25062748" transparent="1" />
+       </screen>
+       """
+
+       def __init__(self, session, iface):
+               Screen.__init__(self, session)
+               self.session = session
+               self.iface = iface
+               self.skin = WlanScan.skin
+               self.skin_path = plugin_path
+               self.oldInterfaceState = iNetwork.getAdapterAttribute(self.iface, "up")
+               
+               self["info"] = StaticText()
+               
+               self.list = []  
+               self["list"] = WlanList(self.session, self.iface)
+               
+               self.setInfo()
+
+               self["key_red"] = StaticText(_("Close"))
+               self["key_green"] = StaticText(_("Connect"))
+               self["key_yellow"] = StaticText(_("Refresh"))
+                       
+               self["actions"] = NumberActionMap(["WizardActions", "InputActions", "EPGSelectActions"],
+               {
+                       "ok": self.select,
+                       "back": self.cancel,
+               }, -1)
+               
+               self["shortcuts"] = ActionMap(["ShortcutActions"],
+               {
+                       "red": self.cancel,
+                       "green": self.select,
+                       "yellow": self.rescan,
+               })
+               self.onLayoutFinish.append(self.layoutFinished)
+               
+       def layoutFinished(self):
+               self.setTitle(_("Choose a wireless network"))
+       
+       def select(self):
+               cur = self["list"].getCurrent()
+               #print "CURRENT",cur
+               if cur is not None:
+                       if cur[1] is not None:
+                               essid = cur[0]
+                               if essid == '':
+                                       essid = cur[1]
+                               encrypted = cur[2]
+                               self.close(essid,self["list"].getList())
+                       else:
+                               self.close(None,None)
+               else:
+                       self.close(None,None)
+       
+       def WlanSetupClosed(self, *ret):
+               if ret[0] == 2:
+                       self.close(None)
+       
+       def rescan(self):
+               self["list"].reload()
+               self.setInfo()
+       
+       def cancel(self):
+               if self.oldInterfaceState is False:
+                       iNetwork.deactivateInterface(self.iface,self.deactivateInterfaceCB)
+               else:
+                       self.close(None)
+
+       def deactivateInterfaceCB(self,data):
+               if data is not None:
+                       if data is True:
+                               iNetwork.getInterfaces(self.cancelCB)
+       
+       def cancelCB(self,data):                        
+               if data is not None:
+                       if data is True:
+                               self.close(None)
+
+       def setInfo(self):
+               length = self["list"].getLength()
+               
+               if length == 0:
+                       self["info"].setText(_("No wireless networks found! Please refresh."))
+               elif length == 1:
+                       self["info"].setText(_("1 wireless network found!"))
+               else:
+                       self["info"].setText(str(length)+_(" wireless networks found!"))        
+
+
+def WlanStatusScreenMain(session, iface):
+       session.open(WlanStatus, iface)
+
+
+def callFunction(iface):
+       
+       w = Wlan(iface)
+       i = w.getWirelessInterfaces()
+       if i:
+               if iface in i:
+                       return WlanStatusScreenMain
+       
+       return None
+
+
+def configStrings(iface):
+       driver = iNetwork.detectWlanModule()
+       print "Found WLAN-Driver:",driver
+       if driver  in ('ralink', 'zydas'):
+               return "        pre-up /usr/sbin/wpa_supplicant -i"+iface+" -c/etc/wpa_supplicant.conf -B -D"+driver+"\n        post-down wpa_cli terminate"
+       else:
+               if config.plugins.wlan.essid.value == "hidden...":
+                       return '        pre-up iwconfig '+iface+' essid "'+config.plugins.wlan.hiddenessid.value+'"\n   pre-up /usr/sbin/wpa_supplicant -i'+iface+' -c/etc/wpa_supplicant.conf -B -dd -D'+driver+'\n    post-down wpa_cli terminate'
+               else:
+                       return '        pre-up iwconfig '+iface+' essid "'+config.plugins.wlan.essid.value+'"\n pre-up /usr/sbin/wpa_supplicant -i'+iface+' -c/etc/wpa_supplicant.conf -B -dd -D'+driver+'\n    post-down wpa_cli terminate'
+
+def Plugins(**kwargs):
+       return PluginDescriptor(name=_("Wireless LAN"), description=_("Connect to a Wireless Network"), where = PluginDescriptor.WHERE_NETWORKSETUP, fnc={"ifaceSupported": callFunction, "configStrings": configStrings, "WlanPluginEntry": lambda x: "Wireless Network Configuartion..."})
+       
\ No newline at end of file
index 48bb28e..c1c6f94 100644 (file)
@@ -101,8 +101,8 @@ for where in targetlist:
        importlist.append(where[0])
 
 file.write("""from Screens.Screen import Screen
-from Plugins.Plugin import PluginDescriptor, %s
-""" % ', '.join(importlist))
+from Plugins.Plugin import PluginDescriptor
+""")
 
 mainlist = []
 for count in range(len(targetlist)):
index 3dde7e2..f8edba1 100644 (file)
@@ -6,6 +6,7 @@ from Components.Label import Label
 from Components.EpgList import EPGList, EPG_TYPE_SINGLE, EPG_TYPE_SIMILAR, EPG_TYPE_MULTI
 from Components.ActionMap import ActionMap
 from Components.TimerSanityCheck import TimerSanityCheck
+from Components.UsageConfig import preferredTimerPath
 from Components.Sources.ServiceEvent import ServiceEvent
 from Components.Sources.Event import Event
 from Screens.TimerEdit import TimerSanityConflict
@@ -235,7 +236,7 @@ class EPGSelection(Screen):
                                self.session.openWithCallback(cb_func, MessageBox, _("Do you really want to delete %s?") % event.getEventName())
                                break
                else:
-                       newEntry = RecordTimerEntry(serviceref, checkOldTimers = True, *parseEvent(event))
+                       newEntry = RecordTimerEntry(serviceref, checkOldTimers = True, dirname = preferredTimerPath(), *parseEvent(event))
                        self.session.openWithCallback(self.finishedAdd, TimerEntry, newEntry)
 
        def finishedAdd(self, answer):
index c1ffb58..cced3ce 100644 (file)
@@ -6,6 +6,7 @@ from Components.Button import Button
 from Components.Label import Label
 from Components.ScrollLabel import ScrollLabel
 from Components.TimerList import TimerList
+from Components.UsageConfig import preferredTimerPath
 from enigma import eEPGCache, eTimer, eServiceReference
 from RecordTimer import RecordTimerEntry, parseEvent, AFTEREVENT
 from TimerEntry import TimerEntry
@@ -85,7 +86,7 @@ class EventViewBase:
                                self.session.openWithCallback(cb_func, MessageBox, _("Do you really want to delete %s?") % event.getEventName())
                                break
                else:
-                       newEntry = RecordTimerEntry(self.currentService, checkOldTimers = True, *parseEvent(self.event))
+                       newEntry = RecordTimerEntry(self.currentService, checkOldTimers = True, dirname = preferredTimerPath(), *parseEvent(self.event))
                        self.session.openWithCallback(self.finishedAdd, TimerEntry, newEntry)
 
        def finishedAdd(self, answer):
index 59cc21d..a15c7ac 100644 (file)
@@ -212,7 +212,6 @@ class MoviePlayer(InfoBarBase, InfoBarShowHide, \
                                        return
 
                if answer in ("quit", "quitanddeleteconfirmed"):
-                       config.movielist.last_videodir.cancel()
                        self.close()
                elif answer == "movielist":
                        ref = self.session.nav.getCurrentlyPlayingServiceReference()
index 2cbfeb7..a3e56a4 100644 (file)
@@ -10,6 +10,7 @@ from Components.ServiceEventTracker import ServiceEventTracker
 from Components.Sources.Boolean import Boolean
 from Components.config import config, ConfigBoolean, ConfigClock
 from Components.SystemInfo import SystemInfo
+from Components.UsageConfig import preferredInstantRecordPath, defaultMoviePath
 from EpgSelection import EPGSelection
 from Plugins.Plugin import PluginDescriptor
 
@@ -28,7 +29,7 @@ from Screens.TimeDateInput import TimeDateInput
 from ServiceReference import ServiceReference
 
 from Tools import Notifications
-from Tools.Directories import SCOPE_HDD, resolveFilename, fileExists
+from Tools.Directories import fileExists
 
 from enigma import eTimer, eServiceCenter, eDVBServicePMTHandler, iServiceInformation, \
        iPlayableService, eServiceReference, eEPGCache
@@ -691,8 +692,6 @@ class InfoBarSeek:
                                iPlayableService.evSOF: self.__evSOF,
                        })
 
-               self.minSpeedBackward = useSeekBackHack and 16 or 0
-
                class InfoBarSeekActionMap(HelpableActionMap):
                        def __init__(self, screen, *args, **kwargs):
                                HelpableActionMap.__init__(self, screen, *args, **kwargs)
@@ -739,24 +738,19 @@ class InfoBarSeek:
                self.__seekableStatusChanged()
 
        def makeStateForward(self, n):
-               minspeed = config.seek.stepwise_minspeed.value
-               repeat = int(config.seek.stepwise_repeat.value)
-               if minspeed != "Never" and n >= int(minspeed) and repeat > 1:
-                       return (0, n * repeat, repeat, ">> %dx" % n)
-               else:
+#              minspeed = config.seek.stepwise_minspeed.value
+#              repeat = int(config.seek.stepwise_repeat.value)
+#              if minspeed != "Never" and n >= int(minspeed) and repeat > 1:
+#                      return (0, n * repeat, repeat, ">> %dx" % n)
+#              else:
                        return (0, n, 0, ">> %dx" % n)
 
        def makeStateBackward(self, n):
-               minspeed = config.seek.stepwise_minspeed.value
-               repeat = int(config.seek.stepwise_repeat.value)
-               if self.minSpeedBackward and n < self.minSpeedBackward:
-                       r = (self.minSpeedBackward - 1)/ n + 1
-                       if minspeed != "Never" and n >= int(minspeed) and repeat > 1:
-                               r = max(r, repeat)
-                       return (0, -n * r, r, "<< %dx" % n)
-               elif minspeed != "Never" and n >= int(minspeed) and repeat > 1:
-                       return (0, -n * repeat, repeat, "<< %dx" % n)
-               else:
+#              minspeed = config.seek.stepwise_minspeed.value
+#              repeat = int(config.seek.stepwise_repeat.value)
+#              if minspeed != "Never" and n >= int(minspeed) and repeat > 1:
+#                      return (0, -n * repeat, repeat, "<< %dx" % n)
+#              else:
                        return (0, -n, 0, "<< %dx" % n)
 
        def makeStateSlowMotion(self, n):
@@ -876,7 +870,7 @@ class InfoBarSeek:
                        if config.seek.on_pause.value == "play":
                                self.unPauseService()
                        elif config.seek.on_pause.value == "step":
-                               self.doSeekRelative(0)
+                               self.doSeekRelative(1)
                        elif config.seek.on_pause.value == "last":
                                self.setSeekState(self.lastseekstate)
                                self.lastseekstate = self.SEEK_STATE_PLAY
@@ -949,7 +943,7 @@ class InfoBarSeek:
                        self.setSeekState(self.makeStateBackward(int(config.seek.enter_backward.value)))
                        self.doSeekRelative(-6)
                elif seekstate == self.SEEK_STATE_PAUSE:
-                       self.doSeekRelative(-3)
+                       self.doSeekRelative(-1)
                elif self.isStateForward(seekstate):
                        speed = seekstate[1]
                        if seekstate[2]:
@@ -1212,10 +1206,7 @@ class InfoBarTimeshift:
                        self.setSeekState(self.SEEK_STATE_PAUSE)
 
                if back:
-                       self.doSeek(-5) # seek some gops before end
                        self.ts_rewind_timer.start(200, 1)
-               else:
-                       self.doSeek(-1) # seek 1 gop before end
 
        def rewindService(self):
                self.setSeekState(self.makeStateBackward(int(config.seek.enter_backward.value)))
@@ -1484,7 +1475,7 @@ class InfoBarInstantRecord:
                if isinstance(serviceref, eServiceReference):
                        serviceref = ServiceReference(serviceref)
 
-               recording = RecordTimerEntry(serviceref, begin, end, name, description, eventid, dirname = config.movielist.last_videodir.value)
+               recording = RecordTimerEntry(serviceref, begin, end, name, description, eventid, dirname = preferredInstantRecordPath())
                recording.dontSave = True
                
                if event is None or limitEvent == False:
@@ -1585,9 +1576,9 @@ class InfoBarInstantRecord:
                        self.session.nav.RecordTimer.timeChanged(entry)
 
        def instantRecord(self):
-               dir = config.movielist.last_videodir.value
-               if not fileExists(dir, 'w'):
-                       dir = resolveFilename(SCOPE_HDD)
+               dir = preferredInstantRecordPath()
+               if not dir or not fileExists(dir, 'w'):
+                       dir = defaultMoviePath()
                try:
                        stat = os_stat(dir)
                except:
@@ -1669,17 +1660,46 @@ class InfoBarAudioSelection:
                                else:
                                        break
 
+                       availableKeys = []
+                       usedKeys = []
+
                        if SystemInfo["CanDownmixAC3"]:
-                               tlist = [(_("AC3 downmix") + " - " +(_("Off"), _("On"))[config.av.downmix_ac3.value and 1 or 0], "CALLFUNC", self.changeAC3Downmix),
-                                       ((_("Left"), _("Stereo"), _("Right"))[self.audioChannel.getCurrentChannel()], "mode"),
-                                       ("--", "")] + tlist
-                               keys = [ "red", "green", "", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"] + [""]*n
-                               selection += 3
-                       else:
-                               tlist = [((_("Left"), _("Stereo"), _("Right"))[self.audioChannel.getCurrentChannel()], "mode"), ("--", "")] + tlist
-                               keys = [ "red", "", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"] + [""]*n
+                               flist = [(_("AC3 downmix") + " - " +(_("Off"), _("On"))[config.av.downmix_ac3.value and 1 or 0], "CALLFUNC", self.changeAC3Downmix),
+                                       ((_("Left"), _("Stereo"), _("Right"))[self.audioChannel.getCurrentChannel()], "mode")]
+                               usedKeys.extend(["red", "green"])
+                               availableKeys.extend(["yellow", "blue"])
                                selection += 2
-                       self.session.openWithCallback(self.audioSelected, ChoiceBox, title=_("Select audio track"), list = tlist, selection = selection, keys = keys, skin_name = "AudioTrackSelection")
+                       else:
+                               flist = [((_("Left"), _("Stereo"), _("Right"))[self.audioChannel.getCurrentChannel()], "mode")]
+                               usedKeys.extend(["red"])
+                               availableKeys.extend(["green", "yellow", "blue"])
+                               selection += 1
+
+                       if hasattr(self, "runPlugin"):
+                               class PluginCaller:
+                                       def __init__(self, fnc, *args):
+                                               self.fnc = fnc
+                                               self.args = args
+                                       def __call__(self, *args, **kwargs):
+                                               self.fnc(*self.args)
+
+                               Plugins = [ (p.name, PluginCaller(self.runPlugin, p)) for p in plugins.getPlugins(where = PluginDescriptor.WHERE_AUDIOMENU) ]
+
+                               for p in Plugins:
+                                       selection += 1
+                                       flist.append((p[0], "CALLFUNC", p[1]))
+                                       if availableKeys:
+                                               usedKeys.append(availableKeys[0])
+                                               del availableKeys[0]
+                                       else:
+                                               usedKeys.append("")
+
+                       flist.append(("--", ""))
+                       usedKeys.append("")
+                       selection += 1
+
+                       keys = usedKeys + [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" ] + [""] * n
+                       self.session.openWithCallback(self.audioSelected, ChoiceBox, title=_("Select audio track"), list = flist + tlist, selection = selection, keys = keys, skin_name = "AudioTrackSelection")
                else:
                        del self.audioTracks
 
index 61d7105..29d94f5 100644 (file)
@@ -289,6 +289,11 @@ class LocationBox(Screen, NumericalTextInput, HelpableScreen):
                        else:
                                self["filelist"].refresh()
                                self.removeBookmark(name, True)
+                               val = self.realBookmarks and self.realBookmarks.value
+                               if val and name in val:
+                                       val.remove(name)
+                                       self.realBookmarks.value = val
+                                       self.realBookmarks.save()
 
        def up(self):
                self[self.currList].up()
index 44994b8..585983c 100755 (executable)
@@ -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
+       TextBox.py FactoryReset.py RecordPaths.py
 
index 5f2032f..bb0709e 100644 (file)
@@ -97,8 +97,12 @@ class Menu(Screen):
 
        def addMenu(self, destList, node):
                requires = node.get("requires")
-               if requires and not SystemInfo.get(requires, False):
-                       return
+               if requires:
+                       if requires[0] == '!':
+                               if SystemInfo.get(requires[1:], False):
+                                       return
+                       elif not SystemInfo.get(requires, False):
+                               return
                MenuTitle = _(node.get("text", "??").encode("UTF-8"))
                entryID = node.get("entryID", "undefined")
                weight = node.get("weight", 50)
@@ -120,8 +124,12 @@ class Menu(Screen):
 
        def addItem(self, destList, node):
                requires = node.get("requires")
-               if requires and not SystemInfo.get(requires, False):
-                       return
+               if requires:
+                       if requires[0] == '!':
+                               if SystemInfo.get(requires[1:], False):
+                                       return
+                       elif not SystemInfo.get(requires, False):
+                               return
                item_text = node.get("text", "").encode("UTF-8")
                entryID = node.get("entryID", "undefined")
                weight = node.get("weight", 50)
index 174a4f0..0468f8a 100644 (file)
@@ -7,8 +7,9 @@ from Components.DiskInfo import DiskInfo
 from Components.Pixmap import Pixmap
 from Components.Label import Label
 from Components.PluginComponent import plugins
-from Components.config import config, ConfigSubsection, ConfigText, ConfigInteger, ConfigLocations
+from Components.config import config, ConfigSubsection, ConfigText, ConfigInteger, ConfigLocations, ConfigSet
 from Components.Sources.ServiceEvent import ServiceEvent
+from Components.UsageConfig import defaultMoviePath
 
 from Plugins.Plugin import PluginDescriptor
 
@@ -31,6 +32,7 @@ config.movielist.last_timer_videodir = ConfigText(default=resolveFilename(SCOPE_
 config.movielist.videodirs = ConfigLocations(default=[resolveFilename(SCOPE_HDD)])
 config.movielist.first_tags = ConfigText(default="")
 config.movielist.second_tags = ConfigText(default="")
+config.movielist.last_selected_tags = ConfigSet([], default=[])
 
 
 def setPreferredTagEditor(te):
@@ -168,7 +170,10 @@ class MovieSelection(Screen, HelpableScreen, SelectionEventInfo):
                HelpableScreen.__init__(self)
 
                self.tags = [ ]
-               self.selected_tags = None
+               if selectedmovie:
+                       self.selected_tags = config.movielist.last_selected_tags.value
+               else:
+                       self.selected_tags = None
                self.selected_tags_ele = None
 
                self.movemode = False
@@ -183,8 +188,8 @@ class MovieSelection(Screen, HelpableScreen, SelectionEventInfo):
                self["DescriptionBorder"] = Pixmap()
                self["DescriptionBorder"].hide()
 
-               if not pathExists(config.movielist.last_videodir.value):
-                       config.movielist.last_videodir.value = resolveFilename(SCOPE_HDD)
+               if not fileExists(config.movielist.last_videodir.value):
+                       config.movielist.last_videodir.value = defaultMoviePath()
                        config.movielist.last_videodir.save()
                self.current_ref = eServiceReference("2:0:1:0:0:0:0:0:0:0:" + config.movielist.last_videodir.value)
 
@@ -292,6 +297,7 @@ class MovieSelection(Screen, HelpableScreen, SelectionEventInfo):
                self.close(None)
 
        def saveconfig(self):
+               config.movielist.last_selected_tags.value = self.selected_tags
                config.movielist.moviesort.save()
                config.movielist.listtype.save()
                config.movielist.description.save()
@@ -339,8 +345,8 @@ class MovieSelection(Screen, HelpableScreen, SelectionEventInfo):
                self["list"].setSortType(type)
 
        def reloadList(self, sel = None, home = False):
-               if not pathExists(config.movielist.last_videodir.value):
-                       path = resolveFilename(SCOPE_HDD)
+               if not fileExists(config.movielist.last_videodir.value):
+                       path = defaultMoviePath()
                        config.movielist.last_videodir.value = path
                        config.movielist.last_videodir.save()
                        self.current_ref = eServiceReference("2:0:1:0:0:0:0:0:0:0:" + path)
@@ -370,7 +376,7 @@ class MovieSelection(Screen, HelpableScreen, SelectionEventInfo):
 
        def gotFilename(self, res):
                if res is not None and res is not config.movielist.last_videodir.value:
-                       if pathExists(res):
+                       if fileExists(res):
                                config.movielist.last_videodir.value = res
                                config.movielist.last_videodir.save()
                                self.current_ref = eServiceReference("2:0:1:0:0:0:0:0:0:0:" + res)
@@ -392,7 +398,7 @@ class MovieSelection(Screen, HelpableScreen, SelectionEventInfo):
        def showTagsN(self, tagele):
                if not self.tags:
                        self.showTagWarning()
-               elif not tagele or self.selected_tags_ele == tagele or not tagele.value in self.tags:
+               elif not tagele or (self.selected_tags and tagele.value in self.selected_tags) or not tagele.value in self.tags:
                        self.showTagsMenu(tagele)
                else:
                        self.selected_tags_ele = tagele
diff --git a/lib/python/Screens/RecordPaths.py b/lib/python/Screens/RecordPaths.py
new file mode 100644 (file)
index 0000000..c833266
--- /dev/null
@@ -0,0 +1,194 @@
+from Screens.Screen import Screen
+from Screens.LocationBox import MovieLocationBox, TimeshiftLocationBox
+from Screens.MessageBox import MessageBox
+from Components.Label import Label
+from Components.config import config, ConfigSelection, getConfigListEntry, configfile
+from Components.ConfigList import ConfigListScreen
+from Components.ActionMap import ActionMap
+from Tools.Directories import fileExists
+
+
+class RecordPathsSettings(Screen,ConfigListScreen):
+       skin = """
+               <screen name="RecordPathsSettings" position="160,150" size="450,200" title="Recording paths">
+                       <ePixmap pixmap="skin_default/buttons/red.png" position="10,0" size="140,40" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/green.png" position="300,0" size="140,40" alphatest="on" />
+                       <widget source="key_red" render="Label" position="10,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
+                       <widget source="key_green" render="Label" position="300,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
+                       <widget name="config" position="10,44" size="430,146" />
+               </screen>"""
+
+       def __init__(self, session):
+               from Components.Sources.StaticText import StaticText
+               Screen.__init__(self, session)
+               self["key_red"] = StaticText(_("Cancel"))
+               self["key_green"] = StaticText(_("Save"))
+
+               ConfigListScreen.__init__(self, [])
+               self.initConfigList()
+
+               self["setupActions"] = ActionMap(["SetupActions", "ColorActions"],
+               {
+                   "green": self.save,
+                   "red": self.cancel,
+                   "cancel": self.cancel,
+                   "ok": self.ok,
+               }, -2)
+
+       def checkReadWriteDir(self, configele):
+               print "checkReadWrite: ", configele.value
+               if configele.value in [x[0] for x in self.styles] or fileExists(configele.value, "w"):
+                       configele.last_value = configele.value
+                       return True
+               else:
+                       dir = configele.value
+                       configele.value = configele.last_value
+                       self.session.open(
+                               MessageBox,
+                               _("The directory %s is not writable.\nMake sure you select a writable directory instead.")%dir,
+                               type = MessageBox.TYPE_ERROR
+                               )
+                       return False
+
+       def initConfigList(self):
+               self.styles = [ ("<default>", _("<Default movie location>")), ("<current>", _("<Current movielist location>")), ("<timer>", _("<Last timer location>")) ]
+               styles_keys = [x[0] for x in self.styles]
+               tmp = config.movielist.videodirs.value
+               default = config.usage.default_path.value
+               if default not in tmp:
+                       tmp = tmp[:]
+                       tmp.append(default)
+               print "DefaultPath: ", default, tmp
+               self.default_dirname = ConfigSelection(default = default, choices = tmp)
+               tmp = config.movielist.videodirs.value
+               default = config.usage.timer_path.value
+               if default not in tmp and default not in styles_keys:
+                       tmp = tmp[:]
+                       tmp.append(default)
+               print "TimerPath: ", default, tmp
+               self.timer_dirname = ConfigSelection(default = default, choices = self.styles+tmp)
+               tmp = config.movielist.videodirs.value
+               default = config.usage.instantrec_path.value
+               if default not in tmp and default not in styles_keys:
+                       tmp = tmp[:]
+                       tmp.append(default)
+               print "InstantrecPath: ", default, tmp
+               self.instantrec_dirname = ConfigSelection(default = default, choices = self.styles+tmp)
+               default = config.usage.timeshift_path.value
+               tmp = config.usage.allowed_timeshift_paths.value
+               if default not in tmp:
+                       tmp = tmp[:]
+                       tmp.append(default)
+               print "TimeshiftPath: ", default, tmp
+               self.timeshift_dirname = ConfigSelection(default = default, choices = tmp)
+               self.default_dirname.addNotifier(self.checkReadWriteDir, initial_call=False, immediate_feedback=False)
+               self.timer_dirname.addNotifier(self.checkReadWriteDir, initial_call=False, immediate_feedback=False)
+               self.instantrec_dirname.addNotifier(self.checkReadWriteDir, initial_call=False, immediate_feedback=False)
+               self.timeshift_dirname.addNotifier(self.checkReadWriteDir, initial_call=False, immediate_feedback=False)
+
+               self.list = []
+               if config.usage.setup_level.index >= 2:
+                       self.default_entry = getConfigListEntry(_("Default movie location"), self.default_dirname)
+                       self.list.append(self.default_entry)
+                       self.timer_entry = getConfigListEntry(_("Timer record location"), self.timer_dirname)
+                       self.list.append(self.timer_entry)
+                       self.instantrec_entry = getConfigListEntry(_("Instant record location"), self.instantrec_dirname)
+                       self.list.append(self.instantrec_entry)
+               else:
+                       self.default_entry = getConfigListEntry(_("Movie location"), self.default_dirname)
+                       self.list.append(self.default_entry)
+               self.timeshift_entry = getConfigListEntry(_("Timeshift location"), self.timeshift_dirname)
+               self.list.append(self.timeshift_entry)
+               self["config"].setList(self.list)
+
+       def ok(self):
+               currentry = self["config"].getCurrent()
+               self.lastvideodirs = config.movielist.videodirs.value
+               self.lasttimeshiftdirs = config.usage.allowed_timeshift_paths.value
+               if config.usage.setup_level.index >= 2:
+                       txt = _("Default movie location")
+               else:
+                       txt = _("Movie location")
+               if currentry == self.default_entry:
+                       self.entrydirname = self.default_dirname
+                       self.session.openWithCallback(
+                               self.dirnameSelected,
+                               MovieLocationBox,
+                               txt,
+                               self.default_dirname.value
+                       )
+               elif currentry == self.timer_entry:
+                       self.entrydirname = self.timer_dirname
+                       self.session.openWithCallback(
+                               self.dirnameSelected,
+                               MovieLocationBox,
+                               _("Initial location in new timers"),
+                               self.timer_dirname.value
+                       )
+               elif currentry == self.instantrec_entry:
+                       self.entrydirname = self.instantrec_dirname
+                       self.session.openWithCallback(
+                               self.dirnameSelected,
+                               MovieLocationBox,
+                               _("Location for instant recordings"),
+                               self.instantrec_dirname.value
+                       )
+               elif currentry == self.timeshift_entry:
+                       self.entrydirname = self.timeshift_dirname
+                       config.usage.timeshift_path.value = self.timeshift_dirname.value
+                       self.session.openWithCallback(
+                               self.dirnameSelected,
+                               TimeshiftLocationBox
+                       )
+
+       def dirnameSelected(self, res):
+               if res is not None:
+                       self.entrydirname.value = res
+                       if config.movielist.videodirs.value != self.lastvideodirs:
+                               styles_keys = [x[0] for x in self.styles]
+                               tmp = config.movielist.videodirs.value
+                               default = self.default_dirname.value
+                               if default not in tmp:
+                                       tmp = tmp[:]
+                                       tmp.append(default)
+                               self.default_dirname.setChoices(tmp, default=default)
+                               tmp = config.movielist.videodirs.value
+                               default = self.timer_dirname.value
+                               if default not in tmp and default not in styles_keys:
+                                       tmp = tmp[:]
+                                       tmp.append(default)
+                               self.timer_dirname.setChoices(self.styles+tmp, default=default)
+                               tmp = config.movielist.videodirs.value
+                               default = self.instantrec_dirname.value
+                               if default not in tmp and default not in styles_keys:
+                                       tmp = tmp[:]
+                                       tmp.append(default)
+                               self.instantrec_dirname.setChoices(self.styles+tmp, default=default)
+                               self.entrydirname.value = res
+                       if config.usage.allowed_timeshift_paths.value != self.lasttimeshiftdirs:
+                               tmp = config.usage.allowed_timeshift_paths.value
+                               default = self.instantrec_dirname.value
+                               if default not in tmp:
+                                       tmp = tmp[:]
+                                       tmp.append(default)
+                               self.timeshift_dirname.setChoices(tmp, default=default)
+                               self.entrydirname.value = res
+                       if self.entrydirname.last_value != res:
+                               self.checkReadWriteDir(self.entrydirname)
+
+       def save(self):
+               currentry = self["config"].getCurrent()
+               if self.checkReadWriteDir(currentry[1]):
+                       config.usage.default_path.value = self.default_dirname.value
+                       config.usage.timer_path.value = self.timer_dirname.value
+                       config.usage.instantrec_path.value = self.instantrec_dirname.value 
+                       config.usage.timeshift_path.value = self.timeshift_dirname.value
+                       config.usage.default_path.save()
+                       config.usage.timer_path.save()
+                       config.usage.instantrec_path.save()
+                       config.usage.timeshift_path.save()
+                       self.close()
+
+       def cancel(self):
+               self.close()
+
index d0af8f7..bea0872 100644 (file)
@@ -295,9 +295,11 @@ class ScanSetup(ConfigListScreen, Screen, CableTransponderSearchSupport):
 
                self.list = []
                ConfigListScreen.__init__(self, self.list)
-               self.createSetup()
-
-               self["introduction"] = Label(_("Press OK to start the scan"))
+               if not self.scan_nims.value == "":
+                       self.createSetup()
+                       self["introduction"] = Label(_("Press OK to start the scan"))
+               else:
+                       self["introduction"] = Label(_("Nothing to scan!\nPlease setup your tuner settings before you start a service scan."))
 
        def runAsync(self, finished_cb):
                self.finished_cb = finished_cb
@@ -709,6 +711,8 @@ class ScanSetup(ConfigListScreen, Screen, CableTransponderSearchSupport):
                tlist.append(buildTerTransponder(*args, **kwargs))
 
        def keyGo(self):
+               if self.scan_nims.value == "":
+                       return
                tlist = []
                flags = None
                startScan = True
index ff061d8..e5e7af4 100644 (file)
@@ -5,6 +5,7 @@ from Components.Input import Input
 from Components.Label import Label
 from Components.Pixmap import Pixmap
 from Components.config import config, ConfigInteger
+from Components.SystemInfo import SystemInfo
 from enigma import eEPGCache
 from SleepTimer import SleepTimer
 from time import time
@@ -77,7 +78,11 @@ class SleepTimerEdit(Screen):
                        self["red_text"].setText(_("Action:") + " " + _("Disable timer"))
                
                if config.SleepTimer.action.value == "shutdown":
-                       self["green_text"].setText(_("Sleep timer action:") + " " + _("Deep Standby"))
+                       if SystemInfo["DeepstandbySupport"]:
+                               shutdownString = _("Deep Standby")
+                       else:
+                               shutdownString = _("Shutdown")
+                       self["green_text"].setText(_("Sleep timer action:") + " " + shutdownString)
                elif config.SleepTimer.action.value == "standby":
                        self["green_text"].setText(_("Sleep timer action:") + " " + _("Standby"))
                
index 1453c05..eb926ca 100644 (file)
@@ -1,6 +1,7 @@
 from Screen import Screen
 from Components.ConfigList import ConfigListScreen
 from Components.config import config, ConfigSubsection, ConfigSelection, getConfigListEntry
+from Components.SystemInfo import SystemInfo
 from InfoBarGenerics import InfoBarNotifications
 import Screens.Standby
 from Tools import Notifications
@@ -44,7 +45,11 @@ class JobView(InfoBarNotifications, Screen, ConfigListScreen):
 
                self.afterevents = [ "nothing", "standby", "deepstandby", "close" ]
                self.settings = ConfigSubsection()
-               self.settings.afterEvent = ConfigSelection(choices = [("nothing", _("do nothing")), ("close", _("Close")), ("standby", _("go to standby")), ("deepstandby", _("go to deep standby"))], default = self.afterevents[afterEvent])
+               if SystemInfo["DeepstandbySupport"]:
+                       shutdownString = _("go to deep standby")
+               else:
+                       shutdownString = _("shut down")
+               self.settings.afterEvent = ConfigSelection(choices = [("nothing", _("do nothing")), ("close", _("Close")), ("standby", _("go to standby")), ("deepstandby", shutdownString)], default = self.afterevents[afterEvent])
                self.setupList()
                self.state_changed()
 
index caaf8c9..5435498 100644 (file)
@@ -4,6 +4,7 @@ from Components.config import config
 from Components.MenuList import MenuList
 from Components.TimerList import TimerList
 from Components.TimerSanityCheck import TimerSanityCheck
+from Components.UsageConfig import preferredTimerPath
 from RecordTimer import RecordTimerEntry, parseEvent, AFTEREVENT
 from Screen import Screen
 from Screens.ChoiceBox import ChoiceBox
@@ -243,7 +244,7 @@ class TimerEditList(Screen):
                else:
                        data = parseEvent(event, description = False)
 
-               self.addTimer(RecordTimerEntry(serviceref, checkOldTimers = True, dirname = config.movielist.last_timer_videodir.value, *data))
+               self.addTimer(RecordTimerEntry(serviceref, checkOldTimers = True, dirname = preferredTimerPath(), *data))
                
        def addTimer(self, timer):
                self.session.openWithCallback(self.finishedAdd, TimerEntry, timer)
index edd1968..b231b56 100644 (file)
@@ -8,11 +8,12 @@ from Components.MenuList import MenuList
 from Components.Button import Button
 from Components.Label import Label
 from Components.Pixmap import Pixmap
+from Components.SystemInfo import SystemInfo
+from Components.UsageConfig import defaultMoviePath
 from Screens.MovieSelection import getPreferredTagEditor
 from Screens.LocationBox import MovieLocationBox
 from Screens.ChoiceBox import ChoiceBox
 from RecordTimer import AFTEREVENT
-from Tools.Directories import resolveFilename, SCOPE_HDD
 from enigma import eEPGCache
 from time import localtime, mktime, time, strftime
 from datetime import datetime
@@ -93,7 +94,11 @@ class TimerEntry(Screen, ConfigListScreen):
                                day[weekday] = 1
 
                        self.timerentry_justplay = ConfigSelection(choices = [("zap", _("zap")), ("record", _("record"))], default = {0: "record", 1: "zap"}[justplay])
-                       self.timerentry_afterevent = ConfigSelection(choices = [("nothing", _("do nothing")), ("standby", _("go to standby")), ("deepstandby", _("go to deep standby")), ("auto", _("auto"))], default = afterevent)
+                       if SystemInfo["DeepstandbySupport"]:
+                               shutdownString = _("go to deep standby")
+                       else:
+                               shutdownString = _("shut down")
+                       self.timerentry_afterevent = ConfigSelection(choices = [("nothing", _("do nothing")), ("standby", _("go to standby")), ("deepstandby", shutdownString), ("auto", _("auto"))], default = afterevent)
                        self.timerentry_type = ConfigSelection(choices = [("once",_("once")), ("repeated", _("repeated"))], default = type)
                        self.timerentry_name = ConfigText(default = self.timer.name, visible_width = 50, fixed_size = False)
                        self.timerentry_description = ConfigText(default = self.timer.description, visible_width = 50, fixed_size = False)
@@ -106,7 +111,7 @@ class TimerEntry(Screen, ConfigListScreen):
                        self.timerentry_starttime = ConfigClock(default = self.timer.begin)
                        self.timerentry_endtime = ConfigClock(default = self.timer.end)
 
-                       default = self.timer.dirname or resolveFilename(SCOPE_HDD)
+                       default = self.timer.dirname or defaultMoviePath()
                        tmp = config.movielist.videodirs.value
                        if default not in tmp:
                                tmp.append(default)
@@ -273,9 +278,10 @@ class TimerEntry(Screen, ConfigListScreen):
                self.timer.service_ref = self.timerentry_service_ref
                self.timer.tags = self.timerentry_tags
 
-               self.timer.dirname = self.timerentry_dirname.value
-               config.movielist.last_timer_videodir.value = self.timer.dirname
-               config.movielist.last_timer_videodir.save()
+               if self.timer.dirname or self.timerentry_dirname.value != defaultMoviePath():
+                       self.timer.dirname = self.timerentry_dirname.value
+                       config.movielist.last_timer_videodir.value = self.timer.dirname
+                       config.movielist.last_timer_videodir.save()
 
                if self.timerentry_type.value == "once":
                        self.timer.begin, self.timer.end = self.getBeginEnd()
index 6d9cad0..a6b6cc6 100644 (file)
@@ -917,7 +917,7 @@ eDVBServicePlay::eDVBServicePlay(const eServiceReference &ref, eDVBService *serv
        m_is_pvr = !m_reference.path.empty();
        
        m_timeshift_enabled = m_timeshift_active = 0, m_timeshift_changed = 0;
-       m_skipmode = 0;
+       m_skipmode = m_fastforward = m_slowmotion = 0;
        
        CONNECT(m_service_handler.serviceEvent, eDVBServicePlay::serviceEvent);
        CONNECT(m_service_handler_timeshift.serviceEvent, eDVBServicePlay::serviceEventTimeshift);
@@ -1185,7 +1185,10 @@ RESULT eDVBServicePlay::setSlowMotion(int ratio)
        eDebug("eDVBServicePlay::setSlowMotion(%d)", ratio);
        setFastForward_internal(0);
        if (m_decoder)
+       {
+               m_slowmotion = ratio;
                return m_decoder->setSlowMotion(ratio);
+       }
        else
                return -1;
 }
@@ -1197,10 +1200,11 @@ RESULT eDVBServicePlay::setFastForward(int ratio)
        return setFastForward_internal(ratio);
 }
 
-RESULT eDVBServicePlay::setFastForward_internal(int ratio)
+RESULT eDVBServicePlay::setFastForward_internal(int ratio, bool final_seek)
 {
-       int skipmode, ffratio;
-       
+       int skipmode, ffratio, ret = 0;
+       pts_t pos=0;
+
        if (ratio > 8)
        {
                skipmode = ratio;
@@ -1225,19 +1229,28 @@ RESULT eDVBServicePlay::setFastForward_internal(int ratio)
                if (m_cue)
                        m_cue->setSkipmode(skipmode * 90000); /* convert to 90000 per second */
        }
-       
+
        m_skipmode = skipmode;
-       
+
+       if (final_seek)
+               eDebug("trickplay stopped .. ret %d, pos %lld", getPlayPosition(pos), pos);
+
+       m_fastforward = ffratio;
+
        if (!m_decoder)
                return -1;
-               
+
        if (ffratio == 0)
                ; /* return m_decoder->play(); is done in caller*/
        else if (ffratio != 1)
-               return m_decoder->setFastForward(ffratio);
+               ret = m_decoder->setFastForward(ffratio);
        else
-               return m_decoder->setTrickmode();
-       return 0;
+               ret = m_decoder->setTrickmode();
+
+       if (pos)
+               eDebug("final seek after trickplay ret %d", seekTo(pos));
+
+       return ret;
 }
 
 RESULT eDVBServicePlay::seek(ePtr<iSeekableService> &ptr)
@@ -1266,9 +1279,10 @@ RESULT eDVBServicePlay::getLength(pts_t &len)
 RESULT eDVBServicePlay::pause()
 {
        eDebug("eDVBServicePlay::pause");
-       setFastForward_internal(0);
+       setFastForward_internal(0, m_slowmotion || m_fastforward > 1);
        if (m_decoder)
        {
+               m_slowmotion = 0;
                m_is_paused = 1;
                return m_decoder->pause();
        } else
@@ -1278,9 +1292,10 @@ RESULT eDVBServicePlay::pause()
 RESULT eDVBServicePlay::unpause()
 {
        eDebug("eDVBServicePlay::unpause");
-       setFastForward_internal(0);
+       setFastForward_internal(0, m_slowmotion || m_fastforward > 1);
        if (m_decoder)
        {
+               m_slowmotion = 0;
                m_is_paused = 0;
                return m_decoder->play();
        } else
@@ -1728,6 +1743,7 @@ int eDVBServicePlay::selectAudioStream(int i)
 {
        eDVBServicePMTHandler::program program;
        eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
+       pts_t position = -1;
 
        if (h.getProgramInfo(program))
                return -1;
@@ -1750,6 +1766,9 @@ int eDVBServicePlay::selectAudioStream(int i)
                apidtype = program.audioStreams[stream].type;
        }
 
+       if (i != -1 && apid != m_current_audio_pid && (m_is_pvr || m_timeshift_active))
+               eDebug("getPlayPosition ret %d, pos %lld in selectAudioStream", getPlayPosition(position), position);
+
        m_current_audio_pid = apid;
 
        if (m_is_primary && m_decoder->setAudioPID(apid, apidtype))
@@ -1758,6 +1777,9 @@ int eDVBServicePlay::selectAudioStream(int i)
                return -4;
        }
 
+       if (position != -1)
+               eDebug("seekTo ret %d", seekTo(position));
+
        int rdsPid = apid;
 
                /* if we are not in PVR mode, timeshift is not active and we are not in pip mode, check if we need to enable the rds reader */
@@ -2229,7 +2251,7 @@ void eDVBServicePlay::switchToLive()
        m_new_subtitle_page_connection = 0;
        m_rds_decoder_event_connection = 0;
        m_video_event_connection = 0;
-       m_is_paused = m_skipmode = 0; /* not supported in live mode */
+       m_is_paused = m_skipmode = m_fastforward = m_slowmotion = 0; /* not supported in live mode */
 
                /* free the timeshift service handler, we need the resources */
        m_service_handler_timeshift.free();
@@ -2263,12 +2285,13 @@ void eDVBServicePlay::switchToTimeshift()
        r.path = m_timeshift_file;
 
        m_cue = new eCueSheet();
+       m_cue->seekTo(0, -1000);
        m_service_handler_timeshift.tune(r, 1, m_cue, 0, m_dvb_service); /* use the decoder demux for everything */
 
        eDebug("eDVBServicePlay::switchToTimeshift, in pause mode now.");
        pause();
        updateDecoder(); /* mainly to switch off PCR, and to set pause */
-       
+
        m_event((iPlayableService*)this, evSeekableStatusChanged);
 }
 
index b4d0f19..e3c7fd5 100644 (file)
@@ -220,7 +220,7 @@ private:
 
        int m_current_audio_stream;
        int selectAudioStream(int n = -1);
-       RESULT setFastForward_internal(int ratio);
+       RESULT setFastForward_internal(int ratio, bool final_seek=false);
        
                /* timeshift */
        ePtr<iDVBTSRecorder> m_record;
@@ -233,6 +233,8 @@ private:
        void updateDecoder();
        
        int m_skipmode;
+       int m_fastforward;
+       int m_slowmotion;
        
                /* cuesheet */
        
index f74bc5e..d3eaa26 100644 (file)
@@ -37,6 +37,7 @@ eServiceFactoryMP3::eServiceFactoryMP3()
                extensions.push_back("vob");
                extensions.push_back("wav");
                extensions.push_back("wave");
+               extensions.push_back("m4v");
                extensions.push_back("mkv");
                extensions.push_back("avi");
                extensions.push_back("divx");
@@ -240,7 +241,7 @@ eServiceMP3::eServiceMP3(eServiceReference ref)
                sourceinfo.containertype = ctAVI;
                sourceinfo.is_video = TRUE;
        }
-       else if ( strcasecmp(ext, ".mp4") == 0 || strcasecmp(ext, ".mov") == 0)
+       else if ( strcasecmp(ext, ".mp4") == 0 || strcasecmp(ext, ".mov") == 0 || strcasecmp(ext, ".m4v") == 0)
        {
                sourceinfo.containertype = ctMP4;
                sourceinfo.is_video = TRUE;
index a37289a..4f26387 100644 (file)
@@ -27,7 +27,17 @@ entries: .svn/entries
 
 version.h: entries
        > version.h
-       if [ -d .svn ]; then echo "#define ENIGMA2_CHECKOUT_TAG \"D`svn info | grep 'Last Changed Date:' | sed -e 's/[^:]*: \(....\)-\(..\)-\(..\) \(..\):\(..\):\(..\).*+.*$$/\1.\2.\3.\4.\5.\6/'`\"" >> version.h; fi
+       @if [ -d .svn ]; then \
+               echo "#define ENIGMA2_LAST_CHANGE_DATE \"`LANG="en" svn info | grep 'Last Changed Date:' | cut -d' ' -f4`\"" >> version.h; \
+       elif [ -d ../.git ]; then \
+               if [ -f ../.git/last_commit_info ]; then \
+                       echo "#define ENIGMA2_LAST_CHANGE_DATE \"`cat ../.git/last_commit_info | grep 'Date:' | cut -d' ' -f4`\"" >> version.h; \
+                       echo "#define ENIGMA2_BRANCH \"`cat ../.git/branch`\"" >> version.h; \
+               else \
+                       echo "#define ENIGMA2_LAST_CHANGE_DATE \"`LANG="en" git log --max-count=1 --date=short | grep 'Date:' | cut -d' ' -f4`\"" >> version.h; \
+                       echo "#define ENIGMA2_BRANCH \"`LANG="en" git branch | grep '* ' | cut -d' ' -f2`\"" >> version.h; \
+               fi; \
+       fi;
 
 enigma2_LDADD_WHOLE = \
        $(top_builddir)/lib/actions/libenigma_actions.a \
index be9d9a5..3f420b4 100644 (file)
@@ -309,14 +309,21 @@ void quitMainloop(int exitCode)
 
 const char *getEnigmaVersionString()
 {
-       return 
-#ifdef ENIGMA2_CHECKOUT_TAG
-               ENIGMA2_CHECKOUT_TAG
+       std::string date =
+#ifdef ENIGMA2_LAST_CHANGE_DATE
+               ENIGMA2_LAST_CHANGE_DATE;
 #else
-               "HEAD"
+               __DATE__;
 #endif
-                       "-" __DATE__;
+       std::string branch =
+#ifdef ENIGMA2_BRANCH
+               ENIGMA2_BRANCH;
+#else
+               "HEAD";
+#endif
+       return std::string(date + '-' + branch).c_str();
 }
+
 #include <malloc.h>
 
 void dump_malloc_stats(void)
index 46b67b2..2319b7f 100755 (executable)
@@ -32,6 +32,7 @@ enigma2.pot:
        ./xml2po.py     ../lib/python/Plugins/SystemPlugins/Videomode/ >> enigma2.pot
        ./xml2po.py     ../lib/python/Plugins/SystemPlugins/SoftwareManager/ >> enigma2.pot
        ./xml2po.py     ../lib/python/Plugins/SystemPlugins/CleanupWizard/ >> enigma2.pot
+       ./xml2po.py     ../lib/python/Plugins/SystemPlugins/NetworkWizard/ >> enigma2.pot
        cat enigma2_rel25.pot | tail -n +19 >> enigma2.pot
        msguniq --no-location -o enigma2uniq.pot enigma2.pot
        $(RM) enigma2.pot
old mode 100644 (file)
new mode 100755 (executable)
index 133a4ab..077d4bf
--- a/po/ar.po
+++ b/po/ar.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: tuxbox-enigma 0.0.1\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-10-09 13:06+0200\n"
+"POT-Creation-Date: 2009-11-05 18:09+0100\n"
 "PO-Revision-Date: 2006-01-10 01:17+0300\n"
 "Last-Translator: hazem <moustafagamal@hotmail.com>\n"
 "Language-Team: Arabic <moustafagamal@hotmail.com>\n"
@@ -77,6 +77,11 @@ msgstr ""
 
 msgid ""
 "\n"
+"System will restart after the restore!"
+msgstr ""
+
+msgid ""
+"\n"
 "View, install and remove available or installed packages."
 msgstr ""
 
@@ -92,6 +97,9 @@ msgstr ""
 msgid " updates available."
 msgstr ""
 
+msgid " wireless networks found!"
+msgstr ""
+
 msgid "#000000"
 msgstr ""
 
@@ -184,6 +192,9 @@ msgstr ""
 msgid "1"
 msgstr ""
 
+msgid "1 wireless network found!"
+msgstr ""
+
 msgid "1.0"
 msgstr ""
 
@@ -362,6 +373,9 @@ msgstr "عن"
 msgid "About..."
 msgstr "عـن..."
 
+msgid "Accesspoint:"
+msgstr ""
+
 msgid "Action on long powerbutton press"
 msgstr ""
 
@@ -623,6 +637,9 @@ msgstr ""
 msgid "Behavior when a movie reaches the end"
 msgstr ""
 
+msgid "Bitrate:"
+msgstr ""
+
 msgid "Block noise reduction"
 msgstr ""
 
@@ -745,6 +762,9 @@ msgstr ""
 msgid "Choose Tuner"
 msgstr ""
 
+msgid "Choose a wireless network"
+msgstr ""
+
 msgid "Choose backup files"
 msgstr ""
 
@@ -856,6 +876,21 @@ msgstr ""
 msgid "Configuration Mode"
 msgstr "وضع التهيئه"
 
+msgid "Configure interface"
+msgstr ""
+
+msgid "Configure nameservers"
+msgstr ""
+
+msgid "Configure your internal LAN"
+msgstr ""
+
+msgid "Configure your network again"
+msgstr ""
+
+msgid "Configure your wireless LAN again"
+msgstr ""
+
 msgid "Configuring"
 msgstr ""
 
@@ -865,6 +900,9 @@ msgstr ""
 msgid "Connect"
 msgstr ""
 
+msgid "Connect to a Wireless Network"
+msgstr ""
+
 msgid "Connected to"
 msgstr ""
 
@@ -926,6 +964,11 @@ msgstr ""
 
 msgid ""
 "Crashlogs found!\n"
+"Send them to Dream Multimedia ?"
+msgstr ""
+
+msgid ""
+"Crashlogs found!\n"
 "Send them to Dream Multimedia?"
 msgstr ""
 
@@ -1083,6 +1126,9 @@ msgstr "وضعيـه الدايزك"
 msgid "DiSEqC repeats"
 msgstr ""
 
+msgid "DiSEqC-Tester settings"
+msgstr ""
+
 msgid "Dialing:"
 msgstr ""
 
@@ -1096,6 +1142,9 @@ msgstr ""
 msgid "Directory %s nonexistent."
 msgstr ""
 
+msgid "Directory browser"
+msgstr ""
+
 msgid "Disable"
 msgstr "إبطال"
 
@@ -1359,6 +1408,10 @@ msgstr ""
 msgid "Enabled"
 msgstr ""
 
+#, python-format
+msgid "Encrypted: %s"
+msgstr ""
+
 msgid "Encryption"
 msgstr ""
 
@@ -1371,6 +1424,9 @@ msgstr ""
 msgid "Encryption Type"
 msgstr ""
 
+msgid "Encryption:"
+msgstr ""
+
 msgid "End time"
 msgstr ""
 
@@ -1398,12 +1454,6 @@ msgid ""
 "© 2006 - Stephan Reichholf"
 msgstr ""
 
-#. #-#-#-#-#  enigma2.pot (PACKAGE VERSION)  #-#-#-#-#
-#.   TRANSLATORS: Note that "Enter" in the two strings below should *not*
-#.       be interpreted as "Give speed as input". The intended meaning is
-#.       instead "Initial speed when starting winding", i.e. the speed at
-#.       which "winding mode" is entered when first pressing "rewind" or
-#.       "fast forward". 
 msgid "Enter Fast Forward at speed"
 msgstr ""
 
@@ -1461,6 +1511,9 @@ msgstr ""
 msgid "Exit editor"
 msgstr ""
 
+msgid "Exit network wizard"
+msgstr ""
+
 msgid "Exit the cleanup wizard"
 msgstr ""
 
@@ -1648,6 +1701,9 @@ msgstr ""
 msgid "Hidden network SSID"
 msgstr ""
 
+msgid "Hidden networkname"
+msgstr ""
+
 msgid "Hierarchy Information"
 msgstr ""
 
@@ -1801,6 +1857,10 @@ msgstr ""
 msgid "Integrated Wireless"
 msgstr ""
 
+#, python-format
+msgid "Interface: %s"
+msgstr ""
+
 msgid "Intermediate"
 msgstr ""
 
@@ -1906,6 +1966,9 @@ msgstr ""
 msgid "Limits on"
 msgstr ""
 
+msgid "Link Quality:"
+msgstr ""
+
 msgid "Link:"
 msgstr ""
 
@@ -1981,6 +2044,10 @@ msgstr ""
 msgid "Margin before record (minutes)"
 msgstr ""
 
+#, python-format
+msgid "Max. Bitrate: %s"
+msgstr ""
+
 msgid "Media player"
 msgstr ""
 
@@ -2108,6 +2175,9 @@ msgstr ""
 msgid "Network Setup"
 msgstr "ضبط الشبـكة"
 
+msgid "Network Wizard"
+msgstr ""
+
 msgid "Network scan"
 msgstr ""
 
@@ -2150,6 +2220,9 @@ msgstr ""
 msgid "No 50 Hz, sorry. :("
 msgstr ""
 
+msgid "No Connection"
+msgstr ""
+
 msgid "No HDD found or HDD not initialized!"
 msgstr ""
 "لا يوجد قرص صلب\n"
@@ -2181,6 +2254,9 @@ msgstr ""
 msgid "No free tuner!"
 msgstr ""
 
+msgid "No networks found"
+msgstr ""
+
 msgid ""
 "No packages were upgraded yet. So you can check your network and try again."
 msgstr ""
@@ -2220,6 +2296,9 @@ msgid ""
 "When you say 'No' here the setup protection stay disabled!"
 msgstr ""
 
+msgid "No wireless networks found! Please refresh."
+msgstr ""
+
 msgid ""
 "No working local network adapter found.\n"
 "Please verify that you have attached a network cable and your network is "
@@ -2439,6 +2518,18 @@ msgid "Please choose the default services lists you want to install."
 msgstr ""
 
 msgid ""
+"Please configure or verify your Nameservers by filling out the required "
+"values.\n"
+"When you are ready press OK to continue."
+msgstr ""
+
+msgid ""
+"Please configure your internet connection by filling out the required "
+"values.\n"
+"When you are ready press OK to continue."
+msgstr ""
+
+msgid ""
 "Please disconnect all USB devices from your Dreambox and (re-)attach the "
 "target USB stick (minimum size is 64 MB) now!"
 msgstr ""
@@ -2520,6 +2611,19 @@ msgstr ""
 msgid "Please select the movie path..."
 msgstr ""
 
+msgid ""
+"Please select the network interface that you want to use for your internet "
+"connection.\n"
+"\n"
+"Please press OK to continue."
+msgstr ""
+
+msgid ""
+"Please select the wireless network that you want to connect to.\n"
+"\n"
+"Please press OK to continue."
+msgstr ""
+
 msgid "Please set up tuner B"
 msgstr "من فضلك أضبط التيونر ب"