openpyxl is a popular library to access Excel data via python.
However, there is an unexpected side effect if you have formulas in your Excel workbook.
I'm not the first to find that out the hard way - so here is another warning.
If you have a formula in your xlsx-spreadsheet like "=B1-A1" the spreadsheet app (Excel, LibreOffice etc.) stores the formula as well as the calculated result which you can see in the cell.
If the formula is stored e.g. in "C1", and you open the file in your python script like this:
import openpyxl
wb = openpyxl.load_workbook(filename="testwb.xlsx")
print(sheet["C1"].value)
# prints the formula
The result will be the formula, not the calculated value.
In order to access the calculated value, you have to open it with data_only set to True.
import openpyxl
wb = openpyxl.load_workbook(filename="testwb.xlsx", data_only=True)
print(sheet["C1"].value)
# prints the calculated value
The catch is that if you try to save the workbook later with for example
wb.save("testwb2.xlsx")
all formulas in the entire workbook are gone (if the workbook was loaded with data_only=True).
If you must have access to the results of the formulas that Excel has calculated, the work-around is to open two instances of the workbook: one with and one without data_only.
Make the one using data only also read_only, just in case
wb = openpyxl.load_workbook(filename="testwb.xlsx", data_only=False)
wb_dataonly = openpyxl.load_workbook(filename="testwb.xlsx", data_only=True, read_only=True)
This way you have access to the calculated values via wb_dataonly and you can add data and save the result using wb... and yes, you have to keep in mind that the two instances go out of sync as soon as you modify wb.
Posts mit dem Label Tutorial werden angezeigt. Alle Posts anzeigen
Posts mit dem Label Tutorial werden angezeigt. Alle Posts anzeigen
Sonntag, 23. März 2025
openpyxl - data_only beware
Freitag, 23. April 2010
dbus tutorial - part 1
Basic dbus concepts
What is dbus?
dbus is part of most modern Linux distros. It handles interprocess communication, either between desktop applications or between systems daemons and applications (e.g. a desktop framework like Gnome or KDE, or user applications).
Overview
The goal of this series of postings is the creation of a small desktop example application written in Python which reads the name of the files on a CD or DVD after the media has been inserted, and to store these names together with the CD label in a file. The graphical user interface will be based on wxWidgets.
The first part contains an introduction to the basic dbus components.
The second part discusses the implementation using the Hardware Abstraction Layer (HAL).
The following part shows the differences in implementation between HAL to the DeviceKit.Disks.
Prerequisites
Python: which is part of any current Linux distribution. (I'm using Python 2.6).
python-dbus: the dbus bindings for Python
python-wxgtk2.8: wxWidgets and its Python bindings (for the GUI)
Useful additions
python-wxglade: GUI builder for wxWidgets, creates Python source code (and C source code...)
d-feet: graphical display of dbus components
dbus components
In our example dbus is used to catch the notifications sent by the kernel when a CD or DVD has been inserted, as well as the notification when Gnome has mounted this medium. (There were times when you had to do this manually.)
In some places I will differ from the official dbus designations for these components to make their distinction easier. In some cases different components share the same name. This makes their close relation quite obvious, but it becomes difficult to determine if a given name refers to a connection or an interface, for example.
Buses
In dbus “buses” are at the root of a hierarchy. In normal applications you encounter mostly the following two buses:
bus = dbus.SessionBus()
for communication between desktop applications, and
bus = dbus.SystemBus()
for communication with system programs and daemons like the NetworkManager, the ModemManager, the Hardware Abstraction Layer daemon (HAL) or DeviceKit, to name but a few.
When you insert a disc, a notification is routed via HAL or DeviceKit, depending on which daemon is installed.
Note: Ubuntu Karmic uses HAL and DeviceKit simultaneously. However, the Hardware Abstraction Layer is being phased out from most Linux distributions, and the upcoming version of Ubuntu 10.04 (Lucid Lynx) will drop it completely.
Connections
“Connections” are the layer below the buses. You can use a "connection" to “connect” to a specific daemon or application. Please note the dotted notation:
The NetworkManager is available via a connection named org.freedesktop.NetworkManger.
The connection org.freedesktop.Hal will connect you to the HAL daemon.
The "disks" part of DeviceKit is available via the connection named org.freedesktop.DeviceKit.Disks.
Objects
These programs (NetworkManager, HAL, DeviceKit.Disks, etc.) will offer their services via one or more "objects". Object names contain slashes and look like file paths, which might be the reason that they are sometimes called "paths".
Examples:
/org/freedesktop/Hal/devices
/org/freedesktop/DeviceKit/Disks/devices/sr0
Interfaces
Objects export methods and and signals grouped into one or more "interfaces". The names of these interfaces again contain dots, e.g. org.freedesktop.Hal.Manager or org.freedesktop.DeviceKit.Disks.Device.
Methods
Methods are functions you can invoke. One method of the org.freedesktop.Hal.Manager interface for example is DeviceExists. The interface org.freedesktop.DeviceKit.Disks implements e.g. EnumerateDevices, etc.
Signals
An interface may also export "signals". Signals of the org.freedesktop.Hal.Manager interface that we are going to use are DeviceAdded and DeviceRemoved, which are triggered when you put a new CD into the drive or eject it, but also if any other device is added (an USB stick, a new network interface, etc.), as well as the signal PropertiesModified.
Introspect
One interface that is implemented by all objects is org.freedesktop.DBus.Introspectable which offers one method: Introspect().
This function returns a description of the object's interfaces, i.e. what methods and signals are available and what parameters they use. The above mentioned utility d-feet uses this method to display the information in a nice graphical way. (Note: In d-feet a "Connection" is called "Bus Name").
If you want to see the dbus messaging at work (for the SystemBus) open a shell and start:
dbus-monitor --system
Summary
Examples
How to call a method (HAL)
In order to call a method like DeviceExists, you have to know, that this particular function is
In Python:
# (4)
bus = dbus.SystemBus()
# (3 + 2)
object = bus.get_object("org.freedesktop.Hal","/org/freedesktop/Hal/Manager")
# (1)
interface = dbus.Interface(object,"org.freedesktop.Hal.Manager")
#
result = interface.DeviceExists(...)
As mentioned earlier, you have to know which parameter of bus.get_object and dbus.Interface is the object name, the connection name, and the interface name. The names themselves are usually not a great help.
Signal callbacks (HAL)
In order to make dbus call a method in your program when a signal is triggered you have to add a signal receiver:
bus.add_signal_receiver(
handler_name_in_your_program,
"signal_name",
"interface_name",
"connection_name",
"object_name")
The handler method looks like this:
def handler(...):
...
The parameters used when this handler is executed (the so called "signature") differ from signal to signal. (This info can be obtained via the Introspect interface.) Here the example for the methods DeviceAdded and DeviceRemoved:
bus = dbus.SystemBus()
bus.add_signal_receiver(device_added_callback,
"DeviceAdded",
"org.freedesktop.Hal.Manager",
"org.freedesktop.Hal",
"/org/freedesktop/Hal/Manager")
bus.add_signal_receiver(device_removed_callback,
"DeviceRemoved",
"org.freedesktop.Hal.Manager",
"org.freedesktop.Hal",
"/org/freedesktop/Hal/Manager")
....
def device_added_callback(udi):
print udi
def device_removed_callback(udi):
print udi
(More on add_signal_receiver in the next post)
How to call a function (DeviceKit.Disks)
The fundamental dbus principles described in the HAL example still apply:
# (4)
bus = dbus.SystemBus()
# (3 + 2)
devkit_object = bus.get_object("org.freedesktop.DeviceKit.Disks",
"/org/freedesktop/DeviceKit/Disks")
# (1)
devkit_disks = dbus.Interface(devkit_object, 'org.freedesktop.DeviceKit.Disks')
#
all_devices = devkit_disks.EnumerateDevices()
Note: This time the connection/object/interface names are nearly identical. Keep in mind which parameter describes what
Signal callbacks (DeviceKit.Disks)
Even tough a few handler names are identical to HAL and their functions are similar, their parameters are different. Also note that the way DeviceKit.Disks adds callbacks is different:
devkit_disks.connect_to_signal('DeviceAdded', device_added_callback)
devkit_disks.connect_to_signal('DeviceRemoved', device_removed_callback)
devkit_disks.connect_to_signal('DeviceChanged', device_changed_callback)
def device_added_callback(device):
# not really needed
print 'Device %s was added' % (device)
def device_removed_callback(device):
# not really needed
print 'Device %s was removed' % (device)
def device_changed_callback(device):
print 'Device %s was changed' % (device)
Other daemons
There are other interesting daemons, like the ModemManager, which not only can control modems, but also allows access to your mobile phone, SMS etc.
What is dbus?
dbus is part of most modern Linux distros. It handles interprocess communication, either between desktop applications or between systems daemons and applications (e.g. a desktop framework like Gnome or KDE, or user applications).
Overview
The goal of this series of postings is the creation of a small desktop example application written in Python which reads the name of the files on a CD or DVD after the media has been inserted, and to store these names together with the CD label in a file. The graphical user interface will be based on wxWidgets.
The first part contains an introduction to the basic dbus components.
The second part discusses the implementation using the Hardware Abstraction Layer (HAL).
The following part shows the differences in implementation between HAL to the DeviceKit.Disks.
Prerequisites
Python: which is part of any current Linux distribution. (I'm using Python 2.6).
python-dbus: the dbus bindings for Python
python-wxgtk2.8: wxWidgets and its Python bindings (for the GUI)
Useful additions
python-wxglade: GUI builder for wxWidgets, creates Python source code (and C source code...)
d-feet: graphical display of dbus components
dbus components
In our example dbus is used to catch the notifications sent by the kernel when a CD or DVD has been inserted, as well as the notification when Gnome has mounted this medium. (There were times when you had to do this manually.)
In some places I will differ from the official dbus designations for these components to make their distinction easier. In some cases different components share the same name. This makes their close relation quite obvious, but it becomes difficult to determine if a given name refers to a connection or an interface, for example.
Buses
In dbus “buses” are at the root of a hierarchy. In normal applications you encounter mostly the following two buses:
bus = dbus.SessionBus()
for communication between desktop applications, and
bus = dbus.SystemBus()
for communication with system programs and daemons like the NetworkManager, the ModemManager, the Hardware Abstraction Layer daemon (HAL) or DeviceKit, to name but a few.
When you insert a disc, a notification is routed via HAL or DeviceKit, depending on which daemon is installed.
Note: Ubuntu Karmic uses HAL and DeviceKit simultaneously. However, the Hardware Abstraction Layer is being phased out from most Linux distributions, and the upcoming version of Ubuntu 10.04 (Lucid Lynx) will drop it completely.
Connections
“Connections” are the layer below the buses. You can use a "connection" to “connect” to a specific daemon or application. Please note the dotted notation:
The NetworkManager is available via a connection named org.freedesktop.NetworkManger.
The connection org.freedesktop.Hal will connect you to the HAL daemon.
The "disks" part of DeviceKit is available via the connection named org.freedesktop.DeviceKit.Disks.
Objects
These programs (NetworkManager, HAL, DeviceKit.Disks, etc.) will offer their services via one or more "objects". Object names contain slashes and look like file paths, which might be the reason that they are sometimes called "paths".
Examples:
/org/freedesktop/Hal/devices
/org/freedesktop/Hal/Manager
/org/freedesktop/Hal/devices/volume_label_backupcd1________/org/freedesktop/DeviceKit/Disks/devices/sr0
Interfaces
Objects export methods and and signals grouped into one or more "interfaces". The names of these interfaces again contain dots, e.g. org.freedesktop.Hal.Manager or org.freedesktop.DeviceKit.Disks.Device.
Methods
Methods are functions you can invoke. One method of the org.freedesktop.Hal.Manager interface for example is DeviceExists. The interface org.freedesktop.DeviceKit.Disks implements e.g. EnumerateDevices, etc.
Signals
An interface may also export "signals". Signals of the org.freedesktop.Hal.Manager interface that we are going to use are DeviceAdded and DeviceRemoved, which are triggered when you put a new CD into the drive or eject it, but also if any other device is added (an USB stick, a new network interface, etc.), as well as the signal PropertiesModified.
Introspect
One interface that is implemented by all objects is org.freedesktop.DBus.Introspectable which offers one method: Introspect().
This function returns a description of the object's interfaces, i.e. what methods and signals are available and what parameters they use. The above mentioned utility d-feet uses this method to display the information in a nice graphical way. (Note: In d-feet a "Connection" is called "Bus Name").
If you want to see the dbus messaging at work (for the SystemBus) open a shell and start:
dbus-monitor --system
Summary
- bus: top level (SessionBus or SystemBus)
- connection: from the bus to a daemon; names with dots
- object: logical part within that daemon; names with slashes
- interface: one or more within an object (same interface on different objects means same API (methods and signals)); names with dots
- methods and signals (none or more within an object)
Examples
How to call a method (HAL)
In order to call a method like DeviceExists, you have to know, that this particular function is
- part of the interface org.freedesktop.Hal.Manager
- that this interface is implemented by the object named /org/freedesktop/Hal/Manager
- which in turn can be reached via the connection org.freedesktop.Hal
- on the SystemBus
In Python:
# (4)
bus = dbus.SystemBus()
# (3 + 2)
object = bus.get_object("org.freedesktop.Hal","/org/freedesktop/Hal/Manager")
# (1)
interface = dbus.Interface(object,"org.freedesktop.Hal.Manager")
#
result = interface.DeviceExists(...)
As mentioned earlier, you have to know which parameter of bus.get_object and dbus.Interface is the object name, the connection name, and the interface name. The names themselves are usually not a great help.
Signal callbacks (HAL)
In order to make dbus call a method in your program when a signal is triggered you have to add a signal receiver:
bus.add_signal_receiver(
handler_name_in_your_program,
"signal_name",
"interface_name",
"connection_name",
"object_name")
The handler method looks like this:
def handler(...):
...
The parameters used when this handler is executed (the so called "signature") differ from signal to signal. (This info can be obtained via the Introspect interface.) Here the example for the methods DeviceAdded and DeviceRemoved:
bus = dbus.SystemBus()
bus.add_signal_receiver(device_added_callback,
"DeviceAdded",
"org.freedesktop.Hal.Manager",
"org.freedesktop.Hal",
"/org/freedesktop/Hal/Manager")
bus.add_signal_receiver(device_removed_callback,
"DeviceRemoved",
"org.freedesktop.Hal.Manager",
"org.freedesktop.Hal",
"/org/freedesktop/Hal/Manager")
....
def device_added_callback(udi):
print udi
def device_removed_callback(udi):
print udi
(More on add_signal_receiver in the next post)
How to call a function (DeviceKit.Disks)
The fundamental dbus principles described in the HAL example still apply:
# (4)
bus = dbus.SystemBus()
# (3 + 2)
devkit_object = bus.get_object("org.freedesktop.DeviceKit.Disks",
"/org/freedesktop/DeviceKit/Disks")
# (1)
devkit_disks = dbus.Interface(devkit_object, 'org.freedesktop.DeviceKit.Disks')
#
all_devices = devkit_disks.EnumerateDevices()
Note: This time the connection/object/interface names are nearly identical. Keep in mind which parameter describes what
Signal callbacks (DeviceKit.Disks)
Even tough a few handler names are identical to HAL and their functions are similar, their parameters are different. Also note that the way DeviceKit.Disks adds callbacks is different:
devkit_disks.connect_to_signal('DeviceAdded', device_added_callback)
devkit_disks.connect_to_signal('DeviceRemoved', device_removed_callback)
devkit_disks.connect_to_signal('DeviceChanged', device_changed_callback)
def device_added_callback(device):
# not really needed
print 'Device %s was added' % (device)
def device_removed_callback(device):
# not really needed
print 'Device %s was removed' % (device)
def device_changed_callback(device):
print 'Device %s was changed' % (device)
Other daemons
There are other interesting daemons, like the ModemManager, which not only can control modems, but also allows access to your mobile phone, SMS etc.
Freitag, 25. Dezember 2009
Changing USB device permissions in Ubuntu Karmic
If you plug an USB device into a Linux box that uses a current distro, udev dynamically creates an entry in the /dev directory. You can list all currently available USB units with the lsusb command:
The only "real" device here is my XAiOX GPS logger (first entry). The output shows that it has the vendor id (hex) 03eb, the product id (hex) 6125.
The device file created by udev is: /dev/bus/usb/002/003
(Yes, these are the bus and device numbers shown in the lsusb output).
The default permissions are rather restrictive:
Only root can read and write to the USB device. Anybody else only has read access.
In order to retrieve the stored GPS info from my GPS logger (e.g. by using itrackutil), I have to instruct the device to send the data. In order to send this command I need the write privileges.
I could start itrackutil as root, but from a security standpoint that is not what I want.
This problem usually arises only, if the USB device is not (yet) managed by the system, because part of that managing process is... changing the permissions.
The solution I'm suggesting here works with Ubuntu Karmic.
The first step is to create a group named usbusers (or any other name), then make yourself member of that group and instruct udev to set the device group id to usbusers and set the permissions accordingly.
On the command line, creating a group and adding the user (e.g. mike) is quite simple:
If you pefer the Gnome GUI, you find the appropriate program under "System - Administration - User and groups":
After unlocking the panel ("Click to make changes"), click onto "Manage Groups".
"Add Group".
Make enter "usbusers" as group name, make sure that the group id suggested by the system is not zero. It's usually in the 1000+ range, enable the "Group Members" and click "Ok".
As a last step you have to create a new udev rule:
Save it under the following name: /etc/udev/rules.d/45-xaiox.rules
Then reboot.
Two remarks regarding the filename:
And being a member of usbusers, you have read and write access.
$ lsusb
Bus 002 Device 003: ID 03eb:6125 Atmel Corp.
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
The only "real" device here is my XAiOX GPS logger (first entry). The output shows that it has the vendor id (hex) 03eb, the product id (hex) 6125.
The device file created by udev is: /dev/bus/usb/002/003
(Yes, these are the bus and device numbers shown in the lsusb output).
The default permissions are rather restrictive:
$ ls -l /dev/bus/usb/002
insgesamt 0
crw-rw-r-- 1 root root 189, 128 2009-12-23 22:14 001
crw-rw-r-- 1 root root 189, 128 2009-12-23 22:19 003
Only root can read and write to the USB device. Anybody else only has read access.
In order to retrieve the stored GPS info from my GPS logger (e.g. by using itrackutil), I have to instruct the device to send the data. In order to send this command I need the write privileges.
I could start itrackutil as root, but from a security standpoint that is not what I want.
This problem usually arises only, if the USB device is not (yet) managed by the system, because part of that managing process is... changing the permissions.
The solution I'm suggesting here works with Ubuntu Karmic.
The first step is to create a group named usbusers (or any other name), then make yourself member of that group and instruct udev to set the device group id to usbusers and set the permissions accordingly.
On the command line, creating a group and adding the user (e.g. mike) is quite simple:
sudo groupadd usbusers
sudo adduser mike usbusers
If you pefer the Gnome GUI, you find the appropriate program under "System - Administration - User and groups":
After unlocking the panel ("Click to make changes"), click onto "Manage Groups".
"Add Group".
Make enter "usbusers" as group name, make sure that the group id suggested by the system is not zero. It's usually in the 1000+ range, enable the "Group Members" and click "Ok".
As a last step you have to create a new udev rule:
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", MODE="0664", GROUP="usbusers"
Save it under the following name: /etc/udev/rules.d/45-xaiox.rules
Then reboot.
Two remarks regarding the filename:
- in order to be executed, the filename must end with .rules (all other files are ignored)
- the 45 ensures that the file is executed before the corresponding "old" rule found in /lib/udev/rules.d/50-udev-default.rules
$ ls -l /dev/bus/usb/002/total 0crw-rw-r-- 1 root usbusers 189, 128 2009-12-25 20:20 001crw-rw-r-- 1 root usbusers 189, 133 2009-12-25 22:22 006
And being a member of usbusers, you have read and write access.
Dienstag, 1. Dezember 2009
Bisecting mesa - bug 446632

Bug 446632 is responsible for the segfaulting blender on start-up on machines with ATI graphics cards running Ubuntu Karmic.
Analysis showed that the segfault originated in the mesa library. The code of the mesa contains the OpenGL implementation under Linux, and is used by Blender and various other programs.
During the pre-release process of Karmic, various builds of the mesa package have been made and are still available online. Tests showed that the last build without the bug was 7.6.0~git20090817.7c422387-0ubuntu8. The next one was 7.6.0-1ubuntu1.
To determine which patch between those two releases is responsible for the bug, a process called git-bisecting is used. For this, you give git the id of a version with and without the bug. Git chooses a version in the middle. You check it out, compile it and test it. After that you tell git if this version was good or bad. After that git chooses another version halfway between the last good and the first bad one. This process is repeated until you find the bad commit.
Sounds simple enough.... but it raises the following questions:
- What Git repository does Ubuntu use for the mesa package?
- Which commits correspond to the above mentioned builds?
- And once you have the source, how do you compile, package and use it?
7c422387 is the commit id within the freedesktop repository (well, not quite. The real commit ID is 7c4223876b4f8a78335687c7fcd7448b5a83ad10, but the first few digits are usually sufficient to find it).
The last commit of the 7.6.0 branch in this repository has the label mesa_7_6
The way to compile the source is described later in this post. As you will see, packaging is not necessary. The compiled drivers can be used directly.
"Git"ting started
You need git-core - and also download gitk (which is not really necessary, but makes a nice graphical representation).
sudo apt-get install git-core gitkchoose a directory and download the entire repository (in this tutorial I use my home directory).
cd ~
git clone git://anongit.freedesktop.org/mesa/mesa
This will create the subdirectory mesa, and a subdirectory .git, that contains the content of the cloned repository.
Be patient. After counting the elements to be transferred it takes some time before the actual download begins. All in all around 100 MB.
The code that we are going to compile needs some additional source files:
sudo apt-get build-dep mesa
sudo apt-get install libx11-dev libxt-dev libxmu-dev libxi-dev
Further preparations
make cleanmake clean removes the "debris" from previous compilations. But we haven't created any yet... Do it anyway - it's good practice :-)
./autogen.sh
./configure --prefix=/usr --mandir=\${prefix}/share/man \
--infodir=\${prefix}/share/info --sysconfdir=/etc \
--localstatedir=/var --build=i486-linux-gnu --disable-gallium --with-driver=dri \
--with-dri-drivers="r200 r300 radeon" --with-demos=xdemos --libdir=/usr/lib/glx \
--with-dri-driverdir=/usr/lib/dri --enable-glx-tls --enable-driglx-direct --disable-egl \
--disable-glu --disable-glut --disable-glw CFLAGS="-Wall -g -O2"
./autogen.sh verifies that all prerequisites are met. If anything is missing, it will complain.
./configure sets up what is compiled, where and how.
During the tests remove -O2 (under CFLAGS). This disables compiler optimisations. The resulting code is a bit larger and a little bit slower, but it is easier to use during debugging.
--with-dri-drivers="..." determines which drivers are compiled. As the original bug only affects ATI machines, we only need the drivers we use. That saves a lot of compile time. If yours is not among them, check out ~/mesa/src/mesa/drivers/dri/ and add it.
You can find out which driver you are using with:
xdriinfo driver 0
Verify the good build
We know that build 7c4223876b4f8a78335687c7fcd7448b5a83ad10 still works with Blender. So let's check it out, compile it and test it. If Blender does not crash, we know that the process so far is working correctly.
git checkout 7c422387
make
We could enter the entire ID, but the first few digits are usually sufficient.
make should finish without errors. Now we start Blender using:
LD_LIBRARY_PATH="~/mesa/glx" LIBGL_DRIVERS_PATH="~/mesa/src/mesa/drivers/dri/radeon" Blender
LD_LIBRARY_PATH and LIBGL_DRIVERS_PATH make Blender (and only Blender, or any other program you specify) use the just compiled libraries. No need to reboot or to restart X. No effects to the remaining programs.
Please note, that you may need to replace the radeon part of the driver path with r200 or r300 depending on the driver you use.
Blender should run correctly.
Bisecting
We now officially start the bisecting process:
git bisect start... and tell git that this was a "good" build.
git bisect good
Checking out the bad build
As we can not pinpoint which git version corresponds to first bad Ubuntu build (7.6.0-1ubuntu1) we simply start at the newest commit in the mesa_7_6 branch:
git checkout mesa_7_6
This replaces the files in the mesa directories and its subdirectories (except .git) with the new ones.
We compile it:
makeand test it:
LD_LIBRARY_PATH="~/mesa/glx" LIBGL_DRIVERS_PATH="~/mesa/src/mesa/drivers/dri/radeon" Blender
This time Blender should crash. We notify git:
git bisect bad
With this command, git chooses a commit approx. in the middle:
Bisecting: 482 revisions left to test after this (roughly 9 steps)
[ee066eaf6d0dd3c771dc3e37390f3665e747af2a] llvmpipe: Allow to dump the disassembly byte code.
The make, test, bisect process is repeated until git displays the first bad commit.
bfbad4fbb7420d3b5e8761c08d197574bfcd44b2 is first bad commit
commit bfbad4fbb7420d3b5e8761c08d197574bfcd44b2
Author: Pauli Nieminen
Date: Fri Aug 28 04:58:50 2009 +0300
r100/r200: Share PolygonStripple code.
:040000 040000 1b1f09ef26e217307a5768bb9806072dc50f2a14 eb20bf89c37b2f59ce2c243b361587918d3c9021 M src
As an interesting side note, the driver from this commit does crash Blender, but not with a segfault. There is even an output on the console: "drmRadeonCmdBuffer: -22".
The next commit in this branch 4322181e6a07ecb8891c2d1ada74fd48c996a8fc makes Blender crash the way we have come to know.
The previous commit (e541845959761e9f47d14ade6b58a32db04ef7e4) would be a good candidate to keep Blender running until mesa is fixed:
git checkout e541845959761e9f47d14ade6b58a32db04ef7e4
make
LD_LIBRARY_PATH="~/mesa/glx" LIBGL_DRIVERS_PATH="~/mesa/src/mesa/drivers/dri/radeon" Blender
Ackowledgements
Tormod Volden for creating and updating https:/
References
https://bugs.launchpad.net/ubuntu/+source/mesa/+bug/446632
http://bugs.freedesktop.org/show_bug.cgi?id=25354
https://wiki.ubuntu.com/X/Bisecting
https://wiki.ubuntu.com/X/BisectingMesa
https://launchpad.net/~xorg-edgers/+archive/ppa
http://www.kernel.org/pub/software/scm/git/docs/user-manual.html
http://cgit.freedesktop.org/mesa/mesa
Montag, 14. September 2009
Der lange Marsch nach Huawei

Das UMTS-Modem
Zurzeit gibt es bei Aldi-Süd den „Internet-USB-Stick S4011“ für knapp 60 €.
Die von lsusb ausgegebene USB-ID sowie die „Selbstauskunft“ des Sticks zeigen aber, dass es sich um ein Huawei E160 handelt, wie sie im Augenblick zu Tausenden in Startersets von diversen Mobilfunkanbietern unter die Leute gebracht werden.
Unter der Glasabdeckung des Lebensmitteldiscounters war jedoch die Rückseite nicht zu erkennen, die auf das hauseigene Starterset hinweist. Ganz unten findet sich dann aber dann der Hinweis, dass dieses Starterset nicht im Lieferumfang enthalten ist.
Und in der Tat hat dieser Stick, im Gegensatz zu vielen anderen (teilweise teureren) „Startersets“, keinen Sim-Lock und ist hier schon mit den SIM-Karten der unterschiedlichsten Mobilfunkanbieter gelaufen.
Eine kurze Recherche zeigte, dass der Stick vom (noch) aktuellen Ubuntu Jaunty unterstützt wird, und in der Tat läuft er mit dem Network-Manager ohne Probleme.
Der Datentarif
Ohne SIM-Karte läuft aber auch dieses Modem nicht. Da der Stick nur gelegentlich eingesetzt werden soll, fiel die Wahl - nach einiger Suche - auf die Prepaid-Karte von Fonic.
Auch dort gibt es ein Starterset – 69,95 € mit 5 Tagen freies Surfen. Der Stick, ein – wer hätte es gedacht – Huawai E160, hat jedoch, nach Auskunft der Hotline, einen Simlock.
Da ich ja nun bereits ein simlock-freies E160 habe war die Alternative die normale SIM-Karte von Fonic (mit 111 Freiminuten). Da die Freiminuten bzw. die „Frei-Tage“ als Guthaben auf das Prepaid-Konto gutgeschrieben werden besteht zwischen den Angeboten kein großer Unterschied.
Der normale Datentarif kostet zurzeit 0,24 €/MB und kann von der Hotline vom Volumentarif auf die Tagesflatrate zu 2,50 € umgestellt werden. Bei der Flatrate wird nach 1 GB am Tag die Geschwindigkeit gedrosselt.
UMTSmon
Wie bereits erwähnt läuft der Stick unter Network-Manager ohne Probleme. Bei meiner Recherche bin ich aber auf das Programm UMTSmon gestoßen.
UMTSmon gab es schon bevor die Funktion in den Network-Manager integriert wurde. Es hat ein paar nützlich Zusatzfunktionen, wie das Anzeigen der Empfangsfeldstärke, SMS-Versand und das Nachhalten der verbrauchten Zeit und des verbrauchten Datenvolumens.
UMTSmon ist leider nicht in den Ubuntu-Repositories verfügbar. Ein i386 Binary ist jedoch im Download-Bereich des Projekts zu finden.
usb_modeswitch
UMTSmon verlangt nach einem weiteren Progamm: usb_modeswitch. Das Programm ist auf der Seite des Autors erhältlich. Das Debian-Projekt hält es als .deb-Paket vor. Bei neueren Kernels ist usb_modeswitch eigentlich nicht mehr notwendig, da der Kernel diese Funktion übernimmt.
Die Huawai-Sticks melden sich nämlich zunächst als USB-Massenspeicher an. Dieser Massenspeicher enthält Software und Treiber, die unter Windows per Autorun gestartet und installiert werden. Diese Treiber schalten dann den Stick in den „Modem-Modus“ um. Unter Linux übernimmt diese Funktion usb_modeswitch, und seit einiger Zeit der Kernel. Diese Technik ist auch als ZeroCD bekannt.
… und die Problemchen
Beim ersten Aufruf prüft UMTSmon diverse Abhängigkeiten. Zunächst bemängelte es das fehlende SUID-Bit bei usb_modeswitch. usb_modeswitch braucht für seine Aufgabe Root-Rechte. Diese waren schnell nachgetragen mit:
sudo chmod u+s /usr/sbin/usb_modeswitch
Das nächste Problem bestand darin, dass sich das Modem in kein Netz einwählen konnte. Der Network Operator Wizard (Verbindung – Netzbetreiber auswählen) zeigte zwar diverse Netze an, nur ansprechen konnte ich sie nicht. Dieses Problem löste sich aber mit der Zeit von selbst. Man sollte bei neuen SIM-Karten warten bis sie freigeschaltet sind... :-)
Nach der Freischaltung fand das Modem auch das von Fonic verwendete O2-Netz.

Danach habe ich eine neues Profil für Fonic angelegt (Verbindung – Profile bearbeiten – Add Profile). Als APN (Zugangspunkt) habe ich die im Netz angegebene Adresse „pinternet.interkom.de“ verwendet (ohne Gewähr). Ansonsten habe ich die Standardeinstellungen belassen.
pppd
Der Versuch, sich mit dem Internet zu verbinden (2. Icon von links - „Connect to default profile“), scheiterte mit der Fehlermeldung:

und den vielsagenden Erklärungen:
- << ppp did not provide any stdout information >> und
- << ppp did not provide any stderr information >>
Leider brachte mich der gutgemeinte Hinweis auf die Kommandozeilen-Option -v4 nicht viel weiter. Sie bewirkt, dass UMTSmon Debug-Informationen ausgibt. Unter anderem sieht man die Kommunikation mit dem Modem.
Zum Einbinden des Internets ruft UMTSmon den pppd Daemon auf. Sehen wir uns die Datei pppd mal genauer an:
$ ls -l /usr/sbin/pppd
-rwsr-xr-- 1 root dip 277352 2009-02-20 18:25 /usr/sbin/pppd
Das Programm kann nur von root oder einem Mitglied der Gruppe dip gestartet werden – und das bin ich „normalerweise“ nicht. Der Grund, weshalb UMTSmon keine Informationen von ppp erhält ist, dass das pppd mangels fehlender Rechte nicht gestartet wurde.
Wo ist dip?
Natürlich könnte man UMTSmon einfach mit root-Rechten aufrufen, aber das gehört sich nicht. Die einfachste Variante zum Mitglied der Gruppe dip zu werden ist der Befehl:
sudo adduser user_name dip
Der Versuch dies über die GUI (System – Systemverwaltung – Benutzer und Gruppen) zu erledigen läuft zunächst ins Leere. Ruft man nach dem „Entsperren“ den Punkt „Gruppen verwalten“ auf, so sucht man dort die Gruppe dip vergebens. Diese Gruppe versteckt sich bei den Benutzerrechten.
Also: Benutzer anklicken – Eigenschaften – Benutzerrechte – „Internet-Verbindung mit Modem aufbauen“ ankreuzen.
Eigentlich logisch – aber das muss man wirklich erst einmal wissen. Die Option „Modems verwenden“ muss ebenfalls aktiv sein, was sie jedoch standardmäßig ist. Sie macht einem zum Mitglied der Gruppe dialout.
Dann muss man sich erst einmal ab- und wieder anmelden, bevor diese neue Einstellung aktiv ist. Ein Neustart ist jedoch nicht nötig.
Ein neuer Versuch
Der nächste Versuch, ins Internet zu kommen, scheiterte auch. Diesmal war die Fehlermeldung (stdout) etwas umfangreicher. Hier ein gekürzter Ausschnitt:
pppd options in effect:
debug debug debug # (from command line)
...
/dev/ttyUSB1 # (from command line)
460800 # (from command line)
lock # (from command line)
crtscts # (from command line)
...
Using interface ppp0
Connect: ppp0 <--> /dev/ttyUSB1
...
LCP: timeout sending Config-Requests
Connection terminated.
Receive serial link is not 8-bit clean:
Problem: all had bit 7 set to 0
Modem hangup
Im Rahmen der Fehlersuche hatte ich mit dmesg das Boot-Protokoll abgefragt. Dort findet man u.a.:
[ 11.424602] USB Serial support registered for GSM modem (1-port)
[ 11.424737] option 2-2:1.0: GSM modem (1-port) converter detected
[ 11.425007] usb 2-2: GSM modem (1-port) converter now attached to ttyUSB0
[ 11.425071] option 2-2:1.1: GSM modem (1-port) converter detected
[ 11.425322] usb 2-2: GSM modem (1-port) converter now attached to ttyUSB1
[ 11.425405] usbcore: registered new interface driver option
[ 11.425452] option: v0.7.2:USB Driver for GSM modems
Hier ist zu erkennen, dass der Kernel für das Modem zwei serielle Devices einrichtet: /dev/ttyUSB0 und /dev/ttyUSB1
Startet man umtsmon mit den Optionen -v4 und --force-autodetect kann man schön verfolgen, wie
- zunächst das Modem als solches erkannt wird
- die beiden seriellen Devices gefunden und
- nacheinander getestet werden (ein Modem antwortet auf „AT“ mit „OK“)
- und dann sowohl für die AT-Befehle als auch für die PPP-Verbindung /dev/ttyUSB1 ausgewählt wird.
Hier die interessanten Ausgaben:
##P3 t=372: Start iterating through all AutoDetectors
…
##P3 t=372: Let's continue with the next AutoDetector
##P3 t=372: AutoDetectBase::go() for 'USB ZeroCD Autodetection'
##P3 t=372: AutoDetect_USB::traverseTrees()
##P4 t=372: Checking USB device on 001:006
##P3 t=372: AutoDetect_USB::matchIDs(0x12d1, 0x1003)
##P3 t=372: This is a known ZeroCD Device: "Huawei E220 / E800"
##P3 t=372: AutoDetect_USB_ZeroCD::findPortNames()
##P3 t=372: AutoDetect_USB::findPortNames()
##P4 t=372: looking for ttyUSB ports
##P4 t=372: Found serial port number 1 with name 'ttyUSB0'
##P4 t=372: Found serial port number 2 with name 'ttyUSB1'
##P3 t=372: INFO: 'There are 2 ports available'
…
##P3 t=372: AutoDetect_USB::traverseTrees()
##P4 t=372: Checking USB device on 001:006
##P3 t=372: AutoDetect_USB::matchIDs(0x12d1, 0x1003)
##P2 t=372: GOOD: 'A 'Huawei E220 / E800' modem detected'
##P3 t=372: AutoDetect_USB::findPortNames()
##P4 t=372: looking for ttyUSB ports
##P4 t=372: Found serial port number 1 with name 'ttyUSB0'
##P4 t=372: Found serial port number 2 with name 'ttyUSB1'
##P3 t=372: INFO: 'There are 2 ports available'
...
##P3 t=372: Device: probing port '/dev/ttyUSB0' for AT commands
##P3 t=372: TempSerialPort::TempSerialPort()
##P3 t=372: Serial::openDev('/dev/ttyUSB0') as FD 7 - Serial instance 0xbfa4eec0
##P4 t=372: Query sends the following mesage: 'AT'
##P2 t=372: Device port '/dev/ttyUSB0': no response to "AT", return code 5
##P3 t=372: Device: probing port '/dev/ttyUSB0' failed
##P3 t=372: TempSerialPort::~TempSerialPort()
##P3 t=372: SerialPort::closeDev() for FD 7
##P3 t=372: Device: probing port '/dev/ttyUSB1' for AT commands
##P3 t=372: TempSerialPort::TempSerialPort()
##P3 t=372: Serial::openDev('/dev/ttyUSB1') as FD 7 - Serial instance 0xbfa4eec0
##P4 t=372: Query sends the following mesage: 'AT'
##P4 t=372: answer 1:'AT'
##P4 t=372: answer 2:'OK'
##P3 t=372: Got Query::OK from port
##P3 t=372: Device: probing port '/dev/ttyUSB1' successful
…
##P3 t=372: TempSerialPort::~TempSerialPort()
##P3 t=372: SerialPort::closeDev() for FD 7
##P3 t=372: set AT serial to '/dev/ttyUSB1'
##P3 t=372: set PPP serial to '/dev/ttyUSB1'
##P3 t=373: Serial::openDev('/dev/ttyUSB1') as FD 7 - Serial instance 0x9ff3b70
##P2 t=373: GOOD: 'Device created successfully'
##P1 t=373: Found hardware configuration stored to disk
##P3 t=373: TheDeviceManagerSingleton::writeToConfigFile()
##P3 t=373: Everything done - device created
Könnte es also sein, dass man für die PPP-Verbindung /dev/ttyUSB0 statt 1 verwenden sollte? Die entsprechende Option beim Aufruf lautet:
umtsmon -s/dev/ttyUSB1,/dev/ttyUSB0
Und siehe da... Internet!
Damit man dies nicht andauernd eingeben muss, kann man es auch in der Konfiguration von UMTSmon dauerhaft ändern (zu finden unter ~/.umtsmon/umtsmonrc):
[device]
ATPortName=/dev/ttyUSB1
PPPPortName=/dev/ttyUSB0
Happy surfing.
Mittwoch, 29. Juli 2009
Linux, Python und die MS-Access-Datenbank
Hier lag sie nun - ein Überbleibsel aus einer anderen Zeit und Welt. Eine Bilderdatenbank, die ich vor Jahren unter Windows mit dem bekannten Programm "Daumen Plus" erstellt hatte und deren Daten ich nun gerne nutzen wollte. Das Problem war das Format: MS-Access
Dieses Format ist unter Linux nicht gerade gängig, der Zugriff ist aber - wenn auch nicht "out of the box" - durchaus möglich.
Die hier beschriebenen Schritte beziehen sich auf eine Standardinstallation von Ubuntu Jaunty - sie dürften sich aber so oder ähnlich auch auf anderen Systemen nachvollziehen lassen.
Der Treiber
Der eigentliche Treiber findet man im Paket libmdbodbc. Wie der Name schon andeutet, läuft der Treiber im ODBC-Framework.
Die Schnittstelle ODBC
ODBC ist eine standardisierte Schnittstelle, in der auf der einen Seite Treiber wie Plugins die Verbindung zu den verschiedenen Datenbankentypen herstellen, und die auf der anderen Seite von Programmen - unabhängig vom Typ der Datenbank - immer in der gleichen Weise angesprochen werden können.
ODBC ist in Jaunty nicht standardmäßig installiert. Man braucht das Paket unixodbc. Zusätzlich sollte man noch unixodbc-dev holen, das wir weiter unten brauchen.
Zunächst muss man ODBC über das Vorhandensein des Treibers informieren. Die Treiber werden in Form sog. Templates eingerichtet. Hier das Template für MS Access.
[MDB]
Description = Microsoft Access ODBC Driver
Driver = /usr/lib/libmdbodbc.so.0
Setup =
FileUsage = 1
CPTimeout =
CPReuse =
UsageCount = 1
Es besagt, dass der Treiber libmdbodbc.so.0 nun im ODBC-Framework unter dem Namen frei gewählten Namen MDB angesprochen werden kann.
Speichern Sie dieses Template (z.B. unter derm Namen msaccess.template) und installieren Sie es mit dem folgenden Befehl:
odbcinst -i -d -f msaccess.template
Das Template wird in der Datei /etc/odbcinst.ini abgelegt. Diese Datei im INI-Format könnte man natürlich auch von Hand editieren.
Die Datenquelle
Eine Datenquelle fasst mehrere Parameter unter einem Namen (Data Source Name, DSN) zusammen. Diese Parameter könnten zwar auch beim Aufruf der Datenbank angegeben werden, aber der Parameterstring wird schnell sehr lang und seine Länge ist begrenzt.
Unter einem DSN werden in diesem Beispiel der verwendete Treiber, der Server und der Pfad zur Datenbank hinterlegt. Weitere Angaben sind je nach verwendetem Treiber möglich.
Das Verfahren ähnelt dem Einrichten des Treibers. Hier ein Beispiel:
[bilderdb]
Description = Bilder-Datenbank
Driver = MDB
Database = /home/mike/fotos.mdb
Servername = localhost
UserName =
Password =
Port = 5432
Abgespeichert in einer Textdatei mit dem Namen bilder.template, erfolgt die Installation entweder systemweit mit
odbcinst -i -s -l -f bilder.template
oder benutzerspezifisch mit
odbcinst -i -s -f bilder.template
Gespeichert wird diese Information in der INI-Datei /etc/odbc.ini (systemweit) bzw. ~/.odbc.ini (benutzerspezifisch).
Zugriff via Python
Zum Zugriff braucht man das Paket pyodbc. Das wiederum gibt es leider zurzeit nicht in einem Ubuntu-Paket. Man muss es - wie früher - aus dem Quellcode kompilieren. Hierzu braucht man zum einen den Sourcecode von pyodbc sowie die oben erwähnte Datei unixodbc-dev.
Wer das erste Mal selbst kompiliert, installiert noch build-essential, letzteres ist wieder bequem über apt-get oder Synaptic aus den Ubuntu-Archiven verfügbar.
Das pyodbc-Archiv muss entpackt werden. Danach begibt man sich in das beim Auspacken angelegte Verzeichnis und gibt
sudo python setup.py build install
ein. Das war es schon.
Kurze Zusammenfassung:
Aus den Ubuntu-Repositories braucht man:
build-essential, unixodbc-dev, unix-odbc und libmdbodbc.
Aus dem Web:
pyodbc
Und los geht's
Jedem, der in Python mit Datenbanken zu tun hatte, sollten diese Zeilen bekannt vorkommen.
Die bei connect verwendete Zeichenkette, die in diesem Beispiel nur auf eine Datenquelle (DSN) verweist, kann viele andere Parameter aufnehmen, z.B. Username und Passwort bei einer passwortgeschützten Datenbank:
con = pyodbc.connect("DSN=bilderdb;UID=name;PWD=passwort")
Die einzelnen Parameter werden, durch Semikolon getrennt, in der Form Attribut=Wert aneinandergereiht. Die Namen der Attribute hängen vom verwendeten Treiber ab und sind recht vielfältig.
Zum Schluss noch ein paar nützliche Tipps beim Erkunden einer MS-Access-Datenbank:
Liste der Tabellen in einer Datenbank
Die Zeilen haben den Aufbau (Werte: String oder None):
table_cat
table_schem
table_name Name der Tabelle
table_type SYSTEM TABLE, VIEW, TABLE
Die eigentlichen Tabellen werden unter dem Typ TABLE aufgelistet.
Aufbau einer Tabelle
Dieser lässt sich mit dem normalen SQL-Befehl erfragen:
Das Ergebnis wird in der Form (Name, Type, Größe) zurückgegeben.
Dieses Format ist unter Linux nicht gerade gängig, der Zugriff ist aber - wenn auch nicht "out of the box" - durchaus möglich.
Die hier beschriebenen Schritte beziehen sich auf eine Standardinstallation von Ubuntu Jaunty - sie dürften sich aber so oder ähnlich auch auf anderen Systemen nachvollziehen lassen.
Der Treiber
Der eigentliche Treiber findet man im Paket libmdbodbc. Wie der Name schon andeutet, läuft der Treiber im ODBC-Framework.
Die Schnittstelle ODBC
ODBC ist eine standardisierte Schnittstelle, in der auf der einen Seite Treiber wie Plugins die Verbindung zu den verschiedenen Datenbankentypen herstellen, und die auf der anderen Seite von Programmen - unabhängig vom Typ der Datenbank - immer in der gleichen Weise angesprochen werden können.
ODBC ist in Jaunty nicht standardmäßig installiert. Man braucht das Paket unixodbc. Zusätzlich sollte man noch unixodbc-dev holen, das wir weiter unten brauchen.
Zunächst muss man ODBC über das Vorhandensein des Treibers informieren. Die Treiber werden in Form sog. Templates eingerichtet. Hier das Template für MS Access.
[MDB]
Description = Microsoft Access ODBC Driver
Driver = /usr/lib/libmdbodbc.so.0
Setup =
FileUsage = 1
CPTimeout =
CPReuse =
UsageCount = 1
Es besagt, dass der Treiber libmdbodbc.so.0 nun im ODBC-Framework unter dem Namen frei gewählten Namen MDB angesprochen werden kann.
Speichern Sie dieses Template (z.B. unter derm Namen msaccess.template) und installieren Sie es mit dem folgenden Befehl:
odbcinst -i -d -f msaccess.template
Das Template wird in der Datei /etc/odbcinst.ini abgelegt. Diese Datei im INI-Format könnte man natürlich auch von Hand editieren.
Die Datenquelle
Eine Datenquelle fasst mehrere Parameter unter einem Namen (Data Source Name, DSN) zusammen. Diese Parameter könnten zwar auch beim Aufruf der Datenbank angegeben werden, aber der Parameterstring wird schnell sehr lang und seine Länge ist begrenzt.
Unter einem DSN werden in diesem Beispiel der verwendete Treiber, der Server und der Pfad zur Datenbank hinterlegt. Weitere Angaben sind je nach verwendetem Treiber möglich.
Das Verfahren ähnelt dem Einrichten des Treibers. Hier ein Beispiel:
[bilderdb]
Description = Bilder-Datenbank
Driver = MDB
Database = /home/mike/fotos.mdb
Servername = localhost
UserName =
Password =
Port = 5432
Abgespeichert in einer Textdatei mit dem Namen bilder.template, erfolgt die Installation entweder systemweit mit
odbcinst -i -s -l -f bilder.template
oder benutzerspezifisch mit
odbcinst -i -s -f bilder.template
Gespeichert wird diese Information in der INI-Datei /etc/odbc.ini (systemweit) bzw. ~/.odbc.ini (benutzerspezifisch).
Zugriff via Python
Zum Zugriff braucht man das Paket pyodbc. Das wiederum gibt es leider zurzeit nicht in einem Ubuntu-Paket. Man muss es - wie früher - aus dem Quellcode kompilieren. Hierzu braucht man zum einen den Sourcecode von pyodbc sowie die oben erwähnte Datei unixodbc-dev.
Wer das erste Mal selbst kompiliert, installiert noch build-essential, letzteres ist wieder bequem über apt-get oder Synaptic aus den Ubuntu-Archiven verfügbar.
Das pyodbc-Archiv muss entpackt werden. Danach begibt man sich in das beim Auspacken angelegte Verzeichnis und gibt
sudo python setup.py build install
ein. Das war es schon.
Kurze Zusammenfassung:
Aus den Ubuntu-Repositories braucht man:
build-essential, unixodbc-dev, unix-odbc und libmdbodbc.
Aus dem Web:
pyodbc
Und los geht's
import odbc
con = pyodbc.connect("DSN=bilderdb")
cursor = con.cursor()
cursor.execute("sinnvoller SQL-Befehl")
result = cursor.fetchone()
Jedem, der in Python mit Datenbanken zu tun hatte, sollten diese Zeilen bekannt vorkommen.
Die bei connect verwendete Zeichenkette, die in diesem Beispiel nur auf eine Datenquelle (DSN) verweist, kann viele andere Parameter aufnehmen, z.B. Username und Passwort bei einer passwortgeschützten Datenbank:
con = pyodbc.connect("DSN=bilderdb;UID=name;PWD=passwort")
Die einzelnen Parameter werden, durch Semikolon getrennt, in der Form Attribut=Wert aneinandergereiht. Die Namen der Attribute hängen vom verwendeten Treiber ab und sind recht vielfältig.
Zum Schluss noch ein paar nützliche Tipps beim Erkunden einer MS-Access-Datenbank:
Liste der Tabellen in einer Datenbank
import pyodbc
con = pyodbc.connect('DSN=bilderdb')
cursor = con.cursor()
for row in cursor.table():
print row
Die Zeilen haben den Aufbau (Werte: String oder None):
table_cat
table_schem
table_name Name der Tabelle
table_type SYSTEM TABLE, VIEW, TABLE
Die eigentlichen Tabellen werden unter dem Typ TABLE aufgelistet.
Aufbau einer Tabelle
Dieser lässt sich mit dem normalen SQL-Befehl erfragen:
cursor.execute('DESCRIBE TABLE tablenname")
Das Ergebnis wird in der Form (Name, Type, Größe) zurückgegeben.
Dienstag, 14. Juli 2009
Eigene Videos auf das Cybershot

Nun gut - ein paar Multimedia- und Organizer-Funktionen hat es dann doch, sowie einen 5 Megapixel-Fotosensor, und es kann Videos aufnehmen und wiedergeben.
Die Handhabung ist ... naja - aber hier geht es ja um...
Die Zusammenarbeit mit Linux
Die Kamera wird unter Linux über das mitgelieferte USB-Kabel als Standard-Massenspeicher erkannt und wie ein normaler USB-Stick behandelt, was den Datentransport sehr beschleunigt. Und seitdem unter Ubuntu Jaunty die Bluetooth-Treiber wieder funktionieren, klappt der Datenaustausch auch drahtlos.
Als Videoformate können 3GP- und MP4-Dateien wiedergegeben werden. Das Display hat 320 x 240 Pixel. Was die Bildgröße der Videos angeht, so skaliert und dreht das Handy (es hat einen Lagesensor) den wiedergegeben Clip, wenn dieser größer oder kleiner als das Display ist.
Erstellen einer MP4-Datei über die Kommandozeile
Ein auf verschiedenen Seiten empfohlener Workflow ist - das Codieren mit mencoder:
mencoder input_file \Dieser Aufruf skaliert das Video auf 320x240 Pixel, codiert es als mpeg4 mit einer Bitrate von 300 kbps und 25 Bildern pro Sekunde. Das Audio wird mit AAC codiert (hierzu muss ggf. das Paket libfaac0 nachinstalliert werden). Audioeinstellungen: Bitrate 64 kbps, Stereo (2 Kanäle) und eine Samplerate von 44100 Hz.
-vf scale=320:240 \
-ovc lavc -lavcopts vcodec=mpeg4:vbitrate=300 \
-ofps 25 \
-oac faac -faacopts br=64:object=2 -channels 2 -srate 44100 \
-o output.avi
Weil mencoder angeblich kein normgerechtes MP4 erzeugen kann, wird das Ergebnis zunächst als AVI gespeichert, und im nächsten Schritt mit mplayer wieder in eine Video- und eine Audio-Datei getrennt:
mplayer output.avi -dumpvideo -dumpfile temp.mp4v
mplayer output.avi -dumpaudio -dumpfile temp.aac
Diese werden dann mit dem Programm mp4creator (aus dem Paket mpeg4ip-server) wieder zusammengefügt - diesmal normgerecht:rm output.mp4
mp4creator -r 25 -c temp.mp4v output.mp4
mp4creator -c temp.aac output.mp4
mp4creator -optimize output.mp4
Das Ergebnis ist dann eine MP4-Datei, die vom C902 wiedergegeben werden kann. Die Bildrate (in diesem Beispiel 25 fps) muss hier explizit angegeben werden.
Man kann mit den Werten ein wenig spielen und z.B. die Audio-Abtastrate an das Quellmaterial anpassen. 300 kbps für Video und 64 kbps für Audio liefern für die Wiedergabe auf dem Handy brauchbare Ergebnisse.
Erstellen der MP4-Datei mit Avidemux
Avidemux ist ein Videokonvertier-Programm mit einigen rudimentären Schnittmöglichkeiten und diversen Bearbeitungsoptionen. Es lässt sich meist über das Repository der jeweiligen Distribution nachinstallieren.
Im Programm selber nimmt man dann - in Anlehnung an die von mencoder verwendeten Werte - folgende Grundeinstellungen vor:

Audio: AAC (FAAC)
Format: MP4
Video - Konfigurieren

Benutzerschnittstelle
Kodier-Modus:
Einfacher/zweifacher Durchlauf mit (Durchschnitts-)Bitrate
Bitrate (kb/s): 300
Audio - Konfigurieren

Bitrate: 64 kb/s
Nun können auch die restlichen Filter und Bearbeitungsfunktonen zum Einsatz kommen. z.B. das Zuschneiden des Clips, Änderungen in der Bildgröße, De-Inferlace-Funktionen, Anlegen neuer Tonspuren, um nur einige zu nennen.
Das Ergebnis ist nach einem "Datei - Speicher - Video speichern" direkt auf dem C902 einsetzbar.
Und sollte die Wiedergabe des Videos das Handy einmal zum Absturz bringen - die Batterie lässt sich ja einfach aus- und wieder einbauen.
Abonnieren
Posts (Atom)