Marco Islas Blog Software_Development http://islascruz.org/html/ markuz@islascruz.org (Marco Antonio Islas Cruz) 2005-2008, Marco Antonio Islas Cruz Mon, 08 Feb 2010 00:54:27 -0600 JAWS 0.8.9 <![CDATA[ Playing with Nokia S60. ]]>


Me :-)

Originally uploaded by markuz



I've just started playing with Nokia S60v5. I'm currently using Python to develop some learning stuff. Remember, Symbian is now Open Source, a little bit late, but Open Source at the end.

]]>
http://islascruz.org/html/index.php/blog/show/Playing-with-Nokia-S60..html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Playing-with-Nokia-S60..html Mon, 08 Feb 2010 00:41:25 -0600
<![CDATA[ Right now ]]>


Right now

Originally uploaded by markuz



3:20 in the morning and I'm working, I need to finish a program that I wrote almost a year ago, that was a Demo program and in 4 days (right now just 2) should be production ready!... I'm gonna need a double Monster dosis.

]]>
http://islascruz.org/html/index.php/blog/show/Right-now.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Right-now.html Sat, 30 Jan 2010 04:29:48 -0600
<![CDATA[ Christine 0.6.1 ]]>
  • http://sourceforge.net/projects/christine/files/christine/0.6.1/christine-0.6.1.tar.bz2
  • http://sourceforge.net/projects/christine/files/christine/0.6.1/christine-0.6.1.tar.gz
  • Binary Packages
    • Ubuntu: https://launchpad.net/~markuz/+archive/ppa (if you already set the ppa in your apt sources list then wait for the update soon :-))
    • Windows: http://sourceforge.net/projects/christine/files/christine/0.6.1/Christine-0.6.1.exe ]]> http://islascruz.org/html/index.php/blog/show/Christine-0.6.1.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine-0.6.1.html Wed, 13 Jan 2010 22:01:02 -0600 <![CDATA[ Drawing with Cairo without flicker ]]> (py)Gtk provides a quick way to get a cairo context using the gtk.DrawingArea widget, this widget let you draw everythin you want into your application using the widget.window drawable area.

      It help you to create custom widgets (you can also use this with buttons or any other widget), the problem with the usage of this context is that everything you ask it to draw it will draw it as soon as it can.

      If you draw several lines or you draw the same thing very often (an animation for example) your draw may flick, making your application looks ugly.

      There is an easy way to avoid this, using a surface to draw and when you are done put your draw into the context using the set_source_surface method.

      In the next example you have a windows, with a custom "progressbar" using gtk.DrawingArea and a slide that is supposed to change the value of the progressbar but I'm so lazy to move a slide that let the computer do the work :-).

      The trick is this part of the code:

              def do_expose(self, widget, event):
                      x,y,w,h = self.allocation
                      surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, w,h)
                      context = cairo.Context(surface)
                      #cleaning
                      rectangle = context.rectangle(x,y,w,h)
                      context.set_source_rgb(1,1,1)
                      context.fill()
                      value = (self.value / 100)*w
                      rectangle = context.rectangle(x,y,value,h)
                      context.set_source_rgb(0.2,0.5,0.8)
                      context.fill()
                      cr = self.window.cairo_create()
                      cr.set_source_surface(surface)
                      cr.paint()
                      return True
       

      We create a surface using cairo.ImageSurface and then create a cairo context from it, draw on that context and at the end use the widget.window.cairo_create to create a context for the drawing_area and use set_source_surface to get all the stuff
      we drew into the DrawingArea context. At the en just paint it.




      ]]>
      http://islascruz.org/html/index.php/blog/show/Drawing-with-Cairo-without-flicker.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Drawing-with-Cairo-without-flicker.html Wed, 30 Dec 2009 01:56:40 -0600
      <![CDATA[ Christine shot for today ]]>


      christine shot for today

      Originally uploaded by markuz



      This is how christine looks like today!

      ]]>
      http://islascruz.org/html/index.php/blog/show/christine-shot-for-today.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/christine-shot-for-today.html Fri, 04 Dec 2009 11:54:26 -0600
      <![CDATA[ Christine update for December 01 ]]> Tonight I have been working on Christine, in the GUI, IMO a media player that work fine should also look good and sometimes GTK just don't fit on that, why? it is because GTK is a general purpose graphical toolkit and everything is general, I wish GTK has some more widget options (like more buttons that fit a specific function, like those small rounded with a simple question sign help buttons)

      christine buttonsFortunately, you can write your own widgets and make them look as you want. Tonight I have been working on Christine's new buttons, just for the Previous, Play/Pause, Next. Creating custom buttons is not a complicated task, just subclass gtk.Button and connect your button "expose-event" signal to a custom function, remember at the end of this function return "True" in order to stop the signal emition. If you don't do this the gtk.Button will do its task and will redraw the button.


      Christine

      As usual, you can check out the source code from the svn

      ]]>
      http://islascruz.org/html/index.php/blog/show/Christine-update-for-December-01.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine-update-for-December-01.html Tue, 01 Dec 2009 07:29:36 -0600
      <![CDATA[ Python trick: How to make lazy objects? ]]> This time I'm about to talk about lazy object, I called like that because they are more or less similar to what we use in lazy treeviews (In Gtk) where the Tree shows expanders but didn't load the child nodes until you expand the node). What I want to do is create objects and count them, but don't load any data until I need it.

      Why would I need this?. Well. I'm currently writing a program for my employer, this program load a list of customers and shows how many accounts it has. As this accounts are kind of complex I create an object for them. This object is responsible for load/save the data for it, and any data you need is accessed via properties.

      In my first approach, the object was loading the data as soon as the constructor was called, but sometimes I never access to any info in that object, remember, a customer may have many (and I mean really many) accounts, then why load all the data if there is a chance that I'll never use it?. Well, that is because there is a chance that I have to use that data.

      Then how could I create the object and then load the data when somebody require it?. That may be easy, may not. :-). One approach is making use of python properties. Just create the object and when someone want to use a "value" from the object use the property to retrieve the data, process it and then return a value. A simple property may be defined like this:

      class demo(object):
          def get_some_property(self):
              #Here you can make use of whatever you want to retrieve the data
              pass
          def set_some_property(self, value):
              #Here you get a value and save it.
              pass
          some_property = property(get_some_property, set_some_property, None, 'Doc')
       

      I just create a class "demo" and the property "some_property", everytime you use this:

      d = demo()
      d.some_property
       

      Python will call the method get_some_property allowing you to do your trick. But if you have an object with more and more properties is better to get all data at one time and then just use properties to return a piece of it. You could call a method on every property if the data container is empty but for me it is not the best.

      What you could do, is get the data the first time you need it. But, how could I know when a property/variable is requested on my object?

      Well, Python classes have several reserved methods, and one of them is __getattribute__. This method let you handle every request to any property/class variable in your object.

      With this you can digg in your object to know if the container is empty, and if it is empty fill it with data before returning the property value :-).

      Lets say that the demo object have a __data dictionary containing the data. and propeties look into it for the right value, it also have a reference to the storage layer called storage.

      class demo(object):
              def __init__(self):
                      self.__data = {}
                      self.storage = storage()
              def __getattribute__(self, name):
                      obj = object.__getattribute__(self,name)
                      #Check if the requested property is __data
                      if name in("__data", '_account__data'):
                              #Get the reference of __data
                              d = object.__getattribute__(self,'_account__data')
                              if not d: #Get in only if __data is empty.
                                      #Get your
                                      s = object.__getattribute__(self,'storage')
                                      #We can assign without using object.__getattribute__
                                      self.__data = s.get_data()
                                      #Get the value again
                                      obj = object.__getattribute__(self,name)
                      return obj
       

      Pay attention that I used object.__getattribute__ instead self.property, if I use self.property will call self.__getattribute__ and will cause a recursion exception.

      With this, we can create a great number of objects quickly and reducing the memory footprint.

      ]]>
      http://islascruz.org/html/index.php/blog/show/Python-trick%3A-How-to-make-lazy-objects%3F.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Python-trick%3A-How-to-make-lazy-objects%3F.html Sun, 22 Nov 2009 05:00:41 -0600
      <![CDATA[ Christine 0.6.0-pre1: first win32 build ]]>
      Christine on Win32

      This night I have been working on the Win32 build of christine. It seems to be working fine. This version is just a test, for those that wanted to use christine on Microsoft Windows.

      Altough that I have made some tests on a clean Windows XP installation cannot guarantee that the Win32 will work on your computer.

      Anyway, if you are brave enough, download the win32 binary and report any bug you found on it.

      If you want to compile it, you will need this:

      • Python 2.6 (I built Christine with it, but python >= 2.5 should work too)
      • Gstreamer Winbuild (http://www.gstreamer-winbuild.ylatuya.es/doku.php)
      • Microsoft Visual C++
      • py2exe (http://py2exe.org/)

      The build script is in win32resources/christine_setup.py, just copy it to the source root and run python christine_setup.py -q py2exe to build it.

      You can download the win32 binary from here: http://downloads.sourceforge.net/project/christine/christine/0.6.0-pre1/Christine-0.06.00-pre1.exe

      I forgot to mention that you have to install Microsoft Visual C++ 2008 redistributable in order to work.

      ]]>
      http://islascruz.org/html/index.php/blog/show/Christine-0.6.0-pre1%3A-first-win32-build.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine-0.6.0-pre1%3A-first-win32-build.html Sun, 22 Nov 2009 04:10:06 -0600
      <![CDATA[ Image as background in a Gtk Application. ]]> This time I'm going to talk about putting an image as the application background in Gtk. In Gtk we are used to leave the colors of the application to the theme, but sometimes we will need to use an image as background. I already wrote how to draw a pixbuf in a gtk.DrawingArea (Esp), we could use that, but we will "draw" directly on the widget window instead.

      Yes, I said the widget's window instead the widget itself. You should know that every widget that has been packed in a container has a gtk.gdk.window object and is the responsible for containing your widget. Well, we can draw on that object.

      What we need is to create a simple gtk.gdk.Pixbuf and call the gtk.gdk.window.draw_pixbuf method using your widget.window object on the expose-event.

      The code should look like this:

      #!/usr/bin/env python
      import gtk
      def draw_pixbuf(widget, event):
              path = '/home/markuz/wallpapers/WMwall1024x768.gif'
              pixbuf = gtk.gdk.pixbuf_new_from_file(path)
              widget.window.draw_pixbuf(widget.style.bg_gc[gtk.STATE_NORMAL], pixbuf, 0, 0, 0,0)
      window = gtk.Window()
      window.set_title('Drawing Test')
      window.set_size_request(640,480)
      window.connect('destroy',gtk.main_quit)
      hbbox = gtk.HButtonBox()
      window.add(hbbox)
      hbbox.connect('expose-event', draw_pixbuf)
      button = gtk.Button('Press Me!')
      hbbox.pack_start(button, True, False, 10)
      window.show_all()
      gtk.main()
       
      And the result should be like this:

      Putting an image as background in Gtk

      It is just a window with an HBoxButton as container and a Button in the middle. The button draws normal, but the HButtonBox is drawing its gtk.gdk.window with a pixbuf. ]]>
      http://islascruz.org/html/index.php/blog/show/Image-as-background-in-a-Gtk-Application..html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Image-as-background-in-a-Gtk-Application..html Wed, 18 Nov 2009 01:16:02 -0600
      <![CDATA[ Christine running on MS Win32 ]]>

      Finally!!!, Christine, my beloved media player is running on Windows, this is something that I really wanted to do for the next release. I had spend the last nights trying to compile it, first I tried to compile GStreamer, then I realized that there are binaries in the GStreamer WinBuilds project, with a little less work, I tried to compile Christine using cygwin, but it didn't worked. Then using the Python's distutils I compiled the C modules and I created a binary with Py2exe

      There it is, running. I still have a lot of work to do, because Christine is written for UNIX and several technologies like Dbus are not in win32, although it seems to be in progress.

      I'm running it on a virtual machine and I haven't tested if it really plays something, I'll give a try tomorrow.

      For tonight I'm happy :-)

      Some shots:

      Christine running on Win32 Christine running on Win32Coding Christine
      ]]>
      http://islascruz.org/html/index.php/blog/show/Christine-running-on-MS-Win32.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine-running-on-MS-Win32.html Sat, 31 Oct 2009 04:29:06 -0500
      <![CDATA[ Trying to compile christine on Windows ]]>


      Trying to

      Originally uploaded by markuz



      Last night I was trying to compile christine on windows using cygwin, I didn't made it but I think I know why, I will try to make it work this tonight.

      ]]>
      http://islascruz.org/html/index.php/blog/show/Trying-to-compile-christine-on-Windows.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Trying-to-compile-christine-on-Windows.html Wed, 28 Oct 2009 10:45:23 -0500
      <![CDATA[ Christine playing videos ]]>


      Christine playing videos

      Originally uploaded by markuz



      I was playing with gstreamer video sinks, I found that using cacasink and aasink you can play videos in ascii mode ;-) funny even when (for me) has no good use.

      ]]>
      http://islascruz.org/html/index.php/blog/show/Christine-playing-videos.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine-playing-videos.html Fri, 23 Oct 2009 17:31:00 -0500
      <![CDATA[ Christine small mode ]]>


      Christine small mode

      Originally uploaded by markuz



      This is Christine in small mode (Ctrl+d).

      ]]>
      http://islascruz.org/html/index.php/blog/show/Christine-small-mode.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine-small-mode.html Wed, 21 Oct 2009 12:22:52 -0500
      <![CDATA[ Developing Christine ]]>


      Christine

      Originally uploaded by markuz




      ]]>
      http://islascruz.org/html/index.php/blog/show/Developing-Christine.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Developing-Christine.html Wed, 21 Oct 2009 02:49:48 -0500
      <![CDATA[ Working on Christine ]]>


      Christine

      Originally uploaded by markuz



      Tonight I have been working on the display widget. That part of christine that displays the title and lenght of the song you are playing. I have set up a background to make it look less simple.
      I also put the control buttons, the volume control and the search entry (which is hided in this screenshot) in a toolbar.
      What do you think about this small changes?

      ]]>
      http://islascruz.org/html/index.php/blog/show/Working-on-Christine.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Working-on-Christine.html Wed, 21 Oct 2009 02:47:48 -0500
      <![CDATA[ Christine 0.5.1 released! ]]> It supports all the media files that your gstreamer installation can support, being MP3, OGG, AVI, MPG. It saves the URIs and Meta tags in a database and let you browse them quickly.
      Christine also provides early support for Radio Stations and have its own DBus interface which let you control christine with your media keyboard buttons as they are configured on GNOME.
      The early access to Plugins will let you tweet the music you are listening to, put it on your pidgin status and use notifications while you change your current song.

      Bug fix release

      Several bugs have been fixed, you can find the bug list and release notes here

      Download

      Download Sources

      ]]>
      http://islascruz.org/html/index.php/blog/show/Christine-0.5.1-released%21.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine-0.5.1-released%21.html Tue, 13 Oct 2009 00:41:09 -0500
      <![CDATA[ Working on christine 0.5 ]]>


      Working on christine 0.5.0

      Originally uploaded by markuz



      I have been working today on Christine 0.5 fixing bugs to release 0.5.1 and then start working on new features.

      ]]>
      http://islascruz.org/html/index.php/blog/show/Working-on-christine-0.5.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Working-on-christine-0.5.html Sat, 03 Oct 2009 22:15:29 -0500
      <![CDATA[ Extra Large ]]>
      DSC04831.JPG

      Originally uploaded by markuz



      This is the biggest Red Bull I've ever seen.

      ]]>
      http://islascruz.org/html/index.php/blog/show/Extra-Large.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Extra-Large.html Fri, 04 Sep 2009 17:02:50 -0500
      <![CDATA[ Christine 0.5.0 released! ]]> It supports all the media files that your gstreamer installation can support, being MP3, OGG, AVI, MPG. It saves the URIs and Meta tags in a database and let you browse them quickly.
      Christine also provides early support for Radio Stations and have its own DBus interface which let you control christine with your media keyboard buttons as they are configured on GNOME.
      The early access to Plugins will let you tweet the music you are listening to, put it on your pidgin status and use notifications while you change your current song.

      What's new

      • Faster: Christine improves the startup and search methods to be faster than 0.4.0.
      • Drag and Drop import: You can import a folder by Dragging it from Nautilus and dropping into Christine.
      • Library list flick: In Christine 0.4, when the list is too big and you are at the end, it flicks while you scroll over it. Christine 0.5.0 improves that, with smooth scroll.
      • Config directory change Apply the freedesktop's standard for config directory http://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
      • Double function in Previous button When you are using Christine and click in the previous button, Christine will restart the current item, if you hit the previous button again it will get you to the previous item.
      • Import files are something non-blocking You can use Christine while you are importing files.

      Download

      Download Sources

      Binary Packages

      update: Added the Fedora package link. ]]>
      http://islascruz.org/html/index.php/blog/show/Christine-0.5.0-released%21.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine-0.5.0-released%21.html Tue, 01 Sep 2009 01:34:34 -0500
      <![CDATA[ Wrap text in a TreeView column ]]> In ICT Consulting I did a small program that help the support team to create new tickets in the tracking system and keep them updated. In the "update" screen, I put a TreeView to show the comments history.

      For Gtk TreeViews are just a "viewer" of the data stored in the "model", but it depends in the way the cell renderer will do its job. The render for text is called.. yes, you guessed: CellRendererText. This item will render the text as it is in the model.

      If you are using text with markup (with the pango markup) it will be displayed with bold, italic and many other properties you define in your markup. But this render have a small problem, if you have a long line because the input method was a text box and the user didn't use the return key then you will end with a very very long line in the treeview.

      If the line is not too big then the use of the scrollbar may help you, but, if that's not the case, and you or your user have to check more and more lines like that, using the scrollbar is tedious.

      The fix: make the column usually big to wrap the text.

      The trick is know the size of the window, and compute the space left by other columns then, set the
      wrap_width property of the cell renderer according to the space left. That's what the "resize_wrap" function do.




      treeview resize

      ]]>
      http://islascruz.org/html/index.php/blog/show/Wrap-text-in-a-TreeView-column.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Wrap-text-in-a-TreeView-column.html Sun, 30 Aug 2009 02:04:53 -0500
      <![CDATA[ Using Ctrl+s to save in Vim ]]> You can achieve this behavior in gvim, just edit your vimrc, typically located in /home/$user/.vimrc and add the next lines:
      if has("gui_running")
        " If the current buffer has never been saved, it will have no name,
        "
      call the file browser to save it, otherwise just save it.
        :map <silent> <C-S> :if expand("%") == ""<CR>:browse confirm w<CR>:else<CR>:confirm w<CR>:endif<CR>
      endif
       
      Then add this imap to save any time you are typing, with this, you just save as in any other text editor, just Ctrl+s and keep going.
      :imap <c-s> <c-o><c-s>
       
      Source ]]>
      http://islascruz.org/html/index.php/blog/show/Using-Ctrl%2Bs-to-save-in-Vim.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Using-Ctrl%2Bs-to-save-in-Vim.html Sun, 30 Aug 2009 01:10:13 -0500
      <![CDATA[ Holy Shit! ]]> I used Christine in an usual way. I use to play the items in the main list as the items there are in my hard drive. Today I was switching between playlists and some of them have more or less 14000 items. I don't know why but christine grows a lot more than I expect.

      Holy Shit!!!
      ]]>
      http://islascruz.org/html/index.php/blog/show/Holy-Shit%21.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Holy-Shit%21.html Sat, 08 Aug 2009 01:03:55 -0500
      <![CDATA[ Christine on Fedora ]]>
      Fedora

      Nushio is building Christine packages for Fedora. He already build Christine 0.4.0 for Fedora 11 x86 and packages for the other architectures are coming.
      You can get the package from here:

      http://nushio.fedorapeople.org/christine/

      ]]>
      http://islascruz.org/html/index.php/blog/show/Christine-on-Fedora.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine-on-Fedora.html Thu, 23 Jul 2009 14:15:55 -0500
      <![CDATA[ Christine Drag & Drop ]]>


      ]]>
      http://islascruz.org/html/index.php/blog/show/Christine-Drag-%26-Drop.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine-Drag-%26-Drop.html Thu, 23 Jul 2009 12:08:28 -0500
      <![CDATA[ Christine on Gentoo ]]> If you are using Gentoo, now you can use the ebuild to have christine running on your system, more on:

      http://packages.gentoo.org/


      Thanks to Samuli Suominen who is taking care :-) ]]>
      http://islascruz.org/html/index.php/blog/show/Christine-on-Gentoo.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine-on-Gentoo.html Wed, 22 Jul 2009 06:35:54 -0500
      <![CDATA[ Help Christine: Translate ]]> If you talk mote than one language, please consider helping Christine translating it., you'll need a launchapd account, then go to this url and help us :-):

      https://translations.launchpad.net/christine/0.5.0

      ]]>
      http://islascruz.org/html/index.php/blog/show/Help-Christine%3A-Translate.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Help-Christine%3A-Translate.html Tue, 21 Jul 2009 15:16:55 -0500
      <![CDATA[ Python C Class ]]> IronPython.
      The main reason of why you want to extend Python is because the libraries you need are not in the Python packages/modules, another reason may be that you need to crate a small piece of code that have to run faster, IMHO Python is fast enought for most tasks but it doesn't mean that you don't need to create your own C modules.
      Python offers a very good C/C++ API for this. This API is explained in the Python/C API Reference Manual and you'll have a tutorial in the document Extending and Embedding the Python Interpreter, they cover most of what you need.
      I said *most* because even when they are well done documents, you may still have some questions (as I did).
      Well, this post is about classes in python written in C. If you didn't already, there is a recipe in ActiveState's documents, Recipe 54352: Defining Python class methods in C , this recipe will tell you how to create a class in a quick way let's see what does the code do.
      In the next example, I'm creating a class whose methods are going to be inherited by a another class. Now, you know that C is not an object oriented language, and having something like object.property does not exists (you'll have to use an struct for that). Then, you have to create your "methods" as "functions" and add them later to the class you are creating.
      #include <Python.h>
      #include <import.h>
      /*
      * Constructor, yes the Class.__init__ method
      */

      static PyObject*
      init(PyObject *self){
              Py_INCREF(Py_None);
          return Py_None;
      }
      /*
      * A simple method that will be inherited
      * we are assuming that the child class will have a
      * "data" property
      */

      static PyObject *
      print_data(PyObject *self, PyObject *args)
      {
              static PyObject *result;
              static PyObject *selfobj;
              static PyObject *data;
              int index;
          if (!PyArg_ParseTuple(args, "O", &selfobj, ))
              return NULL;
          data = PyObject_GetAttrString(selfobj, "data");
          PyObject_Print(data, stderr, Py_PRINT_RAW);
          Py_INCREF(Py_None);
          return Py_None;
      }
      static PyMethodDef baseClassMethods[] = {
              {"__init__", init, METH_VARARGS,"doc string"},
          {"print_data",  print_data, METH_VARARGS,
          "Print what the data property is/contain."},
          {NULL, NULL, 0, NULL}
      };

      static PyMethodDef ModuleMethods[] = { {NULL} };
      #ifdef __cplusplus
      extern "C"
      #endif
      PyMODINIT_FUNC
      baseClass(void)
      {
              PyMethodDef *def;
              PyImport_AddModule("baseClass");
          //(void) Py_InitModule("baseClass", baseClassMethods);
          PyObject *module = Py_InitModule("baseClass", ModuleMethods);
          PyObject *moduleDict = PyModule_GetDict(module);
          PyObject *classDict = PyDict_New();
          PyObject *className = PyString_FromString("baseClass");
          PyObject *fooClass = PyClass_New(NULL, classDict, className);
          PyDict_SetItemString(moduleDict, "baseClass", fooClass);
          Py_DECREF(classDict);
          Py_DECREF(className);
          Py_DECREF(fooClass);
          /* add methods to class */
          for (def = CLibraryModelMethods; def->ml_name != NULL; def++) {
              PyObject *func = PyCFunction_New(def, NULL);
              PyObject *method = PyMethod_New(func, NULL, fooClass);
              PyDict_SetItemString(classDict, def->ml_name, method);
              Py_DECREF(func);
              Py_DECREF(method);
           }
      }
      int
      main(int argc, char *argv[])
      {
          /* Pass argv[0] to the Python interpreter */
          Py_SetProgramName(argv[0]);
          /* Initialize the Python interpreter.  Required. */
          Py_Initialize();
          /* Add a static module */
          initCLibraryModel();
          return 0;
      }
       
      The code I saw in the recipe is so simple, quite enought to start, but, I have two very very important question.. how that hell do I get the reference of the class? and then, access to the child properties?. Well, looking in the docs, the functions appear to start with a "self" PythonObject, which I assume that is the reference to the class, but no, if you look close the the PyMethod_New the sencond argument is the "self" reference to the class, which we are passing as NULL.
      Using the code in the recipe, when you inherit your class or even using it in this way:
      class a(baseClass):
          def __init__(self):
              baseClass.__init__(self)
              a.data = 'Hello World!'
      b = a()
      b.print_data()
       
      will give an error, if you consider that you are not passing arguments. The problem with the code in the recipe is that they are not using the "self" reference. I found (maybe I'm wrong) that the self reference comes in the arguments!, then you have to do something like this:
      static PyObject *
      print_data(PyObject *self, PyObject *args)
      {
          ...
          if (!PyArg_ParseTuple(args, "O", &selfobj, ))
              return NULL;
          data = PyObject_GetAttrString(selfobj, "data");
          ...
      }
       
      You take the self, reference from the args using the same PyArg_ParseTuple that you use to get the other arguments. Now you can use this class as any other class written in Python, just rememter the __setattr__ and __getattr__ part that is in the bottom of the recipe ]]>
      http://islascruz.org/html/index.php/blog/show/Python-C-Class.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Python-C-Class.html Mon, 13 Jul 2009 04:54:36 -0500
      <![CDATA[ PyGtk: GtkDialog for configurations using pure treeviews ]]>


      I have been working on this, this is a very early version of the configuration dialog I have already created, I promisse I will put fully working version here with source code :-) ]]>
      http://islascruz.org/html/index.php/blog/show/PyGtk%3A-GtkDialog-for-configurations-using-pure-treeviews.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/PyGtk%3A-GtkDialog-for-configurations-using-pure-treeviews.html Wed, 10 Jun 2009 09:25:50 -0500
      <![CDATA[ Head Tracking for Desktop VR Displays using the WiiRemote ]]> Project natal rocks, but this (at least for me) rocks even more..



      If they get together that would be awesome! ]]>
      http://islascruz.org/html/index.php/blog/show/Head-Tracking-for-Desktop-VR-Displays-using-the-WiiRemote.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Head-Tracking-for-Desktop-VR-Displays-using-the-WiiRemote.html Wed, 03 Jun 2009 23:01:50 -0500
      <![CDATA[ Sockets (and some other files) and PyGTK without threads. ]]> PyGTK and Threads motivated by the work I have been doing on ICT Consulting where I have a graphical application that need to have a web service where some other applications could connect and execute some of its public function.
      My first aproach was Threads just because with them I could use an infinite loop reading the socket while in the main thread the gtk loop runs. This is nice if your application is going to ask/request something trough the socket and receive the answer at some point, then, when the answer is here, you could emit a signal and then move your gui to show the answer.
      But, what if you need to receive the request and then, move your gui asking to the user for an answer or show something in the screen, or whatever, you could make use of what I just did in the PyGTK and Threads post, where you use gobject.idle_add to launche the function that will modify your gui, which is nice you don't care about the return value of the task.
      Today, looking in trough the gobject reference I saw the gobject.io_add_watch function. This function will let you, as its name describes, watch for the I/O activity in a file descriptor. As sockets are treated like sockets, then you have the chance to use it here.
      What about that?, well, if you have the chance to check the I/O of the socket file then you will know when data arrives and call the proper handler, and do it in the very same thread that the main loop. Then, you can move the GUI and return something if you have to.
      In webservices this is useful because you can catch any error and inform the client that there is something wrong with the function it calls. The implementation is quite simple, let's do it with the code that we already use in the Threads post.
      This is the server:
      import SOAPpy
      import gtk
      import gobject
      import time
       
      def hello(name):
              dialog = gtk.Dialog("Hello dialog",
                              None,
                              gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
                              (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
                                      gtk.STOCK_OK, gtk.RESPONSE_ACCEPT,)
                              )
              label = gtk.Label('Hello %s'%name)
              dialog.vbox.pack_start(label)
              label.show()
              response = dialog.run()
              dialog.destroy()
              return response
      def change_time(label):
              label.set_text(repr(time.time()))
              return True
      def handle_request(source, condition, webservice):
              try:
                      webservice.handle_request()
              except:
                      pass
              return True
             
      soapserver = SOAPpy.SOAPServer(('',8080))
      soapserver.registerFunction(hello)
      gobject.io_add_watch(soapserver.socket, gobject.IO_IN,
                           handle_request, soapserver)
      win = gtk.Window()
      win.connect('destroy', gtk.main_quit)
      win.set_size_request(300,300)
      label = gtk.Label('Main window')
      gobject.timeout_add(100, change_time, label)
      win.add(label)
      win.show_all()
      gtk.main()
       
      And the client:
      #!/usr/bin/env/python
      import SOAPpy
      import sys

      server = SOAPpy.SOAPProxy("http://localhost:8080/")

      prueba = sys.argv[1]
      args = tuple(sys.argv[2:])
      print args
      func = getattr(server, prueba, False)
      print func(*args)
       
      Using it like this:
      python soaptest.py hello markuz
      gives as result the integer value for the response asociated to the button you just clicked.

      Gtk webservices with no threads from Marco Antonio on Vimeo.


      I hope this information is useful for you. For me, it saves my day! ]]>
      http://islascruz.org/html/index.php/blog/show/Sockets-%28and-some-other-files%29-and-PyGTK-without-threads..html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Sockets-%28and-some-other-files%29-and-PyGTK-without-threads..html Wed, 27 May 2009 00:58:06 -0500
      <![CDATA[ Christine 0.4.0 released! ]]> It supports all the media files that your gstreamer installation can support, being MP3, OGG, AVI, MPG. It saves the URIs and Meta tags in a database and let you browse them quickly.
      Christine also provides early support for Radio Stations and have its own DBus interface which let you control christine with your media
      buttons as they are configured on GNOME.
      The early access to Plugins will let you tweet the music you are listening to, put it on your pidgin status and use notifications while
      you change your current song.
      Changes since 0.3.1
      • Christine plugins are now python packages allowing developers to create them in multiple modules.
      • More methods in the DBus module.
      • Sources List and Queue List are showed in the same place hiding the other while the selected list is showed.
      • Hide de side bar by pressing F9 also, you an enable/disable it on the View Menu.
      Availability ]]>
      http://islascruz.org/html/index.php/blog/show/Christine-0.4.0-released%21.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine-0.4.0-released%21.html Sun, 24 May 2009 14:02:16 -0500
      <![CDATA[ PyGtk and Threads ]]> As a GNOME user I would like to make use of DBus, but again, I have no control over the other applications. and DBus even when it is widely accepted on the Linux/Unix environment, is not the same over Windows.
      Then, how could I communicate my program with the others?, easy, webservices, the reason: Usin a widely used protocol (HTTP) will ensure that the data is received or at least there will be error handlers, and, I don't have to implement the protocol by myself on python, even the webservices libraries exists for a while now.
      Implement a webservice is quite simple with Python, there are some libraries, but I like to use SOAPpy, so, create a webservices server is as simple as this:
      import SOAPpy
      def hello(name):
          return 'Hello %s'%name
      soapserver = SOAPpy.SOAPServer(('',8080))
      soapserver.registerFunc(hello)
      soapserver.serve_forever()
       
      This webservices server will be listening over the port 8080 for new connections and will allow the clients to use the hello function. Simple right?. Well there is something that we must watch, the serve_forever as the SOAPpy docs said, it will be serving until the doomsday, and it does it over a infinite while loop blocking our script on that point.
      For most applications this will be good, maybe because you only want to serve your functions like in the example. If you don't want to be stuck in the serve_forever method, then you have to use another thread. This is what you have to do while writing python applications that need to use a function/method that uses an infinite while loop or may take a long time to complete.
      The reason?, Gtk+ runs over a main loop, this loop is used by GTK+ to emit every signal, run the callbacks, draw everything it needs to redraw and call the functions that are in a gobject.timeout_add or gobject.idle_add methods. Gtk+ does it in one loop. Then, if a pice of your code require a bit more time the gtk loop takes more time to do the loop and it cannot redraw, emit, call, and do other stuff until your piece of code finish it's job, then, your application looks like it is freeze.
      Now, what happend if your piece of code is an infinite while loop?. Yes! Gtk will never do more than one cycle.
      This is why I use the code I know may take a long time in another thread. This may be donwloading something, or serving something. In general, you just need to initialize the threads in gobject calling
      gobject.threads_init()
       
      then, cover your thread over a gtk.gdk.threads_enter() and . This will help you making your application responsive while it is doing a long time task. But, be aware, if you don't do this your thread may not work, and you should know that you can't edit your UI within the child thread.
      It's supposed that you can do it if you use
      gtk.gdk.threads_init(), it does work on Linux, but it doesn't work if you are running your application on Win32.
      So, what can you do?, use you can use gobject.idle_add to launch a function where you are going to move the GUI. with this you will ensure that your GUI will be edited only in the main thread (where gtk.main_loop runs). Remember, your function should return something diferent than True if you don't want it to be called every time gobject have spare time.
      import SOAPpy
      import thread
      import gtk
      import gobject
      import time
      gobject.threads_init()
       
      def hello(name):
              def func(name):
                      dialog = gtk.Dialog("Hello dialog",
                                      None,
                                      gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
                                      (gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
                      label = gtk.Label('Hello %s'%name)
                      dialog.vbox.pack_start(label)
                      label.show()
                      response = dialog.run()
                      dialog.destroy()
                      return False
              gobject.idle_add(func, name)
      def change_time(label):
              label.set_text(repr(time.time()))
              return True
      soapserver = SOAPpy.SOAPServer(('',8080))
      soapserver.registerFunction(hello)
      gtk.gdk.threads_enter()
      thread.start_new(soapserver.serve_forever, tuple())
      gtk.gdk.threads_leave()
      win = gtk.Window()
      win.connect('destroy', gtk.main_quit)
      win.set_size_request(300,300)
      label = gtk.Label('Main window')
      gobject.timeout_add(100, change_time, label)
      win.add(label)
      win.show_all()
      gtk.gdk.threads_enter()
      gtk.main()
      gtk.gdk.threads_leave()
       

      Gtk and threads from Marco Antonio on Vimeo.


      Finally, maybe you don't want to mess with threads and prefer to use asynchronous I/O, or if you are talking about networking the use of the event-driven networking engine Twisted ]]>
      http://islascruz.org/html/index.php/blog/show/PyGtk-and-Threads.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/PyGtk-and-Threads.html Sat, 23 May 2009 01:21:43 -0500
      <![CDATA[ Help testing christine SVN code ]]>
    • Christine Plugins as packages in libchristine/Plugins
    • Use the traductions from rosseta ( I have to update the roseta template for the newest version).
    • I fix a compilation issue I had on Ubuntu, and I require your help here, can you try to compile christine on your system?.
    • I setup the Sources List and the Queue list in a much easier way to see/read, hiding one or the other as you require.
    I hope you have the time to test this and help me to release christine 0.4 within the next two weeks.
    You can get the code from the SVN, you don't have to install christine to test the code, just after the "make" use "make run" to run christine from the sources directory.
    If you found bugs, you can always create a new ticket in our new ticket system ]]> http://islascruz.org/html/index.php/blog/show/Help-testing-christine-SVN-code.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Help-testing-christine-SVN-code.html Thu, 14 May 2009 17:19:35 -0500 <![CDATA[ SourceForge.net's new look ]]>
    New look on sourceforge.net

    I found with surprise that SourceForce.net have a new look really cool and much much better than the orange one that they used. Now, they have to make their services a little bit more friendly, personally, I don't like the Tracker (for bugs, patchers, feature requests) system, the news is the worse system, just a small textarea for you tu put some text, but no chance to give it a little format, or even put an image. Fortunately you can use the "Hosted Apps" and replace their ulgy services with others like Trac, WordPress, change from CVS/SVN to Git/Mercurial/Bazaar.

    Anyway, step by step Sf.net is getting better. ]]>
    http://islascruz.org/html/index.php/blog/show/SourceForge.net%27s-new-look.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/SourceForge.net%27s-new-look.html Fri, 08 May 2009 23:43:53 -0500
    <![CDATA[ Python: Create win32 services using Python and py2exe ]]> Hi, in this case I'm going to show you how to create simple services for the win32 platform using the powerfull Python programming language and the py2exe utility.
    Writing Python applications under windows is quite simple, maybe you didn't use windows to develop your application (as I do most times), the code, what you want to do with your application is up to you, and I'm not goint to touch the programming techniques for developing windows applications, Just, create a simple -and useles- win32 service that will help you to uderstand how to create your very own windows service.
    First, every single program that you create with python and compile with py2exe and does run well, may be a win32 service, it may be a program that fetches the RSS xml feed for islascruz.org, maybe is a more complex program to generate some files and then send them to another server, maybe is a simple program to remind you to sand up an walk 10 minutes.
    Said that we don't really need to create a program thinking on it as a service, we will create a simple program and test it using the python interpreter, who needs to compile?, well, we need it, but just when we are sure that our program performs well.
    Read more ]]>
    http://islascruz.org/html/index.php/blog/show/Python%3A-Create-win32-services-using-Python-and-py2exe.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Python%3A-Create-win32-services-using-Python-and-py2exe.html Fri, 01 May 2009 21:27:26 -0500
    <![CDATA[ Christine for 2009-04-26 ]]> christine, first, I move the plugins, now, instead of being a simple module, they need to be a package, doing this will let us to develop bigger plugins and make use of their directory (package) to store whatever the plugin need to. I also work a bit on the subtitles part, letting the user choose his favourite font on the preferences dialog. Also, you can change the encoding. At last, I added five functions to christineDBus package: get_tags, add_to_queue, get_playlists, get_tracks_on_playlist, get_radios

    Christine preferences dialog with subtitles

    But, I haven't just worked on this, did I mention that now christine uses Trac?, well yes, we now use Trac in http://www.christine-project.org for ticket management, Roadmap, wiki and source code browsing. ]]>
    http://islascruz.org/html/index.php/blog/show/Christine-for-2009-04-26.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine-for-2009-04-26.html Sun, 26 Apr 2009 03:40:39 -0500
    <![CDATA[ Vim: snipMate ]]> vim and I found snipMate which is quite good. I don't think that the computer should write your code, but a little help (like closing braces, parenthesis) is never rejected. A snipper help you to write that "static" part of your code that repeats all the time, like function/class/method definition, while, for, try/except statements. So, I install this plugin for vim and currently Im testing it.


    snipMate.vim Introductory Screencast from Michael Sanders on Vimeo.

    The good is that the snip code is quite simple to edit, being something like this:
    snippet #!
            #!/usr/bin/python
    #coding
    snippet #-
            # -*- coding: ${1:coding} -*-
           
    snippet wh
            while ${1:condition}:
                    ${2:# code...}
    snippet for
            for ${1:needle} in ${2:haystack}:
                    ${3:# code...}
    # New Class
    snippet cl
            class ${1:ClassName}(${2:object}):
                    """${3:docstring for $1}"""
                    def __init__(self, ${4:arg}):
                            ${5:super($1, self).__init__()}
                            self.$4 = $4
                            ${6}
    # New Function
    snippet def
            def ${1:fname}(${2:`indent('.') ? 'self' : ''`}):
                    """${3:docstring for $1}"""
                    ${4:pass}
    # New Method
    snippet defs
            def ${1:mname}(self, ${2:arg})):
                    ${3:pass}
    # New Property
    snippet property
            def ${1:foo}():
                    doc = "${2:The $1 property.}"
                    def fget(self):
                                    ${3:return self._$1}
                    def fset(self, value):
     
    I also try to use PyLint for code check on vim, but.. I didn't really like it. The debugger I never really made it to work but with the snips I have enough for today, if you are a vim user and you aren't using it, you should try it too. ]]>
    http://islascruz.org/html/index.php/blog/show/Vim%3A-snipMate-1.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Vim%3A-snipMate-1.html Sat, 25 Apr 2009 11:38:50 -0500
    <![CDATA[ Christine on Foresight ]]>
    Christine on Foresight

    As usual Zodman, had made the build of christine for Foresight Linux
    sudo conary update christine=_at_fl:2-qa
    Replacing "_at_" by an arroba. ]]>
    http://islascruz.org/html/index.php/blog/show/Christine-on-Foresight.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine-on-Foresight.html Sun, 19 Apr 2009 23:04:24 -0500
    <![CDATA[ Christine: rola_christine.py ]]>
    xchat command to get christine current track

    Similar to what Gnuget do with rola-banshee.py I did the same but for christine:
    #! /usr/bin/env python
    # -*- coding: utf-8 -*-
     
    #Author: Marco Islas
    #Correo: markuz_at_islascruz_dot_org
    #Based on rola-banshee.py http://gnuget.org/blog/view/203/rola-banshee-py
     
    version = "1.0"
     
    __module_name__ = "rola_christine.py"
    __module_version__ = version
    __module_description = 'Shows the track in christine (requires christine from SVN)'
     
    import dbus
    import xchat
    from dbus.mainloop.glib import DBusGMainLoop
     
    class RolaChristine:
            def __init__(self):
                    mainloop = DBusGMainLoop()
                    self.dbus_session = dbus.SessionBus(mainloop = mainloop)
                    self.christine = self.dbus_session.get_object('org.christine',
                                    '/org/christine')
                    xchat.prnt("rola-christine.py Version %s loaded!" %version)
                    xchat.prnt("/rola-christine")
           
            def rola(self,word,word_eol,userdata):
                    tags = self.christine.now_playing()
                    title = '%s'%tags.get('title','')
                    if not title:
                            xchat.command('Nada a mostrar..')
                            return xchat.EAT_XCHAT
                    artist = "%s"%tags.get('artist','')
                    if artist:
                            artist = "%s -"%artist
                    xchat.command("me esta escuchando: %s %s" %(artist,title))
                    return xchat.EAT_XCHAT
    control = RolaChristine()
    xchat.hook_command("rola-christine",control.rola)
     
    This make me check my code, and the script above works only with christine on the svn. This code was done on the afternoon and may get broken at some place, but is nice if you want to play. ]]>
    http://islascruz.org/html/index.php/blog/show/Christine%3A-rola_christine.py.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine%3A-rola_christine.py.html Sun, 12 Apr 2009 23:29:19 -0500
    <![CDATA[ Christine 0.3.0 ]]>
    Christine 0.3.0

    =========================
    Christine 0.3.0 released!
    =========================
    Christine is a small and functional media player written in Python using PyGtk as GUI toolkit and Gstreamer as backend.
    It supports all the media files that your gstreamer installation can support, being MP3, OGG, AVI, MPG. It saves the URIs and Meta tags in a database and let you browse them quickly.
    Christine also provides early support for Radio Stations and have its own DBus interface which let you control christine with your media keyboard buttons as they are configured on GNOME.
    The early access to Plugins will let you tweet the music you are listening to, put it on your pidgin status and use notifications while you change your current song.

    Changes


    • DBus support.

      • Functions:

        • Play
        • Pause
        • Prev
        • Next

      • Signals

        • NewLocation


    • Plugins

      • New Plugins

        • Gnome Media Keys support
        • Album Cover
        • Early acces to getInfo
        • GnomeDBus

      • Improved pidgin configuration dialog

    • Player

      • Support for subtitles
      • Better handle of xvimagesink

    • Misc

      • Faster import
      • 3rd party module that contains libraries developed by others
      • Improved sources UI

    • Bugfixes:

      • Visualization doesn't work with xvimagesink
      • Cannot delete a file from the main library


    As usual, you can get it from sourceforge.net: ]]>
    http://islascruz.org/html/index.php/blog/show/Christine-0.3.0.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine-0.3.0.html Sat, 11 Apr 2009 04:10:30 -0500
    <![CDATA[ Pygtk: About keyboard accelerators ]]> gtk.accelerator_parse to define your accelerator there may be cases where you do not know the tecnical name of the mod, then you can of the key value of the key you are pressing.
    Fortunately Gtk does provide the way to know this values. The next program is a small window where you can know the value of the key you are pressing.
    #!/usr/bin/env python
    import gtk
    import gtk
    def catch_button(window, event, label):
            keyval = event.keyval
            name = gtk.gdk.keyval_name(keyval)
            print event.state
            mod = gtk.accelerator_get_label(keyval,event.state)
            label.set_markup('<span size="xx-large">%s\n%d</span>'% (mod, keyval))
     
     
    window = gtk.Window()
    window.set_size_request(640,480)
    label = gtk.Label()
    label.set_use_markup(True)
    window.connect('key-press-event',catch_button, label)
    window.connect('destroy', gtk.main_quit)
    window.add(label)
    window.show_all()
    gtk.main()
     
    And looks like this:

    GtkKeyCatcher

    In my keyboard the NumLock key makes GTK to set the Mod2 value all the time as in this mail: http://mail.gnome.org/archives/gtk-list/2001-July/msg00153.html
    Anyway, this may give you a clue about what keys you are pressing, but remember, instead of using the key value directly you should use gtk.gkd.keyval_from_name() and pass the name of the key you are trying to use.
    In the next piece of code let you use the "Win" modifier and the F8 key to do something, you should notice that I'm using gtk.gdk functions to get the values.
    def key_catcherself, widget,  event):
            '''
            Maneja los eventos de las ventanas
            '
    ''
            F8 = gtk.gdk.keyval_from_name('F8')
            if os.name != 'posix':
                    superName = gtk.gdk.MOD1_MASK
            else:
                    superName = gtk.gdk.SUPER_MASK
            keyval = event.keyval
            if event.state & superName and keyval == F8:
                    mod = gtk.accelerator_get_label(F8, event.state)
                    print "you have pressed ", mod
     
    ]]>
    http://islascruz.org/html/index.php/blog/show/Pygtk%3A-About-keyboard-accelerators.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Pygtk%3A-About-keyboard-accelerators.html Fri, 10 Apr 2009 22:08:28 -0500
    <![CDATA[ Python: Merge two lists in a single in the less time possible. ]]>
    a = []
    b = []
    for i in range(0,10):
        a.append(i)
        b.append(i)
     
    Then I realize that I was being a fool by creating acouple of lists and then append in every list, the better, copy the list. Copying a list may be done in several ways:
    #Iterating over the list with a for statement
    for i in a:
        b.append(i)
     
    #Copying the data using a list mapping
    b = [k for k in a]
     
    #Using the map function
    map(lambda x: b.append(), a)
     
    But the fastest way is making a slice
    b = a[:]
     
    Then, I append the data to b
    for i in range(10,20):
        b.append(i)
     
    resulting in this:
    a = [0,1,2,3,4,5,6,7,8,9]
    b = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18.19]
     
    Doing this with a small amount data is easy and fast, but with a large amount this will take a bit more time. There is an easy way to append data to the second is this:
    b.append('')
    b[-1:] = range(10,20)
     
    I made a small test and found that iterating over 20000000 takes only 0.2 secs copying the data from the list a into the list b, while iterating using a for statement it takes aprox. 10 secs. This is the code that I use to make the test.
    import time
    added = range(100,20000000)
    a = range(100)
    b = range(100)
    ctime = time.time()
    b.append('')
    b[-1:] = added
    print time.time() - ctime
    ctime = time.time()
    for i in added:
            a.append(i)
    print time.time() - ctime
    print len(a), len(b)
    equals = 'True'
    for index,value in enumerate(a):
            if value != b[index]:
                    print value
                    equals = 'No'
                    break
     
    print "They are the same? ", equals
     
    markuz$ python append_test.py
    0.289237976074
    9.6946041584
    20000000 20000000
    They are the same? True
    markuz$
    ]]>
    http://islascruz.org/html/index.php/blog/show/Python%3A-Merge-two-lists-in-a-single-in-the-less-time-possible..html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Python%3A-Merge-two-lists-in-a-single-in-the-less-time-possible..html Tue, 31 Mar 2009 22:18:32 -0500
    <![CDATA[ Google and the Python performance ]]> Google's Python engineers efford on bringing performance boost on Python. As many of you know, I like a lot this programming language, I do all my work on it. Reading that by the second quarter of 2009 there will be a functionally equivalent replacement for the Python interpreter.
    Python, from my point of view, is a very fast programming language, not only writing on it, but in the tasks that it must do. I know it have its own speed problems inherited by using an interpreter/virtual machine instead native code, but today computers makes building non-ultra-fast programs being written on Python a delightful task. Then, using a more powerfull interpreter will make python a very close to C alternative and many more developers will look on it. ]]>
    http://islascruz.org/html/index.php/blog/show/Google-and-the-Python-performance.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Google-and-the-Python-performance.html Fri, 27 Mar 2009 23:32:03 -0500
    <![CDATA[ Python: Simple HTTP Server on python. ]]> Python have several modules that help you to achieve your goals. This week, on my spare time that is getting every day more scarce I spend time figuring out how to create a Python Web Server, I was planing to use it over an application that I'm developing on ICT Consulting. At the end I didn't use it because I didn't want a "passive" comunication, but probably I will use this code on the CRM Desktop application that we use here.
    Anyway, this code may be helpful for you too. I found that creating a small web server is really simple, It starts getting bigger as you add functions to that web server, but the basis is quite simple.
    import os
    import cgi
    import sys
    from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
    class customHTTPServer(BaseHTTPRequestHandler):
            def do_GET(self):
                    self.send_response(200)
                    self.send_header('Content-type', 'text/html')
                    self.end_headers()
                    self.wfile.write('<HTML><body>Get!</body></HTML>')
                    return
                   
            def do_POST(self):
                    global rootnode
                    ctype,pdict = cgi.parse_header(self.headers.getheader('Content-type'))
                    if ctype == 'multipart/form-data':
                            query = cgi.parse_multipart(self.rfile, pdict)
                    self.send_response(301)
                    self.end_headers()
                    self.wfile.write('Post!')
           
                   
    def main():
            try:
                    server = HTTPServer(('',8080),customHTTPServer)
                    print 'server started at port 8080'
                    server.serve_forever()
            except KeyboardInterrupt:
                    server.socket.close()
    if __name__=='__main__':
            main()
     
    There are two main methods in our small server: do_GET and do_POST, you can figure out what this methods do. Get is quite simple, Post is used to send data to the server, as an example, the file uploading. This is done via POST and many times using "multipat/form-data" as the content type. The Post method here handles that.
    Now that you have a custom server, how can you check it?, well, to check GET you can call it from the web browser. For the POST stuff, you can create a simple web form and using your web browser as "action" on it. However, this code can help you:
    import urllib2
    import urllib
    import time
    import httplib, mimetypes
    HOST = '127.0.0.1'
    PORT = '8080'
    def post_multipart(host, port, selector, fields, files):
            """
            Post fields and files to an http host as multipart/form-data.
            fields is a sequence of (name, value) elements for regular form fields.
            files is a sequence of (name, filename, value) elements for data to be uploaded as files
            Return the server's response page.
            """

            content_type, body = encode_multipart_formdata(fields, files)
            h = httplib.HTTP(host, port)
            h.putrequest('POST', '/cgi-bin/query')
            h.putheader('content-type', content_type)
            h.putheader('content-length', str(len(body)))
            h.endheaders()
            h.send(body)
            #errcode, errmsg, headers = h.getreply()
            h.getreply()
            return h.file.read()
    def encode_multipart_formdata(fields, files):
            """
            fields is a sequence of (name, value) elements for regular form fields.
            files is a sequence of (name, filename, value) elements for data to be uploaded as files
            Return (content_type, body) ready for httplib.HTTP instance
            """

            BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$'
            CRLF = '\r\n'
            L = []
            if fields:
                    for (key, value) in fields:
                            L.append('--' + BOUNDARY)
                            L.append('Content-Disposition: form-data; name="%s"' % key)
                            L.append('')
                            L.append(value)
            if files:
                    for (key, filename, value) in files:
                            L.append('--' + BOUNDARY)
                            L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename))
                            L.append('Content-Type: %s' % get_content_type(filename))
                            L.append('')
                            L.append(value)
            L.append('--' + BOUNDARY + '--')
            L.append('')
            body = CRLF.join(L)
            content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
            return content_type, body
    def get_content_type(filename):
            return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
    def test():
            print  post_multipart(HOST, PORT, 'markuz',
                                            ( ('username','markuz'),  ('another_field','another value')),
                                            (('query','query','Query'), ),
                                       )
    if __name__ == '__main__':     
         test()
     
    ]]>
    http://islascruz.org/html/index.php/blog/show/Python%3A-Simple-HTTP-Server-on-python..html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Python%3A-Simple-HTTP-Server-on-python..html Sat, 21 Mar 2009 03:40:19 -0500
    <![CDATA[ PyGTK: Playing with gtk.GenericCellRenderer ]]> I end by setting the color to the background of the cell renderer using the "background" property. This was better than shoing another column, but still was ugly, because using the background property makes the cells looks splitted.
    Recently, I discover the pygtk's GenericCellrenderer, this cell renderer allows you to implement your very own custom CellRenderer. and then, I could "draw" using Cairo to draw my cell's background. This let me use gradients, or even draw complex images in the background of the cell.

    Playing with GenericCellRenderer

    It's obvious that this is not the only use of the gtk.GenericCellRenderer, you can use it to represend anything you want, being a pixmap, maybe an object, a code bar.. I don't know, that's up to you.
    Creating your own CellRenderer is quite simple, the first you have to do is subclass gtk.GenericCellRenderer, and implement this four methods:
    def on_get_size(widget, cell_area)
    def on_render(window, widget, background_area, cell_area, expose_area, flags)
    def on_activate(event, widget, path, background_area, cell_area, flags)
    def on_start_editing(event, widget, path, background_area, cell_area, flags)
     
    The main methods are on_get_size, that tells the size of the cell, this value is going to be passed to on_render method. The method "on_render" is the one where you are about to work on, since all the "drawing" is made here.
    Just as an example, this is the code I use in the on_render method:
            def on_render(self, window, widget, background_area, cell_area, expose_area, flags):
                    cairo_context = window.cairo_create()
                    x = cell_area.x
                    y = cell_area.y
                    w = cell_area.width
                    h = cell_area.height
                    if x == 0:
                            curve_to = 'start'
                    elif (x + w ) == widget.allocation.width:
                            curve_to = 'end'
                    else:
                            curve_to = None
                    self.render_rect(cairo_context, x, y, w, h, 1, curve_to)
                    pat = cairo.LinearGradient(x, y, x, y + h)
                    color = gtk.gdk.color_parse("#87D8F5")
                    pat.add_color_stop_rgba(
                                                            0.0,
                                                            self.get_cairo_color(color.red),
                                                            self.get_cairo_color(color.green),
                                                            self.get_cairo_color(color.blue),
                                                            1
                                                            )
                    color = gtk.gdk.color_parse(self.get_property('background'))
                    pat.add_color_stop_rgb(
                                                            1.0,
                                                            self.get_cairo_color(color.red),
                                                            self.get_cairo_color(color.green),
                                                            self.get_cairo_color(color.blue)
                                                            )
                    cairo_context.set_source(pat)
                    cairo_context.fill()
                    context = widget.get_pango_context()
                    layout = pango.Layout(context)
                    layout.set_text(self.get_property('text'))
                    layout.set_width(cell_area.width)
                    widget.style.paint_layout(window, gtk.STATE_NORMAL, True,
                                            cell_area, widget, 'footext',
                                            cell_area.x, cell_area.y,
                                            layout)
     
    I already have imported gtk, pango and created some other methods like render_rect, get_cairo_color and the property methods.
    One of the disadvantages I saw is that you can't create a pangocairo context from the CellRenderer, this is because the CellRenderer is not a widget, and doesn't have the create_pango_layout, but you can use the widget.style.paint_layout to write whatever you want.}
    The full code of this is Here ]]>
    http://islascruz.org/html/index.php/blog/show/PyGTK%3A-Playing-with-gtk.GenericCellRenderer.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/PyGTK%3A-Playing-with-gtk.GenericCellRenderer.html Sat, 28 Feb 2009 03:41:48 -0600
    <![CDATA[ Feb 27 2009 ]]> how to for use the regular expressions in vim. ]]> http://islascruz.org/html/index.php/blog/show/Feb-27-2009.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Feb-27-2009.html Fri, 27 Feb 2009 23:20:32 -0600 <![CDATA[ Christine and DBus part II ]]> I also create some functions to allow a small program use this functions (you can see all this in libchristine/christine_dbus/ package).
    Now, I feel the need to create dbus functions for everything.. but it's not possible, so, please, give me a clue about what you want to see in the dbus package.
    I'm about to create several signals, but again, I need your help to create a good enough signal stack. ]]>
    http://islascruz.org/html/index.php/blog/show/Christine-and-DBus-part-II.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine-and-DBus-part-II.html Fri, 13 Feb 2009 00:33:26 -0600
    <![CDATA[ Christine: subtitles. ]]>
    Its alive!

    I was working tonight in subtitles, and fixing a couple of issues in christine :-) ]]>
    http://islascruz.org/html/index.php/blog/show/Christine%3A-subtitles..html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine%3A-subtitles..html Wed, 11 Feb 2009 00:10:40 -0600
    <![CDATA[ MySQL to SQLite ]]> sqlifairy this big and fatty fairy help me to translate my database schema from MySQL to SQLite, and even when this was just the schema was a lot easier than do it by hand. Playing with sqlite I found that I need some kind of console more usable than the command line sqlite, I found sqliteman which is a very good tool that helps you to make querys and see the results in a more readable way, I have to compile it because I found no packages in the Ubuntu repositories. Just have to install qt libraries and qscintilla.
    Doing that migration is quite simple, just do a dump of your database, without data, this is important, because if your dump have all those inserts sqlfairy will check them too, and will take a lot more time.
    mysqldump -u usuario -p database --no-data > database.sql


    Then just use sqlt (the SQL Fairy translator) to translate from MySQL to SQLite
    sqlt -f MySQL -t SQLite dagabse..sql > database.sqlite


    And then, create your sqlite database as usual from an sql file ]]>
    http://islascruz.org/html/index.php/blog/show/MySQL-to-SQLite.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/MySQL-to-SQLite.html Tue, 27 Jan 2009 23:45:21 -0600
    <![CDATA[ Album cover. ]]>


    Christine and album covers from Marco Antonio on Vimeo.
    ]]>
    http://islascruz.org/html/index.php/blog/show/Album-cover..html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Album-cover..html Sat, 24 Jan 2009 11:12:29 -0600
    <![CDATA[ Christine, DBus and Cairo ]]> I have been working tonight trying to create a small notification window for christine, besides we have the PyNotify plugin, I feel this need to try something more. Then I use this great how to create glass like windows and create this:


    Christine, dbus and Cairo from Marco Antonio on Vimeo.

    In the video you'll see the notification window displaying the button I'm pressing in my keyboard to control christine without having christine on focus. The code is already in svn if you want to try. ]]>
    http://islascruz.org/html/index.php/blog/show/Christine%2C-DBus-and-Cairo.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine%2C-DBus-and-Cairo.html Thu, 22 Jan 2009 00:35:26 -0600
    <![CDATA[ More about Christine and dbus ]]>


    Christine and Dbus Part. II from Marco Antonio on Vimeo.
    ]]>
    http://islascruz.org/html/index.php/blog/show/More-about-Christine-and-dbus.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/More-about-Christine-and-dbus.html Mon, 19 Jan 2009 00:01:00 -0600
    <![CDATA[ Christine and DBus ]]>


    I've started coding the DBus interface for christine, is quite simple to use dbus in your scripts, I have just created a few methods just to test the dbus module and it worked just fine. Going to create the other methods, wich should be quite simple, since I have been working in some sort of 'all in one' module.
    The video looks pretty nice on vimeo, I have seen videos with this service and I like a lot the quality, youtube is nice but not the best to show your screencasts, flickr video just allow me 90 seconds of video. I will upload some more videos on my vimeo account :-). Btw.. if you use vimeo and christine, upload your screencast and join the group ]]>
    http://islascruz.org/html/index.php/blog/show/Christine-and-DBus.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine-and-DBus.html Sat, 17 Jan 2009 03:11:55 -0600
    <![CDATA[ This week on Markuz life... ]]> Well, Sunday is my free day, I try to woke up late, but I just can't, I was stand up at 8:30 in the morning. after the breakfast I clean the house and start playing with the acer and go out of the house by the 3 in the noon. Cristina was about to be in the Bus station by the 10 in the night. I can't wait until then. Its horrible that your free day, that day that you usually don't want to pass away I was counting the minutes... horrible.
    Well, after that everything is back to the normal way.
    ICTC finally release the Juvi project. Which is a software development project where almost everybody in the office was involved, not only programmers but people that have to go to the client, document writers, analyst... everyone. The hard work that everyone put is seen by now in a product very very well done. I'm glad to be in such a great team!.
    To test the desktop application for Juvi, I have to use a virtual machine, this virtual machine runs Windows XP and I have knowledge that my programs written in Python runs fine on Windows XP and WIndows 2k using py2exe but I didn't make a test under Windows Vista. We made that test yesterday and the application runs smooth!, I have to change nothing! the same installer for Windows 2K to Windows Vista that's good when you have to make the builds.
    On the other way... I have been working on christine just a bit, I have fixed some small issues and there will be dbus support for christine soon garaged convince me some time ago that using dbus is good for christine, in this way, many programs can make use of christine functionality by communicating with it using dbus. Another thing that I'd like to implement is the keyboard shortcuts what allow me to use the prev, next, stop and play/pause buttons but I don't know if it's better to use the GNOME ones os allow the user to define their owns.
    As an extra-time-consuming little project.. I was wondering how to make a Dialog windows appears as the Mac OS X do. Personally I think MacOS X user interface is one of the most polished UI in the world and the Dialog box are pretty and make me feel that this is not another window in the workspace but a window that is really a child of the window where I was working on. Currently I'm thinking on a window with no decoration and a gtk.Layout area making the animation with a button. Let's see if I can have time for this in the week. ]]>
    http://islascruz.org/html/index.php/blog/show/This-week-on-Markuz-life....html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/This-week-on-Markuz-life....html Wed, 14 Jan 2009 23:13:19 -0600
    <![CDATA[ An easy one. ]]> I have two ways to iterate over sequence with a simple filter, one is making a filtered list and store it in a variable, then iterate over that filtered list, the second is put the mapping list in the for statement. Which one is faster and why?
    TIMES = 10000
    a = xrange(10000)
    c = [k for k in a if (k % 2) == 0]
    #
    def iterate(c):
        for i in c:
            pass
         
    def mapea():
        for i in [k for k in a if (k % 2) == 0]:
            pass
    #
    for i in xrange(TIMES):
        iterate(c)
    #
    for i in xrange(TIMES):
        mapea()
     
    100 points for the first comment with the right answer.
    Update: Zodman wins (even when he is not a python newbie)... the iterate function is making just one iteration over a list with the filterered items, the second (mapea) is creating this filtered list in every iteration, so, mapea uses two for cycles and that's why it is slower. ]]>
    http://islascruz.org/html/index.php/blog/show/An-easy-one..html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/An-easy-one..html Fri, 19 Dec 2008 23:54:33 -0600
    <![CDATA[ Christine 0.2.1 ]]> As usual you may download from sourceforge.net, this are the links: ]]> http://islascruz.org/html/index.php/blog/show/Christine-0.2.1.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine-0.2.1.html Thu, 18 Dec 2008 20:32:15 -0600 <![CDATA[ Christine 0.2.0 ]]> Im proud to announce the release of Christine 0.2.0. I have been working with it for several weeks and after fixing some bugs reported I feel it quite stable to be used for everyone.
    What's the new?
    • This version makes use of the sqlite3 python module to store info in a SQLite 3 database file.
    • The item lists have been reworked and now they are faster than ever.
    • We have early support for plugins :-)
    • Re worked TreeModel wich makes christine load faster
    • gconf dependency is removed.
    • Notify bubbles and TrayIcon are now plugins easy to be enabled/disabled.
    • Plugin for Pidgin.
    • Plugin for twitter (for those that want to tweet their songs)
    Where can I have it? Thank you to everyone who contribuite with this release, bug submitters, patch submitters, packagers and users. ]]>
    http://islascruz.org/html/index.php/blog/show/Christine-0.2.0.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine-0.2.0.html Sun, 07 Dec 2008 01:37:22 -0600
    <![CDATA[ Debugging with pydev ]]>


    My first attempt to create video tutorials :-) ]]>
    http://islascruz.org/html/index.php/blog/show/Debugging-with-pydev.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Debugging-with-pydev.html Fri, 05 Dec 2008 17:52:43 -0600
    <![CDATA[ Python 3000 ]]>


    Yeap.. Python 3000 or Py3k hit the streets. I'm more than glade to hear about the new version of this powerfull programming language. It seems that was yesterday when I watch a video where Guido Van Rossum was talking about the propossal for this new version and excusing the lack of compatiblity with the 2.x python series.
    I like the idea that this language is evolving even with this move (which for me is too risky) where we are going to be forced to modify our programs if we want in the future be compatible with Python. ]]>
    http://islascruz.org/html/index.php/blog/show/Python-3000.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Python-3000.html Thu, 04 Dec 2008 23:58:03 -0600
    <![CDATA[ Just a few extra minutes ]]>


    Relativity.. you bitch! ]]>
    http://islascruz.org/html/index.php/blog/show/Just-a-few-extra-minutes.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Just-a-few-extra-minutes.html Thu, 04 Dec 2008 19:34:27 -0600
    <![CDATA[ Python Logging: RotatingFileHandler ]]> Whenever you write a computer program that is going be a service is recommended that this program saves somewhere what is doing, most of the popular services do it (Apache, Cherokee, MySQL, Put your service here:___________________), or maybe you have a desktop application where you want to write what is doing maybe for debug purposes.
    Fortunately this is an easy task if you use Python's Logging module. This module have several handlers, some of them to write to the standardError, to a Socket, to the syslog and many others
    One of my favorite handler is the
    RotatingFileHandler This module creates a log file, when this file is full (if you set the maximum bytes per file flag) it is renamed, appending the .1 and a new file is created with the same name as main log file. You can set up the max number of files to be created.
    This module (logging) is good, easy to use, but you have to use the RotatingFileHandler with care, or you will have two, three or more files being filled and then, your logs will be in N files..
    When you create your Logger Object you can set the log level, which can be INFO, WARNING, DEBUG, ERROR, CRITICAL and EXCEPTION, you already realized which level prints what. You can set the Handler, and this is where using the RotatingFileHandler becomes a bit trickier.
    In your applications you may want to have several loggers, one for each module you have in your application. If you plan to use the RotatingFileHandler you have to use the same handler for every Logger you are creating if you plan this Logger to use the same file. If you don't do this then you will end with something saving logs in your main file, and every other data will be stored somewhere else.
    This is because when you try to save a something in your log, the handler check the log size, and if the file size is >= maxbytes makes the rollover, if you are using several handlers related to the same file, then the handler that realize first that the size of the log file reach its max size will do the rollover but this will not take effect in the other handlers, so, one handler will be logging in the newly created file while the others will be logging to the old file and now you have two files growing.
    To avoid this, just use the same fucking handler for every logger you are creating if you plan to use the same file.
    Another issue I face with logger what the fact that if you call two time s to the same logger.. I mean:
    a = logging.getLogger('chanchanchan')
    b = logging.getLogger('chanchanchan')
    When you make something like this:
    a.info('This is a test')
    You'll se this:
    This is a test
    This is a test
    Yes, you are calling a to write "This is a test" but in your log file appears two times (or N times you have created a logger with the same name). So, its better for you to have something like a manager that gives you the logger already created with that name if exists or create it for you.
    Let's do an example:
    This is a small program that logs something in a endless cycle:
    #!/usr/bin/env python
    # -*- encoding: latin-1 -*-
    import sys
    import time
    from logger1 import LoggerManager
    a = LoggerManager().getLogger('a')
    b = LoggerManager().getLogger('b')
    c = LoggerManager().getLogger('c')

    while 1:
            t = time.time()
            for index,i in enumerate((a,b,c)):
                    msg = str(index) + repr(t)
                    i.debug(msg)
                    time.sleep(0.005)
     
    And this is the logger class, singleton module can be downloaded from Here
    #!/usr/bin/env python
    import logging
    import logging.handlers
    from Singleton import Singleton
    import os
    if os.name == 'nt':
            LOGPATH = 'C:\\'
    else:
            LOGPATH = './'
    class LoggerManager(Singleton):
            def __init__(self):
                    self.loggers = {}
                    formatter = logging.Formatter('%(asctime)s:%(levelname)-8s:%(name)-10s:%(lineno)4s: %(message)-80s')
                    level = 'DEBUG'
                    nlevel = getattr(logging, level, None)
                    if nlevel != None:
                            self.LOGGING_MODE = nlevel
                    else:
                            self.LOGGING_MODE = logging.DEBUG
                    self.LOGGING_HANDLER = logging.handlers.RotatingFileHandler(
                                            os.path.join(LOGPATH, 'log_event.log'),'a',524288, 10)
                    self.ERROR_HANDLER = logging.handlers.RotatingFileHandler(
                                            os.path.join(LOGPATH,'log_error.log'),'a',524288, 10)
                    self.LOGGING_HANDLER.setFormatter(formatter)
                    self.LOGGING_HANDLER.setLevel(self.LOGGING_MODE)
           
            def getLogger(self, loggername):
                    if not self.loggers.has_key(loggername):
                            logger = Logger(loggername,
                                            logging_handler= self.LOGGING_HANDLER,
                                            error_handler = self.ERROR_HANDLER,
                                            logging_mode = self.LOGGING_MODE)
                            self.loggers[loggername] = logger
                    return self.loggers[loggername]
    class Logger:
            '''
            Implements the christine logging facility.
            '
    ''
            def __init__(self, loggername, type = 'event', logging_handler= '', error_handler = '', logging_mode = ''):
                    '''
                    Constructor, construye una clase de logger.
                   
                    @param loggername: Nombre que el logger tendra.
                    @param type: Tipo de logger. Los valores disponibles son : event y error
                                            por defecto apunta a event. En caso de utilizarse otro
                                            que no sea event o error se apuntara a event.
                    '
    ''
                    # Creating two logger, one for the info, debug and warnings and
                    #other for errors, criticals and exceptions
                    self.__Logger = logging.getLogger(loggername)
                    self.__ErrorLogger = logging.getLogger('Error'+ loggername)
                    # Setting Logger properties
                    self.__Logger.addHandler(logging_handler)
                    self.__Logger.setLevel(logging_mode)
                    self.__ErrorLogger.addHandler(error_handler)
                    self.__ErrorLogger.setLevel(logging_mode)
                    self.info = self.__Logger.info
                    self.debug = self.__Logger.debug
                    self.warning = self.__Logger.warning
                   
                    self.critical = self.__ErrorLogger.critical
                    self.error = self.__ErrorLogger.error
                    self.exception = self.__ErrorLogger.exception
     
    I hope this help you. ]]>
    http://islascruz.org/html/index.php/blog/show/Python-Logging.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Python-Logging.html Tue, 02 Dec 2008 22:30:22 -0600
    <![CDATA[ Christine 0.2.0 alpha ]]> 7 months ago I make the 0.1.6 release of Christine media player. The project continues working on my free time and the free time of some friends. I'd like to work more on it but I just don't have all that time, and wait until everything gets perfect will take a lot. So I'm giving to the christine users the 0.2.0 alpha version. I have been using this "version" a couple weeks ago and seems to be working fine, but I'd like you to check it and report everything you find wrong in it. There are source packages in bz2 and gz and a .deb package for Ubuntu Intrepid.
    This release include the SQite3 as data storage engine, the drop of gconf dependency, early support for plugins and more optimizations that make christine load and work faster.
    C'mon, go and Get it!. ]]>
    http://islascruz.org/html/index.php/blog/show/Christine-0.2.0-alpha.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine-0.2.0-alpha.html Wed, 26 Nov 2008 22:39:52 -0600
    <![CDATA[ Call for testers and translators ]]> christine release, the christine development team have been working on improving christine, and think it is time to make a new release, but before, we want you to test it and report every single fail you detect. We also make use of launchpad's translation page.
    You can find the code Here, the page for tracking bugs is Here, and the translations are Here. ]]> http://islascruz.org/html/index.php/blog/show/Call-for-testers-and-translators.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Call-for-testers-and-translators.html Fri, 21 Nov 2008 01:30:11 -0600 <![CDATA[ Netbeans 6.5 ]]> Netbeans 6.5 release shows an Early Access Netbeans IDE for Python ]]> http://islascruz.org/html/index.php/blog/show/Netbeans-6.5.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Netbeans-6.5.html Thu, 20 Nov 2008 13:24:48 -0600 <![CDATA[ What's your favorite programmer cartoon? ]]>

    What's your favorite programmer cartoon? ]]> http://islascruz.org/html/index.php/blog/show/What%27s-your-favorite-programmer-cartoon%3F.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/What%27s-your-favorite-programmer-cartoon%3F.html Wed, 19 Nov 2008 23:57:15 -0600 <![CDATA[ 2008-11-16 ]]> In this week I have been pretty busy, bugfixing the Juvi desktop application. We don't want Banana products (those that mature with the user) and the test team is doing their best to hit every bug and report it to have a very stable application.
    I have been also busy "porting" the Supramax Evo4 driver to run on windows, the port is quite easy to do since the program was written in Python and I have to fix some paths. In my tests I was doing to the driver I found a Not so funny issue with M2Crypto for MS Windows.
    We have a parameter in the driver, as most Unix programs do the "-v" do a verbose run, spitting to the stdout the logs, if you don't use the verbose parameter then it saves it somewhere. Well, running on verbose mode was easy, it just run perfectly, storing the logs wasn't I had an error with OpenSSL... but wait.. we where talking about logs and not about OpenSSL.. what does OpenSSL has to be with logs?.
    Well, there is an issue with M2Crypto and Python where it doesn't ship a special file and this causes OpenSSL crash if you use I/O. M2Crypto let you load a RSA key in pem format that you can use to crypt/decrypt something this method is called load_key and is part of the M2Crypto's RSA package, you only have to pass the path to the key as first argument and in the second argument a function (anything callable) that returns the password for the key (if it is private). Well, this I/O was crashing M2Crypto.
    There are two workarrounds for this. The first, is to compile at least M2Crypto (I didn't do it, some blogs says that you have to compile python) against OpenSSL and include this specific file... at least Google points to blogs that says that... The other and easier way is just use RSA's function load_key_string where you pass as first argument the string that holds the key instead the path, doing this you will eliminate the I/O done by OpenSSL and then, there is no crash.
    Last Thursday Cristina and I went to Maquiavelo's house to an informal meeting with xbitcarry, unfortunately Maquiavelo was too busy and the meeting wasn't really done but was nice to see xbitcarry again.
    I think that's all for today my readers. Fortunately I don't have to work tomorrow and now I have to work a bit on christine ]]>
    http://islascruz.org/html/index.php/blog/show/2008-11-16.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/2008-11-16.html Sun, 16 Nov 2008 23:08:00 -0600
    <![CDATA[ Playing with gtk.Calendar ]]>

    I'm writing a desktop application for ICTC where the user must select a day in in a calendar. I start using gtk.Calendar because is an easy to use Calendar widget, but I this program also have to set the days available for the user to pick.
    I didn't find this on the gtk.Calendar widget, but tought it may be easy to do by subclassing gtk.Calendar. And here is my first approximation:
    #!/usr/bin/env python
    import gtk
    import calendar

    class Calendar(gtk.Calendar):
            def __init__(self):
                    gtk.Calendar.__init__(self)
                    self.available_days = ()
                    self.last_selected_day =  None
                    self.connect('day-selected', self.__check_day_available)
                    self.connect('map', lambda *args: self.__set_available_days())
                   
           
            def set_available_days(self, *args):
                    '
                    Let you set the days availables on the month
                    @args: days to be used.
                    '

                    nargs = [k for k in args if isinstance(k, int)]
                    self.available_days = tuple(nargs)
            def __check_day_available(self, calendar):
                    '
                    Check if the selected day is available, if not,then
                    try to select the last available day selected, and if can'
    t
                    then select the first available day in the available_days list
                    '
                    day = self.get_property('
    day')
                    if not day in self.available_days:
                            nday = False
                            if self.last_selected_day:
                                    nday = self.last_selected_day
                            elif self.available_days:
                                    nday = self.available_days[0]
                            if nday:
                                    self.select_day(nday)
                    print self.get_date()
           
            def __set_available_days(self):
                    '

                    Set a range of days that are not going to be marked and thus,
                    free days for the user.
                    '
                    if not self.available_days:
                             self.set_sensitive(False)
                    month = self.get_property('
    month')
                    days = calendar.mdays[month]
                    for i in range(1,days+1):
                            if not i in self.available_days:
                                    self.mark_day(i)
                    #Force the calendar to select the first day available
                    day = self.get_property('
    day')
                    self.select_day(day)
    if __name__ == '
    __main__':
            window = gtk.Window()
            window.connect('
    destroy', gtk.main_quit)
            a = Calendar()
            a.set_available_days(1,2,3,5,8,13,21)
            window.add(a)
            window.show_all()
            gtk.main()
    Update: Syntax Highlight sucks and change the code to a simple "pre" tag
    Update: returned to Syntax highlight. in Jaws 0.8.6 is working fine again :-) ]]>
    http://islascruz.org/html/index.php/blog/show/Playing-with-gtk.Calendar.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Playing-with-gtk.Calendar.html Fri, 17 Oct 2008 01:37:36 -0500
    <![CDATA[ 2008 10 08 ]]> So, it is time to post again.. this time is to post about christine. Christine as many of you know is a small project of mine, it must be an easy to use and small (and cute) media player, It start as some gstreamer play and then it becomes the music player I use for my every day, no longer rhythmbox nor banshee, wich are fine, but, not for me.
    The project is slow, mostly because I code on it when I need something else or just want to fix something that don't like me. Why? because I get almost no feedback. So, if you use christine or, you want to see this project to grow up, please, test it and fill bugs or request features so we can work on it or maybe you want to cooperate with this project in another way, like writing documents, doing artwork or something like that.
    The last two weeks GaRaGeD have been working on christine too, on the Pidgin "plugin" which is a nice plugin and I have been doing my work too. This makes me fell good, when you are not the only one in the project it feels better, when you can discuss some point to other project mates and know what would be the better for the average user.

    pidgin and christine

    Well, I'm working on the plugin interface and in the last.fm plugin for christine, I already have the authorization part, and then create the configuration dialog for the plugin, this requires me to get familiar with last.fm but, if you already use last.fm and want some feature that you already have in another player, please comment here or on the feature request tracker for the christine project.
    On the paid work side, I have been working a lot with Gtk, and reading about the Human Interface Guidelines, have you noted that the GNOME Human Interface Guidelines are quite similar to the Apple Human Interface Guidelines. Well, I hope this helps me to create more intuitive and very usable gtk interfaces.
    On the personal side. Cristina and I are really happy, last friday we went to the gynecologist and we see our baby, he is three months right and everything looks right. I have nothing more to say, Im happy!
    Just to close this post, if you use mac or compiz, how does looks likeyour desktop right now using the Exposé or the Scale plugin on compiz

    Desktop
    ]]>
    http://islascruz.org/html/index.php/blog/show/2008-10-08.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/2008-10-08.html Wed, 08 Oct 2008 02:03:00 -0500
    <![CDATA[ Tweeting the song from christine ]]>



    Tweeting the song from christine, originally uploaded by markuz.

    Inspired by GaRaGeD's pidgin "plugin" (christine still doesn't have a plugin API), I wrote my "plugin" to tweet the song on being played on christine.

    ]]>
    http://islascruz.org/html/index.php/blog/show/Tweetingthesongfromchristine.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Tweetingthesongfromchristine.html Sat, 04 Oct 2008 00:03:49 -0500
    <![CDATA[ Asi es la vida de un desarrollador... ]]>



    Visto en el blog de Kraxbox ]]>
    http://islascruz.org/html/index.php/blog/show/Asi-es-la-vida-de-un-desarrollador.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Asi-es-la-vida-de-un-desarrollador.html Thu, 02 Oct 2008 13:18:36 -0500
    <![CDATA[ About my life ]]> Well, I think you just don't care abot my life, is quite boring for everyone that is not me. Why? just because this is not the blog of some kind of nerdy hacker that do lot of shiny new and amazing stuff, nor the guy that post every single fart that Apple, ubuntu nor Microsoft does.
    So, what is about this blog? I think is a way to flush my mind. I wish I have all the time to write more posts, Several times I had Ideas to be written in the blog, but they didn't come to the blog because (again) there is no time.
    Anyway, three paragraphs are enough for my complaints. So, what have I done since my last Post? (the christine love, the picture is not..a post) Well, let me see... let me see... Lot of work. I have been working on this project on ICTC, a desktop application using Python and PyGtk.
    User interface design is a quite interesting challenge, and more if you need to design input forms, make them look good, being user friendly (mmm, user friendly... If user friendly means scratching the testicles {or your favorite scratch part of the body} of the users. This application in some forms, need to be fully functional without mouse and use only the key pad, which makes the challenge more interesting. Writing a form that makes input validation, key-press-event handling for every widget, looks good, be ultra-easy to use is... is sometimes castrating... (the more if the client want the application in this color: #FF00FF.)
    Obviously I don't have to see the application in that color, but I also have to write a color chooser for this application, if I don't, then the client is going to ask me to change the colors after 15 days using the program or when it get almost blind.
    Well. This is most of the work I have done, I'm trying to learn how to use django. I love python, and I want to use django (or another python based framework) to write web applications in the future. I have write some applications but nothing really functional by now. One of the first and small projects I want to do is a web page for christine.
    And talking about christine, I'm still working on the new version. I'm refactoring modules. And by now is quite usefull. Just commit this night fixes for the bug #2122313 but I need people to test it to check it is working fine. I have also fixed the open remote dialog that wasn't working since I reallocate this methods.
    Well, I thinks is enough for today. See you latter.
    Update I forgot, If you like the season 1 of The Big Bang Theory you can the download links from Here, those rar files don't have the subtitles, I will post them there too. I have been watching this tv serie and I love it. ]]>
    http://islascruz.org/html/index.php/blog/show/Aboutmylife.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Aboutmylife.html Fri, 26 Sep 2008 02:30:19 -0500
    <![CDATA[ Giving love to christine ]]>



    Giving love to christine, originally uploaded by markuz.

    This is my desktop testing some changes I have done to christine in this night. Most of them code cleaning and some harmless optimizations.

    Update: I have made a screencast, you can download it


    here


    Update: Maybe you want to see the full resolution video ]]>
    http://islascruz.org/html/index.php/blog/show/Givinglovetochristine.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Givinglovetochristine.html Fri, 12 Sep 2008 00:52:54 -0500
    <![CDATA[ HotKeys on Windows using Python ]]> One of challenges for me in this application is that as it must run in the background there must be a way to raise it, the most easy way to do it is by force the user to click on the small icon in the notification area, but in this case, that was impossible because the computer don't have any mouse, everything is done with the keyboard.
    So, I start googling for some way to use hot keys with GTK (PyGtk) in this case, I found that Gtk does have a way to represent the Display wich a way to get to your computer display resources. I just want to grab the keyboard presses and if the right key with the right modifier where pressed then the application arises.
    Unfortunely for me, Gtk+ does have a way to do this, but the implementation in PyGTK has a bug where all the display events are ignored, I mean, every time you check of a pending event for the display pygtk will return None, so, no event, no catch, no working code.
    Well, in linux you can do this by using the xlib bindings for python, but I have to do this on Windows, so a workmate point me to
    This url. Wich shows how to register a hot key on windows.
    That was easier than I thought!. But, there is a trick... As you can see in this piece of code:
    try:
      msg = wintypes.MSG ()
      while user32.GetMessageA (byref (msg), None, 0, 0) != 0:
        if msg.message == win32con.WM_HOTKEY:
          action_to_take = HOTKEY_ACTIONS.get (msg.wParam)
          if action_to_take:
            action_to_take ()
        user32.TranslateMessage (byref (msg))
        user32.DispatchMessageA (byref (msg))
     
    The method GetMessageA is the one that is listening to the messages in the system, and returns when there is a message. If you use a single threaded program, like... some text bassed application or just a "show something" application, then it will be nice, but, if you use Gtk, where the application's events are handled in the gtk main loop this is useless, why? because this method locks until it receives something, and then let your application work, but, if you have it in a while loop you will never leave that loop and then, your signals will never been emited and your handler will never do their job. Is something similar to the use of sockets. Ha... I forgot, you can't use the while gtk.events_pending(): gtk.main_iteration_do() stuff.. it doesn't work, keep reading if you wanna know why.
    So, what can I do for this to work?, well, I thought: A thread, but, there is a problem. Windows documentation says that the hotkey registerd with the method RegisterHotKey will only be catched with GetMessageA if the "register" method and the "get message" are in the same thread.
    So, what can I do? Put this on the same thread, and then use a flag to let the rest of your application know that the keys have been pressed, then, raise your application. But, why I can't make a gobject based class that emits a signal when this keys are pressed? Well, you should know that Gtk+ is thread aware, but not thread safe, this means, you cannot use Gtk accross the threads, and this is something inherited from gobject (AFAIK).
    Here's the code that will let you register hot keys on windows and make your applications raise when you need them.
    #!/usr/bin/env python
    import ctypes
    import thread
    import win32con
    import gobject
    from ctypes import wintypes
    class keyhandler:
            def __init__(self):
                    self.__emit = False
                    thread.start_new_thread(self.__catchMsgs, tuple())
                    gobject.timeout_add(5,self.checkEmit)
           
            def checkEmit(self):
                    if self.__emit:
                            self.emit('keyhandler-keypress',self,self.__emit)
                            print 'Emitiendo senial..'
                            self.__emit = False
                    return True
            def __catchMsgs(self, *args):
                    byref = ctypes.byref
                    user32 = ctypes.windll.user32
                    self.HOTKEYS[1] = {'hotkey' : win32con.VK_F3,'modifiers': win32con.MOD_WIN}
                    if not user32.RegisterHotKey (None, 1, win32con.MOD_WIN, win32con.VK_F3):
                            print "Unable to register id", 1
                    while 1:
                            try:
                                    msg = wintypes.MSG()
                                    if user32.GetMessageA (byref (msg), None, 0, 0):
                                            if msg.message == win32con.WM_HOTKEY:
                                                    if self.HOTKEYS.has_key(msg.wParam):
                                                            self.__emit = self.HOTKEYS[msg.wParam]
                                            user32.TranslateMessage (byref (msg))
                                            user32.DispatchMessageA (byref (msg))
                            except:
                                    pass
     
    ]]> http://islascruz.org/html/index.php/blog/show/HotKeysonWindows.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/HotKeysonWindows.html Wed, 10 Sep 2008 01:03:05 -0500 <![CDATA[ Christine folder import ]]> .flickr-photo { border: solid 2px #000000; } .flickr-yourcomment { } .flickr-frame { text-align: left; padding: 3px; } .flickr-caption { font-size: 0.8em; margin-top: 0px; }



    christine, originally uploaded by markuz.

    This is christine (trunk) importing a whole folder, about 1321 songs in just 1:07 mins.

    ]]>
    http://islascruz.org/html/index.php/blog/show/christine-1.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/christine-1.html Tue, 09 Sep 2008 16:27:34 -0500
    <![CDATA[ Christine using 6Mb ]]>



    screenshot3.png, originally uploaded by markuz.

    This is a screenshot quite surprising for me, this is the gnome-system-monitor saying that christine uses just 6Mb of my RAM. I was looking for memory leaks in one of the applications that I'm currently developing in ICT Consulting, and I found that the memory used by one program, that memory that just belongs to the program is the Writeable memory and that is the memory you should be aware.
    I have to say, christine was doing nothing, Just launch it and listen some music, then for one reason that I don't remember, just set it to pause and I get over another task, now, looking at the process table, christine is using more thatn 6 Mb.
    btw.. Im using Christine 0.1.6.

    ]]>
    http://islascruz.org/html/index.php/blog/show/Christineusing6Mb.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christineusing6Mb.html Sun, 17 Aug 2008 23:00:26 -0500
    <![CDATA[ WTF! Recursive errors. ]]>



    wtf !, originally uploaded by markuz.

    An internal error ocurred while showing an internal error.

    Update:
    @shakaran: In Eclipse 3.4, trying to install some components. ]]>
    http://islascruz.org/html/index.php/blog/show/wtfrecursiveerrors.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/wtfrecursiveerrors.html Wed, 06 Aug 2008 16:27:32 -0500
    <![CDATA[ Christine in launchpad ]]> sourceforge.net si no longer maintained, the reason: I cannot commit my changes to the svn repo, then, I cannot share the newest code.
    Christine is now a registered project in Launchpad, well, christine has been a in launchpad for a while but never really use it. So, I will use the launchpad christine account. The bug tracker, the code (and all the good things that launchpad offers) will be hosted here.
    As part of the change, christine no longer use Subversion, instead, will use Bazaar, you can get the code using this:
    bzr branch lp:christine ]]>
    http://islascruz.org/html/index.php/blog/show/Christineinlaunchpad.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christineinlaunchpad.html Sun, 03 Aug 2008 10:56:51 -0500
    <![CDATA[ Christine love in the night ]]>



    Christine love in the night, originally uploaded by markuz.

    1:47 in the morning. Im still giving some love to christine, that personal proyect that I used to code frequently. Now, it takes some days before I can toch it.
    I'm working on the sqlite3 storage layer, This should help me with a more unified data between multiple "sources" that should be renamed as playlists. This will be usefull for many other features, I'm thinkin in some kind of browser.
    Anyway, I'm still in the process. I'd like to share the code I have, but SourceForge.net's SVN service is bothering me with a 403 (Forbidden) error that don't let me commit my changes. Now I'm seriously change the project host. What do you recommend?

    ]]>
    http://islascruz.org/html/index.php/blog/show/Christineloveinthenight.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christineloveinthenight.html Thu, 24 Jul 2008 01:57:45 -0500
    <![CDATA[ GNOME 3.0 (Everything with tabs) == Suck! ]]> I believe that GNOME as a project is a very great project, event with the fact that they are reinveing the wheel from time to time (galeon, epiphany => epiphany webkit?). Anyway, I think it's great and as desktop is great too. I use GNOME in my every day and most of the time I'm quite happy, c'mon, there is no desktop environment that have everythin that every user could need.
    I love most of the applications that GNOME has as desktop and many others that are not part of the Desktop but integrates well with it. I use such applications because they solve at least one of my problems, being something for my work or just my day to day computer use, and in most of the cases they solve that problem in a very good way, making me feel like I own my computer. But, I also think that they should evolve to be better.
    In latest posts on http://planet.gnome.org/ I have seen several posts about some projects that want have tabs everywhere, which for me is ridiculous, Not every application must have tabs. One example is the totem at least not in the way Wouter Bolsterlee is showing it. Another application that I think should not is the calculator. Nautilus is nice for me because it may improve the user's workflow, but does anyone plays two items at the same time?.
    Another UGLY example is what Davyd Madeley proposes to the GNOME panel, he may have some point while some people don't know "...what the little grey and blue boxes on their panel are for..." But the users are not stupid, they click them and will know that are they for. And.. a panel with tabs is just UGLY uses more space and useleses (I don't use the workspace switcher applet... is useles at least for me).
    I Hope the GNOME developers reconsider where they should or not use tabs in the applications. And if they are going to do that.. Christian Neumair. ]]>
    http://islascruz.org/html/index.php/blog/show/GNOME30EverythingwithtabsSuck.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/GNOME30EverythingwithtabsSuck.html Sun, 13 Jul 2008 14:48:58 -0500
    <![CDATA[ Christine importing a folder. ]]>


    Christine importing a folder., originally uploaded by markuz.

    I had worked on christine weeks ago, this week I had no time to give it some love. I have been using this "development" version (I think every version of christine is a development version) for a while.
    Christine is faster at the load time, starting in just 4 seconds with at least 1500 items in the list, and the search and sort is quite fast too. But working with something like 6889 items in another 'source' I had make it a bit slow.
    I think this is because christine use 3 models in the main list. Yes, three models. One is the main model, the one that holds all the library data. then the filter model and then the sort model. I'll try to make a model that implements in some way the filter and sort to reduce the work.
    I notice that when you use a filter or even worse a filter and sort model ever time you select or move your cursor, or do anything with a row this process has to be done for every model you have. I mean, in christine you have to do it three times because of the three models. I think this sucks.
    Well, I hope to have the time to write a bit on christine in this week.

    ]]>
    http://islascruz.org/html/index.php/blog/show/Christineimportingafolder.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christineimportingafolder.html Thu, 26 Jun 2008 23:19:17 -0500
    <![CDATA[ What have I done in the last month ?? ]]> com, and that's ok. Anyway, islascruz.org is back again and I hope it never fails again.



    Now, What have I done in the last month?, well, not blogging :-P. I have been using twitter but I had this need to post on my own site.



    I had worked on christine, making it a little more usable, now,it loads in my computer in just a couple of seconds with a track list that is about 2600 rows, It uses a little less memory and I'm trying to make it better. But I'm working in some projects in the work (the paid work) and the idea to be working 8 hours in the office and get to the house to keep working isn't a very nice idea.




    Christine in small view mode




    dsc08103.jpgCristina and I get to the movies, we watch The Happening. Many people didn't like it, and I think this is because there is too much talk, too much death and almost no action. But the point in the movie is the message, we are hurting the planet, and we shouldn't. So, after the blablabla and the blood I like it, just by the message. We also watch Indiana Jones, and to be honest, I like it, but is not by far the most awesome movie I have seen.



    As part of the "Leave the stress" activities cristina and I are doing, we are doing scented candles. We enjoy doing it, but the hard issue is cleaning the mess we do.



    Well, I think I'm gonna leave this post here, my life is not that intersting. You should read somebody else personal posts.. ]]>
    http://islascruz.org/html/index.php/blog/show/WhathaveIdoneinthelastmonth.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/WhathaveIdoneinthelastmonth.html Wed, 18 Jun 2008 19:16:51 -0500
    <![CDATA[ Creating a gtk custom model ]]> ICT Consulting. We found a problem with many many rows in gtk.ListStore. This is a common problem with Gtk's ListStore and TreeStore. Both are easy to implement and convenient if you are not going to work with too many values. I'm thinking in a couple of thousands. As far as this, the TreeModel is quite usable, but if you use a TreeFilterModel and/or TreeModelSort then you will experience some performance issues.



    If what you want to do is just map the main application and then fill the model you can use the idle_add gobject function to iterate over your data and then store it in your model without freezing your application, but it is at the same way, the slowest. You can put chunks of 20 or so, then every time you application runs the callback function will run a small but faster insertion. Anyway, this is still a bit slow.



    I have been doing tests with 100,000 rows, in the easy way there are just numbers using a for cycle via a range() result.I think in Gtk, the smaller is the data stored in the model, the faster it goes, because I can insert 100,000 rows in a gtk.ListStore in 7 seconds aprox. while in christine, inserting 2600 row in christine (with more data per cell) takes a lot more.



    Anyway, the application that I'm developing shows a list of customers, this is a growing list as new customers are added, in our tests we need to show up to 17,000 customers. Using gtk.ListStore takes at least 17 seconds on my machine just to show it, but we also have a filter model becuse search in a list of 17000 items is not easy if you go looking every row by hand. So, usig the FilterModel takes almost the same time in searching something. Obviusly, waiting 17 seconds for the result is not an option, even worse, you made a mistake and wrote LOPEX instead LOPEZ.



    So, I was searching over internet what can I do. I have already use the common 'tweaks' to improve the gtk.ListStore performance and I have reached the 8 - 9 seconds over those 17,000 items, but even with this, its too much time. The search points me to the gtk.GenericTreeModel. This generic model allows you to create a custom model where you can make your own tweaks to improve the performance of your model. In the link above gives you the way to use it. I have alreade created my own custom model and it really relly made the things better.



    Now, one of the problems that gtk.GenericTreeModel have are the memory leaks. Using this model you may use lots of memory. This is because the GTM use to create a reference to the value that you are returning as Iter, e.g. you are using a list of lists, where you store the values, every item in the list is a row, then, the index if the iter wich references to the list you are storing in that row. The problem is that the GTM increase the reference count of you node (the list inside of the list) to aviod row destruction and then use the iter. This, in the best will make your values been refered until you destroy your model (and any reference to the data), in the worse the reference count of your data will never been unrefered and then the memory will never be freed.



    You can use the invalidate_iters every time you modify the rows (add or delete) to make the rows invalid and then decrease the reference count of the row, and when your data have no more references then be deleted. But, I have the problem that the reference count was never decreased when I destroy the window or the model. Where is the trick here, use the Python's garbage collector, and your memory will be freed.



    So, the new model based on PyGtk's GenericTreeModel actually works for us. Inserting 17,000 takes just 1 second, and the search (filter) is the same thing, 1 second is an option. I would like to see everything just appear when you request it, but one second is good for now. And testing with my current christine music list it takes just 0.06 seconds to show the list. Inserting 100,000 items (the easy way, just numbers) takes just 1.164 seconds to get filled with four columns and 2.36 seconds to show itself (creating a filter model and setting it to a treeview), so, for now this kind of optimizations will work for us, there are other optimizations on the Filter model and the treeview, My goal is to create something similar to wat Aaron bockover do with banshee.

    Gtk Custom Model

    Note: Test times are approximate, cache, cpu usage, load average and other may cause the times change, but at the end give us an idea of what is going on.
    ]]>
    http://islascruz.org/html/index.php/blog/show/Creating-a-custom-model.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Creating-a-custom-model.html Sat, 17 May 2008 10:24:50 -0500
    <![CDATA[ Testing the new christineConf module ]]>


    Testing the new christineConf module, originally uploaded by markuz.

    I have been working in the configuration module for christine, something similar to gconf, but just for christine. Why? well, many people complains because christine needs the gnome-extras package, where gconf is, and to be honest, christine didn't use all the gconf power, so, there isn't a big reaons to keep gconf on christine.
    This isn't the only thing I have been working on. I'm trying to improve many things for the next release. Most of the work wil be in the list, zodman gives me some nice ideas, and I will try to implement them.
    Anyway, you are also invited to work with me in the christine development. You can join the maling list for the next release.

    ]]>
    http://islascruz.org/html/index.php/blog/show/TestingthenewchristineConfmodule.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/TestingthenewchristineConfmodule.html Sat, 03 May 2008 23:38:30 -0500
    <![CDATA[ Christine 0.1.6 ]]>
    christine 0.1.6
    CLick to enlarge


    This is the new release of Christine Media Player. This release include:
    HelpMenu.png
    1. Some bugfixes
    2. Reworked code in Sources list
    3. Reworked display.
    4. Improved import code (no more freeze while looking for the media files)
    5. Multiple Sources list.
    6. Translate Christine and Report a bug menuitems
    You can download it from sourceforge:




    ]]>
    http://islascruz.org/html/index.php/blog/show/Christine-016.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine-016.html Tue, 29 Apr 2008 13:45:20 -0500
    <![CDATA[ Nearshoring... The Movie! ]]>
    ]]> http://islascruz.org/html/index.php/blog/show/Nearshoring-The-Movie.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Nearshoring-The-Movie.html Fri, 18 Apr 2008 13:05:47 -0500 <![CDATA[ PyGTK y Threads ]]>
    gtk.gdk.threads_init()
     
    Esto lo tendras que hacer antes de iniciar algun thread. Y luego, al usar algun thread debes englobarlo dentro de
    gtk.threads_enter()
    thread.start_new(funcion, (arg1,arg2,argN))
    gtk.threads_leave()
     
    Solo recuerda que no debes manipular gtk fuera del thread en el que esta corriendo el ciclo principal (gtk.main_loop).
    Si lo que necesitas es estar cachando informacion en un thread aparte y modificar la interfaz (ej. Leyendo un socket y mostrando informacion de cuanto llevas leido) entonces usa alguna bandera y modifica tu apariencia en el thread principal, de lo contrario tendras problemas con gobject y glib. ]]>
    http://islascruz.org/html/index.php/blog/show/PyGTK-y-Threads.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/PyGTK-y-Threads.html Thu, 10 Apr 2008 18:51:44 -0500
    <![CDATA[ Algo de amor para cristine ]]> sources.pngBien, hoy ha sido un pequenio dia para dar amor a christine, Hoy he tenido un poco de tiempo libre para 'descansar', Ayer cristina y yo nos fuimos a conocer Guanajuato, pronto pondre las fotos y la rese??????±a.
    Hoy, despues de hacer los quehaceres de la casa me sente un rato a cubrir una necesidad en especial que he tenido en Christine. Bien, pues resulta que a cristina le gusta mucho la musica en espa??????±ol, en particular la movida, mientras que a mi me gusta mas la musica en ingl??????©s, El problema es que la gran mayoria de la musica en espa??????±ol la he copiado de varios lugares y no la tengo en mi directorio de musica tipico, y tampoco lo tengo dentro de mi lista de canciones normal. Que pasa cuando cristina quiere escuchar su musica, tengo que entrar en ~/.christine y copiar el archivo music a algun otro, despues copiar el archivo de musica de cristina a music, y lo mismo cuando quiero poner mi lista de canciones. Un poco engorroso, aunque no lo hago muy seguido. Hoy he hecho un peque??????±o cambio a christine de forma que es posible selecionar la lista de canciones. Por hoy, en este lado es suficiente, aun le falta pulir, pero lo hace con mas tiempo y despues.
    Tambien estuve trabajando un poco para corregir unos pequenios problemas con los menus, que no se muestran traducidos, esto debido a que en los archivos de descripcion de glade las etiquetas no tienen la propiedad translatable (en los menues). Tambien he agregado al SVN los archivos de traduccion creados en Launchpad. En fin, estos cambios ya estan disponibles en el SVN de christine.

    newMenu1.png
    ]]>
    http://islascruz.org/html/index.php/blog/show/Algo-de-amor-para-cristine.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Algo-de-amor-para-cristine.html Sat, 22 Mar 2008 21:43:11 -0500
    <![CDATA[ Translation status ]]>

    Translation status in christine

    Wanna help? Translate christine HERE! ]]>
    http://islascruz.org/html/index.php/blog/show/Translation-status.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Translation-status.html Tue, 12 Feb 2008 16:57:22 -0600
    <![CDATA[ christine 0.1.5 ]]> christine and I'm not so proud (because of the delay) of the fifth revision of the fifth revision of the 0.1 version.
    This fixes some bugs that I have found since the 0.1.4 but to be honest, I don't remember them. You can download the source packages from Here. There is also an Ubuntu Gutsy Package there.

    christine 0.1.5
    ]]>
    http://islascruz.org/html/index.php/blog/show/christine-015.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/christine-015.html Tue, 05 Feb 2008 15:34:41 -0600
    <![CDATA[ Speed up gtk.ListStore ]]> Se, que podria mostrar Christine y dejar que una llamada con idle_add haga la chamba, es decir, christine se mostraria en menos de 1 segundo, pero el idle_add me retrasa mas la carga de la lista a unos 2 minutos.
    Alguien con algun comentario, enlace o similar, seria mas que apreciado. ]]>
    http://islascruz.org/html/index.php/blog/show/Speed-up-gtkListStore.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Speed-up-gtkListStore.html Thu, 06 Dec 2007 15:24:50 -0600
    <![CDATA[ Profiling Python ]]> Profiling and Optimizing Python ]]> http://islascruz.org/html/index.php/blog/show/Profiling-Python.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Profiling-Python.html Thu, 22 Nov 2007 08:40:15 -0600 <![CDATA[ Widgets 'recortados' en Gtk ]]> Gtk tienen una ventana asociada, y no precisamente la ventana con decoracion que todo mundo ve. Gtk adiere una propiedad llama "window" a los widgets al ser empacados, o emparentados a otro widget contenedor.
    Generalmente estos widgets son de apariencia rectangular, pero es posible tunearlos para que tengan la forma que nosotros queremos. La forma mas facil de hacerlo es tomar una imagen un usarla como "Molde" para crar nuestro contenedor recortado. aunque tambien es posible dibujar lo que nosotros querramos usando las funciones de cairo sobre un contexto (Que en si, es lo que hacemos con la imagen molde, pero mucho mas sencillo).
    Lo que hacemos es obtener un molde a partir de una imagen, es decir, abrimos la imagen y creamos un gtk.gdk.Pixbuf, que es el mostraremos, pero podemos obtener el gtk.gdk.Pixmap y la mascara de este Pixbuf de forma que podamos usar dicha mascara para crear el contorno de nuestro widget.
    Los widgets, una vez empacados,como ya habia dicho obtienen una propiedad llamada window, que pertenece a la clase gtk.gdk.Window. Aquellos que ya se han puesto a dibuar algo con cairo se habran dado cuenta que se obtiene un contexto de un widget a partir de su gtk.gdk.Window.
    Bien. tambien es posible obtener este contexto de cairo a partir de un pixmap, hacer el dibujo molde y luego pegarselo a la ventana para que gtk.gdk sepa que partes ha de dibujar y cuales no.
    Veamos un pequenio ejemplo.
    class shapedWindow(gtk.DrawingArea):
            def __init__(self):
                    gtk.DrawingArea.__init__(self)
                    self.__pixbuf =  gtk.gdk.pixbuf_new_from_file('./logo.png')
                    self.connect('size-allocate',self.size_allocated)
                    self.connect('expose-event',self.do_expose_event)
                    self.set_size_request(self.__pixbuf.get_width(),
                                    self.__pixbuf.get_height())
           
            def size_allocated(self,win,allocation):
                    w,h = (allocation.width, allocation.height)
                    self.bitmap = gtk.gdk.Pixmap(None,w,h,1)
                    context = self.bitmap.cairo_create()
                   
                    self.do_expose_event(self,'',context)
                    parent = self.get_parent()
                    win.shape_combine_mask(self.bitmap,0,0)
                    parent.shape_combine_mask(self.bitmap,0,0)
                   
            def do_expose_event(self, widget, event,allocate = False):
                    if allocate:
                            context = allocate
                    else:
                            context = self.window.cairo_create()
                    if allocate:
                            context.set_operator(cairo.OPERATOR_DEST_OUT)
                            w,h = (self.allocation.width, self.allocation.height)
                            context.rectangle(0,0,w,h)
                            context.set_source_rgb(1,1,1)
                            context.paint()
                    context.move_to(0,0)
                    context.set_operator(cairo.OPERATOR_OVER)
                    if allocate:
                            pixmap,mask = self.__pixbuf.render_pixmap_and_mask()
                            context.set_source_pixmap(mask,0,0)
                    else:
                            context.set_source_pixbuf(self.__pixbuf,0,0)
                    context.paint()
           
    if __name__ == '__main__':
            window = gtk.Window()
            window.set_decorated(False)
            a = shapedWindow()
            window.add(a)
            window.show_all()
            gtk.main()
           
     
    Que es lo que hacemos aqui? bien, primero creamos un widget personalizado usando gtk.DrawingArea y conectamos la sennial size-allocate para poder establecer el tamanio de nuestro widget. Una vez llamada esta funcion creamos un pixmap vacio del tamanio de nuestro widget, que es el tamanio que nos ha dado el contenedor padre, este es un rectangulo como de costubre, con un ancho y alto. A este pixmap le sacaramos el cairo context, sobre el cual hemos de 'dibujar' nuestro molde.
    Como en este ejemplo el widget y su molde de la misma forma estoy aprovechado el metodo do_expose_event para hacer el dibujo inicial y despues hacer las funciones de redibujado en caso de un evento de expose.
    Quienes hacen la chamba aqui? bien, para el dibujo inicial de nuestro widget es context.set_source_from_pixmap(), aunque podriamos usar el mismo set_source_from_pixbuf he detectado problemas con colores en Windows, entonces no lo recomiendo.
    Otro que entra en juego y es el que le dice al widget 'orale cabron, apegate a esta forma' es win.shape_combine_mask(self.bitmap,0,0).
    De ahi, el ponerle contenido a nuestro widget no es mas que un amanipulacion de colores y demas dentro de nuestro contexto cairo. Que, es otro tema del que hablar, como 'dibujar' lo que queremos en nuestro widget usando su contexto cairo.

    Shaped Window widget
    Tamanio Completo

    Ciertamente, el logtipo de Christine es el widget 'recortado' :-) ]]>
    http://islascruz.org/html/index.php/blog/show/Widgets-recordatos-en-Gtk.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Widgets-recordatos-en-Gtk.html Fri, 09 Nov 2007 17:19:06 -0600
    <![CDATA[ Sockets ]]> GTK+ que es el que corresponde a la termina de la esquina inferior izquierda. Otro cliente es puro texto, que es el que esta en la parte superior, y el servidor es la terminal alargada que esta en el centro.

    screenshot5.png

    Lo que muestran las terminales no es mas que pura informacion loggeada usando el modulo logging de python
    En los proximos dias, ya que tenga el codigo mas limpio vere la forma de ponerlo al publico. ]]>
    http://islascruz.org/html/index.php/blog/show/Sockets.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Sockets.html Wed, 31 Oct 2007 18:22:09 -0500
    <![CDATA[ Imprimir a un archivo PDF usando GTK. ]]> Perfecto. En esta semana me ha tocado estar trabajando sobre un programita que ando haciendo, el cual debe correr sobre Linux y MS Windows >= 2000. El desarrollo se esta haciendo en Python usando GTK para la interfaz grafica, pero me he encontrado uno que otro problemita con GTK, sobre todo con el manejo de ventanas, aunque el que mas tiempo me ha llevado ha sido el de impresion.
    Gtk+ a partir de la version 2.10 incluye soporte para impreision en Linux y otros Unix'es gracias a CUPS, mientras que en Windows lo hace de manera nativa con el sistema de impresion de Windows.
    Debo decir que en linux esta cosa es la maravilla, En windows no tanto, pero funciona decentemente si tus requerimientos no son tan especiales.
    Los requerimientos para imprimir son estos:
    • Debe imprimir en la impresora por defecto
      • NO debe mostrar el dialogo de seleccion de impresora
    • Debe imprimir en el tamanio determinado por el programa
    En linux, repito, esto es una maravilla, solo le digo imprime usando la constante gtk.PRINT_OPERATION_PRINT y con esto no me muestra el cuadro de dialogo, previamente he creado la operacion de impresion y le he dicho que seleccione la impresora por defecto, en linux, si en settings.set_printer() le pasas el parametro '' usa la impresora por defecto, es mas, si no usas el metodo set_printer usa la impresora por defecto.
    Pero en Windows la cosa no es tan bonita. para empezar Siempre muestra el cuadro de seleccion de impresora (punto menos). Y para acabarla de amolar, aunque tengas una impresora predeterminada y esta impresora este seleccionada mandas imprimir (Alt +m o ENTER) habra un error porque GTK no ha configurado las cabeceras de impresion para mandarle el 'win32-driver', 'win32-driver-extra' y otros parametros fumados de los que Windows sabe. Obviamente, si seleccionas otra impresora y regresas a la que esta por defecto estos parametros son llenados y entonces la impresion funciona "bien". Obviamente, como no queremos que el usuario vea el cuadro de impresion esto no es opcion.
    Lo siguiente es, obtener la impresora por defecto y mandar establecer los encabezados, para esto se pueden valer del modulo win32print
    import win32print
    printerName = win32print.GetDefaultPrinter()
    printer = win32print.OpenPrinter(printerName)
    printerValues = win32print.GetPrinter(printer,2)
    dir(printerValues['pDevMode'])
     
    Y pueden valerse del gtk.PrintSettings.set() para poner los encabezados.
    Esto les sera util cuando ustedes quieran mostrar el cuadro de impresion, a fin de que lo muestre y espere una configuracion por parte del usuari, o en caso de que no se configure nada por parte del usuario, usar las configuraciones por defecto.
    Hasta aqui todo bien, pero, Yo no quiero el cuadro de impresion!, solo quiero que imprima.
    Bien, yo no queria hacerlo asi, pero pues bueno, no hay de otra.
    if os.name == 'nt':
            filename = './ultimafactura.pdf'
            op.set_export_filename(filename)
            action = gtk.PRINT_OPERATION_ACTION_EXPORT
    elif '-d' in sys.argv:
            action = gtk.PRINT_OPERATION_ACTION_PRINT_DIALOG
    else:
            action = gtk.PRINT_OPERATION_ACTION_PRINT
    try:
            response = op.run(action)
    except:
            response = gtk.PRINT_OPERATION_RESULT_ERROR
    if response == gtk.PRINT_OPERATION_RESULT_ERROR:
            settings = op.get_print_settings()
            settings.foreach(funcPrintKeys)
            print "Hubo un error a imprimir"
    elif response == gtk.PRINT_OPERATION_RESULT_APPLY:
            if os.name == 'nt':
                    filename = './ultimafactura.pdf'
                    import win32api
                    win32api.ShellExecute(0,
                                    'print',
                                    filename,
                                    None,
                                    '.',
                                    0)
     
    La solucion ha sido crear un archivo PDF, usando el PrintOperation.set_export_filename() para despues usar win32api.ShellExecute() para imprimir.
    Que es lo que hace ShellExecute?. Bien, ejecutara el comando que tu le des, en este caso 'print' sobre el archivo dado por el siguiente parametro "filaname", el siguiente parametro son los parametros al programa que va a realizar la operacion, el siguiente, el directorio de trabajo y por ultimo un valor entre 0 y 1 que dice si se ha de mostrar o no la ventana del programa que ha de realizar la operacion.
    Para esto, es necesario tener en Windows un programa que pueda abrir e imprimir PDF. Obviamente el mas conocido es Adobe Acrobat Reader, pero Adobe Acrobat Reader es un Monstruo si lo unico que queremos es impresion. Asi que, lo que he hecho es utilizar Foxit PDF Reader, el cual es mucho mas ligero y rapido.
    Y eso es todo, ese ha sido el cucharazo porque GTK por defecto no te utiliza la impresora por defecto, ni te esconde el cuadro de impresion en Windows.
    En fin. el chiste es lograr que las cosas jalen.
    Un ejemplo sencillo de impresion lo pueden encontrar Aqui ]]>
    http://islascruz.org/html/index.php/blog/show/Imprimir-a-un-archivo-PDF-usando-GTK.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Imprimir-a-un-archivo-PDF-usando-GTK.html Fri, 19 Oct 2007 10:18:44 -0500
    <![CDATA[ CakePHP + Scriptaculous ]]>

    Cake + Scriptaculous
    ]]>
    http://islascruz.org/html/index.php/blog/show/CakePHP--Scriptaculous.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/CakePHP--Scriptaculous.html Tue, 09 Oct 2007 12:40:14 -0500
    <![CDATA[ Christine 0.1.1 ]]> El equipo de desarrollo de Christine se complace en presentarles la nueva version de Christine, 0.1.1, Esta version es una version corregida de Christine 0.1, es decir, no implementa cosas nuevas, solo mejora lo que ya estaba.
    Pueden descargar las fuentes de Christine 0.1.1 Aqui, y revisar las notas de liberacion Aqui.
    Gracias a todos los que han cooperado con el desarrollo de Christine. ]]>
    http://islascruz.org/html/index.php/blog/show/Christine-011.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine-011.html Fri, 21 Sep 2007 14:10:38 -0500
    <![CDATA[ Usando el widget creado anteriormente ]]>

    widgetTest.ogg
    ]]>
    http://islascruz.org/html/index.php/blog/show/Usando-el-widget-creado-anteriormente.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Usando-el-widget-creado-anteriormente.html Fri, 14 Sep 2007 16:44:13 -0500
    <![CDATA[ Un contenedor GTK Redimensionable al gusto. ]]> gtk.Fixed, Este contenedor nos permite poner widgets de manera estatica en nuestra aplicacion. Es decir, si la ventana cambia de tamanio los widgets no se redimencionaran y tampoco cambiaran de posicion. Pocos lo utilizan por esto, pero a veces es necesario.
    Pues resulta que en una de las aplicaciones lo tengo asi, simplemente porque los widgets NO se tienen que mover ni cambiar de tamanio si la ventana se redimenciona, aqui yo lo veo como algo bueno. En fin, El problema del GtkFixed es que nomas no me cacha los eventos, y meterlo en un gtk.EventBox me parece no tan optimo, puesto que yo quiero que los eventos los cache el Widget, no un EventBox.
    Mi primer intento de solucion: Crear una clase que herede de gtk.Fixed y cachar los eventos para que cuando el cursor este dentro de un punto determinado se pueda redimencionar al muy puro estilo de click-arrastra-suelta. Problema, gtk.Fixed no me cacha los eventos, incluso si se los agrego a manita con gtk.Fixed.add_events.
    Segundo intento: Hereda primero de un gtk.EventBox y luego de un Fixed: Si cacha los eventos, No te muestra ni madres. Inviertelo, Si te dibuja, pero no te cacha los eventos... (ya me estoy desesperando)
    La solucion?, Bueno, nunca le habia echado el ojo al gtk.Layout,
    entonces heredo de un gtk.Layout primero, este no me cacha los eventos, pero, me permite dibujar como si fuera un gtk.DrawingArea aunque tienes que dibujar sobre el bin_window de tu layout (gtk.Layout.bin_window) en lugar del window como tipicamente se hace en gtk.DrawingArea. Bien, tu segunda herencia es de un EventBox para poder cachar las seniales, y listo :-).
    Es importante que Primero se herede de gtk.Layout y luego de algun otro widget (gtk.DrawingArea tambien funciona) para que Gtk no reniegue al tratar de agregar widgets a tu gtk.Layout.
    El codigo seria mas o menos asi (Estoy seguro que de alguna manera se puede mejorar):
    class groupWidget(gtk.Layout,gtk.EventBox):
            '''
            Una version modificada del gtk.Fixed
            '
    ''
            def __init__(self):
                    gtk.Layout.__init__(self)
                    gtk.EventBox.__init__(self)
                    self.__buttonPressed = False
                    self.set_name('groupWidget')
                    self.set_size_request(50,50)
                    self.set_property('events',
                                    gtk.gdk.EXPOSURE_MASK |
                                    gtk.gdk.ENTER_NOTIFY_MASK|
                                    gtk.gdk.POINTER_MOTION_MASK |
                                    gtk.gdk.BUTTON_RELEASE_MASK |
                                    gtk.gdk.BUTTON_PRESS_MASK )
                    self.add_events(
                                    gtk.gdk.EXPOSURE_MASK |
                                    gtk.gdk.ENTER_NOTIFY_MASK|
                                    gtk.gdk.POINTER_MOTION_MASK |
                                    gtk.gdk.BUTTON_RELEASE_MASK |
                                    gtk.gdk.BUTTON_PRESS_MASK )
                    self.connect('expose-event',self.__exposeEvent)
                    self.connect('motion-notify-event',
                                    self.__motionNotify)
                    self.connect('button-press-event',
                                    self.__buttonPressEvent)
                    self.connect('button-release-event',
                                    self.__buttonReleaseEvent)
           
            def __motionNotify(self,widget,event):
                    if self.__buttonPressed:
                            x,y = self.get_pointer()
                            if (x,y ) > (0,0):
                                    self.set_size_request(x,y)
                                    self.__lastWH= [x,y]
            def __buttonPressEvent(self,widget,event):
                    w,h = self.__lastWH
                    px,py = self.get_pointer()
                    if event.button == 1:
                            if w > px > w-5 and  h > py > h-6:
                                    self.__buttonPressed = True
           
            def __buttonReleaseEvent(self,widget,event):
                    if event.button == 1:
                            self.__buttonPressed = False
            def __exposeEvent(self,widget,event):
                    '''
                    Encargada de dibujar el widget
                    '
    ''
                    context = self.bin_window.cairo_create()
                    x,y,w,h = self.allocation
                    self.__lastWH = [w,h]
                    context.set_line_width(1)
                    context.set_antialias(cairo.ANTIALIAS_NONE)
                    #Dibujamos el relleno y el borde
                    context.move_to(0,0)
                    context.rectangle(1,0,w-1,h-1)
                    context.rectangle(1,0,w-1,h-1)
                    context.set_source_rgba(1,1,1,0.5)
                    context.fill_preserve()
                    context.set_source_rgb(0,0,0)
                    context.stroke()

                    #Dibujamos un pequenio rectangulito
                    # en la parte inferior derecha.
                    context.rectangle(w-5,h-6,5,5)
                    context.set_source_rgb(0.5,0.5,0.5)
                    context.stroke()

     
    Y se deberia ver asi:



    En el video se puede apreciar que el boton esta dentro del contenedor, por eso de corta cuando el tamanio del contenedor es menor (se pueden usar Scrollbars gracias a la capacidad de gtk.Layout. ]]>
    http://islascruz.org/html/index.php/blog/show/Un-contenedor-GTK-Redimensionable-al-gusto.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Un-contenedor-GTK-Redimensionable-al-gusto.html Thu, 13 Sep 2007 16:23:52 -0500
    <![CDATA[ Respuesta ]]> Armando: En las escuela esta muy dificil que te ensenien a usar PHP, y esta aun mas dificil que te ensenien a usar Python, mas cabron aun, que te ensenien a usar GTK. Desafortunadamente en mexico las escuelas estan dedicadas a enseniar cosas como Java o .NET porque:
    1.- Es un circulo vicioso, los profesores lo saben, lo ensenian a los alumnos, los alumnos aprenden, la mayoria de los alumnos no aprenden otra cosa, y cuando les toca enseniar solo pueden enseniar lo que saben, asi terminan dando Java.
    2.- Muchas escuelas estan casadas con Microsoft, asi que por fuerza lo han de dar :).
    De PHP hay infinidad de libros, y tutoriales libres muy buenos por la red, el libro con el que yo empece con PHP es con el de 'Proyectos Profesionales con PHP' de editorial ANAYA,
    De Python, te recomiendo el tutorial de python que esta en la documentacion de python, 'Dive Into Python' y 'How to think like a computer scientist learning with python' .
    De Gtk, Hay un tutorial muy bueno en la documentacion de PyGTK.
    Un comentario, si piensas aprender PHP para usar GTK, te recomiendo mejor aprender Python para usarlo con GTK. ]]>
    http://islascruz.org/html/index.php/blog/show/Respuesta.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Respuesta.html Thu, 09 Aug 2007 15:35:56 -0500
    <![CDATA[ Amo a PyGTK ]]> Aun no termino el programa, me faltan varios detalles, pero para 2,3 dias que llevo en el vamos bien. Lo que me encanta es que programo desde linux con Vim y pruebo en windows. Obviamente, no se permite que cada maquina tenga una conexion directa con base de datos, asi que mejor abrimos un socket en una maquina 'servidor' y los clientes solo piden datos ahi.

    I love GTK
    En GNU/Linux

    I love GTK
    En Windows

    ]]>
    http://islascruz.org/html/index.php/blog/show/Amo-a-PyGTK.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Amo-a-PyGTK.html Wed, 08 Aug 2007 08:34:08 -0500
    <![CDATA[ Christine 0.1 ]]> Bien, hoy es mi cumplea??????±os, gracias a todos los que no me han felicidado hasta ahora, y gracias a todos los que ya me felicitaron.
    He liberado la primera version de Christine, tal vez no es tan estable como yo quisiera, pero tengo planes par a christine que no van con el codigo que tengo ahorita, asi que lo mejor ser??????? liberar esto y empezar a codear en lo siguiente. Si encuentran bugs ya saben Donde reportarlos.
    Que cambio con respecto de la 0.1rc2?. Bien corregi varias cosas, y mejor??????© un poco algunas otras. Las correcciones no las recuerdo ahorita porque por lo general se almacenan en mi memoria temporal. Y las mejoras, pues mejore un poco lo del soporte para estaciones de radio y playlist m3u y el display que ahora usa los colores del theme.
    Puedes descargar christine 0.1 Aqui. ]]>
    http://islascruz.org/html/index.php/blog/show/Christine-01.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine-01.html Sun, 29 Jul 2007 13:29:01 -0500
    <![CDATA[ Christine for birthday! ]]> Piratearle Metodos a un objeto para hacer empapelados y crear un ambiente de desarrollo mas sencillo. Todo esto es en lo que se esta trabajando y formar??????? parte de christine.
    Otras cosas en las que he trabajado es en bugfixes para la version 0.1 y peque??????±as mejoras (que he de agregar lo otro). Lo mejor es que ahora christine tiene un mejor soporte para archivos m3u y pls y que tiene un "display" que ahora se dibuja con los colores del theme.

    Christine
    ]]>
    http://islascruz.org/html/index.php/blog/show/Christine-for-birthday.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine-for-birthday.html Thu, 26 Jul 2007 12:56:34 -0500
    <![CDATA[ "Piratearle" las propiedades a un objeto en Python ]]> Uno y quieres que obtenga las propiedades de la clase Dos o Tres, Por que harias esto?, simplemente porque en tu programa no quieres lidiar con
    import uno,dos,tres
    if "uno":
        refrerencia = uno()
    elif "dos":
        referencia = dos()
    else:
       referencia  = tres()
     
    Y despues averiguar sobre quien haces la instancia en cada parte de tu codigo que requiera una instancia, de hecho, no es escalable, agregar una referencia mas seria doloroso si tu codigo es grande. mejor es hacer un empapelado de las referencias y hacer instancia a una sola, y que esta se haga pelotas de a quien referenciar.
    Una forma de acercarse seria usar esto:
    class wrapper:
        def __init__(self,modulo):
            moduloobj = __import__("paquete",globals(),locals(),[modulo])
            referencia = vars(moduloobj)[modulo]
            self.__empapelado = referencia()
     
    Para obtener refrencias de las propiedades de un objeto usamos getattr, getattr recibe como primer parametro el objeto en el que se buscar??????? la propiedad y como segundo, el nombre de la propiedad en cadena.
        def Query(self,metodo,*args):
            '''
            @param string metodo: Nombre del metodo en cadena
            @param *args: argumentos a pasar al metodo.
            '
    ''
            met = getattr(self.__empapelado,metodo)
            if callable(met):
                return met(*args) #ejecutamos el metodo y regresamos lo que nos regrese
     
    Y tener:

    a = wrapper("uno") #o "dos", o "tres"

    a.Query("imprimeEsto","Texto a imprimir")
    Esto, desde mi punto de vista es ideal, pues tu codigo es limpio, pero tal vez quieres hacer el empapelado sobre un proyecto que ya tiene rato jalando, y que todo se hace referencia a una clase, pero, quieres que esta clase ahora sea el "empapelado". Puedes Piratearle las propiedades a otro objeto, asi:
    #!/usr/bin/env python
    import paquete
    class Pirata:
            '''
            Se piratea las propiedades de un objeto.
            '
    ''
            def __init__(self,modulo,objeto):
                    '''
                    Constructor
                    '
    ''
                    moduloobj = __import__(paquete,globals(),locals(),[modulo])
                    referencia = vars(moduloobj)[modulo]
                    pirateable = getattr(referencia,objeto)()
                    for i in dir(pirateable):
                            newkey = i.replace("_%s_"%objeto,"_Pirata_")
                            self.__dict__[newkey] = getattr(pirateable,i)
     
    Para tener algo asi:

    a = test.Pirata("modulo","clase")

    a.imprimeEsto("Texto a Imprimir")
    De esta forma, no cambias nada en tu codigo que ya tienes, simplemente, en alguna parte de tu codigo, indicas que el "empapelado" ha de piratearle las propiedades a otro objeto que haga las operaciones necesarias. ]]>
    http://islascruz.org/html/index.php/blog/show/Piratearle-las-propiedades-a-un-objeto-en-Python.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Piratearle-las-propiedades-a-un-objeto-en-Python.html Tue, 24 Jul 2007 11:35:27 -0500
    <![CDATA[ Como dibujar un imagen (jpg, png, gif, etc..) en Cairo ]]>
    def setPixbuf(self,pixbuf):
            if type(pixbuf) != gtk.gdk.Pixbuf:
                    raise TypeError("Pixbuf debe ser %s recibido %s"%(gtk.gdk.Pixbuf, type(pixbuf)))
            self.__Pixbuf = pixbuf
            self.emit("expose-event",gtk.gdk.Event(gtk.gdk.EXPOSE))

    def exposeEvent(self, widget,event):
            x,y,w,h = self.allocation
            try:
                    context =  self.window.cairo_create()
            except AttributeError:
                    return True
            if self.__Pixbuf != None:
                    scaledPixbuf = self.__Pixbuf.scale_simple(ancho,
                                    alto,
                                    gtk.gdk.INTERP_BILINEAR)
                    ct = gtk.gdk.CairoContext(context)
                    ct.set_source_pixbuf(scaledPixbuf,BORDER_WIDTH,BORDER_WIDTH)
                    context.paint()
                    context.stroke()
     
    Y listo :-) ]]>
    http://islascruz.org/html/index.php/blog/show/Como-dibujar-un-imagen-jpg-png-gif-etc-en-Cairo.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Como-dibujar-un-imagen-jpg-png-gif-etc-en-Cairo.html Sat, 21 Jul 2007 10:52:16 -0500
    <![CDATA[ Creando tus propios objetos con gobject y error con las seÃ?Æ?Ã?±ales. ]]>

    <nombredeObjecto object (paquete+modulo+nombredeObjeto) at 0xb7b6f34c&rt;
    Pues es facil, en nuestra clase tendremos esto:
    #notese que estoy haciendo una subclase de gtk.Widget.
    class nombredeObjeto(gtk.Widget):
       def __init__(self):
           gobject.GObject.__init__(self)
           self.set_name("nombredeObjeto")
    gobject.type_register(nombredeObjeto)
     
    Asi de facil :-), el nombre que mostrara despues del "<" sera lo que definas en set_name ]]>
    http://islascruz.org/html/index.php/blog/show/Creando-tus-propios-objetos-con-gobject-y-error-con-las-seales.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Creando-tus-propios-objetos-con-gobject-y-error-con-las-seales.html Thu, 05 Jul 2007 12:08:01 -0500
    <![CDATA[ Creando clases de Python en C ]]> pero aqui va mas o menos como se hace. No encontre mucha documentacion sobre la implementacion de clases de Python en C, pero le seguir??????© buscando.
    Algo que tambien me puse a buscarle hoy, fue como usar variables globales. es algo muy sencillo de lograr, algo que los programadores en C me diran, "Pues si, pendejo, asi se hace", pero yo no sabia, y alguien por ahi no sabr??????? tampoco, asi que ahi va:
    suponiendo que tenemos un modulo demo, en python seria algo asi:
    nombre = ""
    apellido = ""
    def asignaDatos(nom,ape);
        nombre = nom
        apellido = ape
    def doSomething():
        print nombre
        print apellido
     
    para poder usar algo asi:
    Python 2.4.3 (#1, Jul 26 2006, 20:13:39)

    [GCC 3.4.6] on linux2

    Type "help", "copyright", "credits" or "license" for more information.

    >>> import demo

    >>> demo.asignaDatos("marco","islas")

    >>> demo.doSomething()

    marco

    islas

    >>>
    en C seria asi:
    #include <Python.h>
    #include <stdio.h>
    #include <stdlib.h>

    struct pers {
        char *nombre;
        char *apellido;
    };
    struct pers persona;
    static PyObject *doSomething(PyObject *self, PyObject *args){
        extern struct pers persona;
        printf("%s\n",persona.nombre);
        printf("%s\n",persona.apellido);
        free(persona.nombre);
        free(persona.apellido);
        Py_INCREF(Py_None);
        return Py_None;
    }

    static PyObject *asignaDatos(PyObject *self, PyObject *args){
        extern struct pers persona;
        char *nombre,*apellido;
        persona.nombre = malloc (1024);
        persona.apellido = malloc(1024);
        PyArg_ParseTuple(args,"ss",&nombre,&apellido);
        strcpy(persona.nombre,nombre);
        strcpy(persona.apellido,apellido);
        Py_INCREF(Py_None);
        return Py_None;
    }
    static PyMethodDef demoMethods[] = {
        {"doSomething",doSomething,METH_VARARGS,"imprime los valores de la persona"},
        {"asignaDatos",asignaDatos,METH_VARARGS,"Asigna los datos de la persona en la estructura"},
    };
    PyMODINIT_FUNC initdemo(void){
        (void) Py_InitModule("demo",demoMethods);
    }

     
    ]]>
    http://islascruz.org/html/index.php/blog/show/Creando-clases-de-Python-en-C.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Creando-clases-de-Python-en-C.html Wed, 04 Jul 2007 18:08:30 -0500
    <![CDATA[ Christine 0.1rc2.deb ]]> nibblesmx ha creado un paquetin para Ubuntu Feisty de Christine 0.1.rc2. Puedes obtenerlo aqui ]]> http://islascruz.org/html/index.php/blog/show/Christine-01rc2deb.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine-01rc2deb.html Wed, 04 Jul 2007 13:01:43 -0500 <![CDATA[ Work and Fun! ]]> Grupo de usuarios de software libre de Poza Rica (GNUPR) por no haber podido asistir a las tres ultimas reuniones, me fue imposible, la primera, andaba en salamanca en ICTC, y las otras dos por motivos personales, espero en estas semanas compensar.
    Como ya lo mencion??????© en el post anterior, he estado usando Eclipse por un ratito, no saben lo facil que me ha hecho desarrollar en Python con el plugin PyDev, ojo, aun no uso las PyDev extensions, pero puede que en un rato pague la licencia, dependiendo de que tan bien me sienta en un futuro.
    Que es lo bueno?, bien, pues el debugger me ayuda algo, pero el autocompletado, el docstring, el hecho de que analiza mi codigo en el vuelo y me dice si tengo algun error de sintaxis, el crear un modulo o un paquete me queda a un click, el navegador me muestra mis modulos, sus clases y propiedades sean publicas o "privadas". Es un buen chunche muy bonito, muy practico. Ademas, en ICTC usamos svn para manejar las revisiones del software, asi que use el subclipse (el plugin de tigris.org para manejar subversion en eclipse) y todo va sweet, incluso el hecho de que no se hace autenticacion por contrase??????±a sino por llave dsa, muy bonito.
    Tambien he estado utilizando Tomboy para mis notas, ya me estoy acostumbrando a usarlo :-).
    En la semana me fui a Huauchinango a renovar mi licencia de manejo, no tengo fotos porque se me olvido la camara (junto con mi celular) en la casa, pero me di cuenta de algo genial, las oficinas de MySpace.com en mexico han cerrado o se han reubicado puesto que el local esta en renta. En cuanto vaya de nuevo, tomare foto a lo que eran las "oficinas".
    Creo que es todo por ahora. ]]>
    http://islascruz.org/html/index.php/blog/show/Work-and-Fun.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Work-and-Fun.html Sat, 23 Jun 2007 23:44:40 -0500
    <![CDATA[ usando Eclipse ]]> vimero de coraz???????n, no lo puedo evitar, simplemente me parece perfecto que en vim tenga muchas de las opciones que necesito, y como normalmente me concentro en un par de archivos, pues... con las funciones split y vsplit me siento super bien.
    Ahora que estuve en Slamanca Aldo me comento del autocompletado en vim, usando Ctrl+P aparece un "popup" o menu desplegable con las ocurrencias, usando Ctrl+P se selecciona entre las ocurrencias. Una razon mas para seguir usando vim.
    Aldo es usuario de vim tambien, pero para pogramar en Python usa eric3. Hace un par de a??????±os cuando empezaba a programar en Python lo use un poco (tambien usaba ubuntu) pero poco me duro ubuntu en la maquina y menos me duro eric3. Lo sentia feo, en cierta forma incomodo.
    La semana pasada me compile lo necesario y eche a andar eric3 en la cususa, me gusto mucho, bastante practico, pero debo decir que no perfecto y si bien cumple con muchas de mis espectativas, no me siento tan comodo con el. Asi que me puse a probar con Eclipse, cierto, ya me lo dijo aldo, que soy un extremista, de usar vim a Eclipse, pero eclipse con pydev es la neta, me gusto mucho, y creo que para desarrollar con python lo seguire usando un rato mas, si es que no me harto. ]]>
    http://islascruz.org/html/index.php/blog/show/usando-Eclipse.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/usando-Eclipse.html Thu, 14 Jun 2007 19:28:48 -0500
    <![CDATA[ Cambiando el color de nuestros widgets en GTK. ]]> Lo ideal para cambiar el color de un widget seria dejarlo al libre gusto del usuario, pero a veces necesitamos que un widget tenga X o Y color (gimmie?). Bien para cambiar el color de un widget basta con un simple:
    map = widget.get_colormap()
    color = map.alloc_color("white") #Se puede usar codigo RGB #FFFFFF
    widget.modify_bg(gtk.STATE_NORMAL,color)
     
    Ciertamente, no es lo mejor, pero puede que lo necesitemos, y mejor es tenerlo y saber como hacerlo. ]]>
    http://islascruz.org/html/index.php/blog/show/Cambiando-el-color-de-nuestros-widgets-en-GTK.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Cambiando-el-color-de-nuestros-widgets-en-GTK.html Fri, 08 Jun 2007 13:15:21 -0500
    <![CDATA[ Christine 0.1rc2 ]]> christine-0.1rc2.tar.bz2 ]]> http://islascruz.org/html/index.php/blog/show/Christine-01rc2.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine-01rc2.html Mon, 04 Jun 2007 19:56:30 -0500 <![CDATA[ Christine 0.1rc1 ]]> Anyway, I need you to test it before I upload it to sourceforge.net servers.
    get it at: http://islascruz.org/html/data/files/christine-0.1rc.tar.bz2
    And what's the new in christine 0.1 againts 0.0.3??
    • Faster, I mean, really faster import.
    • Very simple radio station support.
    • Drag'n'Drop queue add.
    • lots of bugs fixed.
    Go, test it and report your bugs :-) ]]>
    http://islascruz.org/html/index.php/blog/show/Christine-01rc1.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine-01rc1.html Fri, 01 Jun 2007 16:26:59 -0500
    <![CDATA[ Evitando que las aplicaciones en GTK se congelen... ]]> Suponiendo que tienes que iterar sobre 100,000 elementos (no se que, solo son elementos de algo), y tu aplicacion tiene que procesar esto, obviamente, va tardar algo y quieres que tus usuarios esten "entretenidos" mientras la aplicacion trabaja, asi evitas que se aburran y sobre todo, evitas que piensen que tu aplicaci???????n se ha atorado y terminen matandola.
    Pero, por que se congela la interface grafica si esas ejecutando algo en "background"?, bien, la solucion es simple. GTK+ captura los enventos y realiza sus tareas por ciclos, de ahi el uso del gtk.main() para iniciar el ciclo. pero cuando tu aplicacion entra en un ciclo este no devuelve el control del programa a GTK hasta que termina el ciclo que estas realizando por lo tanto, el ciclo de GTK no termina y se actualiza hasta que se le devuelve el control.
    progress = gtk.ProgressBar()
    fraction = 0
    for i in xrange(100000):
       print "Estoy congelando la interfaz!!"
       sleep(1)
       fraction += 1/100000
       #No se actualizar??????? porque GTK no puede actualizar, no tiene el control
       progress.set_fraction(fraction)
    # Uff, por fin!!
     
    Una solucion que habia estado usando era dividir mi ciclo y realizarlo por pedacitos usando gobject.timeout_add(). este timer te permite ejecutar una funcion/metodo cada determinado tiempo, logrando evitar el "freezeo", lo malo s que no es tan rapido como quisieramos y peor aun, tienes que trozar tu ciclo, en si no realizas un ciclo con un for, o while o algo asi, sino que ejecutas la funcion un chingo de veces, mientras regreses el valor True, y sales regresando el valor False.
    progress = gtk.ProgessBar()
    fraction = 0
    def funcion():
       fraction += 1/100000
       progress.set_fraction(fraction)
        if fraction == 1:
            return False
        return True
    gobject.timeout_add(200, funcion) #ejecutar funcion cada 200 milisegundos
     
    La solucion mas limpia, y mejor es usar
    while gtk.events_pending():
                     gtk.main_iteration_do(False)
     
    Esto se usa dentro de tu ciclo bloqueador. Por ejemplo:
    progress = gtk.ProgressBar()
    fraction = 0
    for i in xrange(100000):
       fraction += 1/100000
       progress.set_fraction(fraction)
       #Detenemos todo y dejamos que GTK tenga control y realice sus tareas pendientes
        while gtk.events_pending():
           gtk.main_iteration_do(False)
    # Uff, por fin!!
     
    Espero les sea util. Con esto no solo evitamos el congelamiento de la aplicacion, sino que el ciclo se realiza tan rapido como el CPU puede hacerlo, usando el timer, no importa que tan rapido sea el CPU, siempre terminara en el mismo tiempo. ]]>
    http://islascruz.org/html/index.php/blog/show/Evitando-que-las-aplicaciones-en-GTK-se-congelen.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Evitando-que-las-aplicaciones-en-GTK-se-congelen.html Thu, 17 May 2007 22:30:26 -0500
    <![CDATA[ Importing files in christine. ]]> Today I have work in the import stuff in christine, since we start working on it we have several issues, some crashes of freezes. Most of them in some other computers. In my computer there where just some freezes that get solved just in time, i mean, I have to be wait a bit and chritine updates itself.
    In the first aproach I try to use gobject.timeout_add to iterate over the files to import, that wasn't the right approach, because, the time between insert and insert where fixed, 0.6 secs, no matter if you have a 4 CuadCore CPU's it will take the same time in my machine. And in some old machines, this just crash. And it crash because in that machines we have to wait a bit more before insert another file to be parsed.
    The other (the right)) approach was using signals. The main library was emitting signals when it was ready to accept another file to be inserted, but there where something that just crashes my app, I try to use this with threads, timer from gobject and nothing. At this time, it just don't crash, but it just freeze.
    Answer.... Use this:
    while gtk.events_pending():
                     gtk.main_iteration_do(False)
     
    Just, let GTK to update the interface before doing anything else. :-). Now it 's sweet and it takes 5 to 6 minutes to import my ~2500 files, takes more importing mp3 than ogg, but that's a gstreamer issue.
    Importing media to christine

    Update1 For some weird reasons this seems not working in some computers. It doesn't run well in nibblesmx machine, even that I guess it's faster than mine and uses a OS that is compiled for i686 instead i486 (wich makes no big difference). The sema with n0sferatu, but I think that is the gstreamer version that they have or something like that, because both of them use Ubuntu... Some ubuntu user to thest the code of christine?. ]]>
    http://islascruz.org/html/index.php/blog/show/Importing-files-in-christine.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Importing-files-in-christine.html Wed, 16 May 2007 11:24:16 -0500
    <![CDATA[ Sin que decir. ]]>
  • Sigo trabajando en C. Me gusta mucho, ya le agarr??????© cari??????±o, a pesar de que he estado utilizando Python que es super sencillo, este lenguaje me ofrece buenos retos y viendolo bien no esta tan dificil, cosa de hacer las cosas como deben de ser. Yo creo que despues de esto implementar??????© mas cosas de Christine en C.
  • Con esto del cambio de servidor, muchos de los dominios que tenia registrados siguen fuera de linea, uno de ellos christine-project.org :-(.
  • Estaba cabilando, hace unos a??????±os obtener una copia e Solaris legal era algo dificil, ahora me llegan por correo. solaris 10, OpenSolaris (esta me la regalo alo), y hoy me llego el Solaris Express Developer Edition.
  • Mi hermano instalo Kubuntu en su maquina, que es algo que me alegra mucho, aunque me molesta que Ubuntu no incluya por defecto las utilerias para compilar. En mi casa tenemos una red inalambrica, algo que ya discuti en un post anterior, Yo tengo ndiswrapper y bueno, con eso tengo mi red funcionando, pero mi hermano la unica forma de conectarse de manera inalambrica es gracias a windows, el driver de su adaptador de red USB debe ser compilado como modulo, es un driver oficial por parte de los de Encore, problema con unbuntu, no puedo compilar porque no tengo ni gcc. ]]> http://islascruz.org/html/index.php/blog/show/Sin-que-decir.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Sin-que-decir.html Thu, 03 May 2007 22:39:46 -0500 <![CDATA[ Happy Sunday for Christine ]]> Christine Bug Squash I'm Happy because we (nibblesmx and I) fixed some bugs, 5 bug reports where fixed and closed while some others are still open waiting for some user testing (even that they where fixed and in my machine it works fine).
    Tanks to Pcero and Jose Oviedo, for their bug reports.
    Things that I like more about Christine is:
    • Support for radio stations. (via Open Remote) Now you can just copy the Url of the .pls or m3u file and christine will play it.
    • Improved the Visualization mode. Now it works on the radio stations too. And if you aren't playin Christine and activate it, when you hit the play button it will work (no wait until next song or deactivate and reactivate).
    • Improved the time for importing I have been working with signals, and at least in my machine it runs smooth, Importing my 1865 songs in just 2 or 3 minutes (hey, fetching all that data isn't easy in GStreamer, and I know there are some other libraries, but we have to be able to fecth this data (tags) with all Media Files supported by GStreamer not only mp3 and vorbis ogg)
    Some things still need some work:
    • Some keyboard bindings are broken.
    • The player display (where videos and visualization shows up) steals events if it is in focus.
    • There are a bunch of features that I'd like to include in next release.
    ]]>
    http://islascruz.org/html/index.php/blog/show/Happy-Sunday-for-Christine.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Happy-Sunday-for-Christine.html Sun, 22 Apr 2007 22:04:13 -0500
    <![CDATA[ Christine bug squash ]]>

  • Se llevar??????? a cabo un bug squash de christine este fin de semana, buscando la liberaci???????n de la primera estable. Si usas christine y quieres cooperar, reporta tu bug en el Bug Tracker. Los bugs permanecer???????n abiertos hasta el fin de semana, en donde les daremos mate. ]]>
    http://islascruz.org/html/index.php/blog/show/Christine-bug-squash.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine-bug-squash.html Tue, 17 Apr 2007 10:36:49 -0500
    <![CDATA[ La mejor manera de aprender es practicando... ]]> Desde un par de semanas me he aventado a programar en C por causas de la chamba. ciertamente a mi me contrataron como desarrollador en Python, pero ps weno, nunca hay que rajarse, asi que cuando me preguntaron que si que tal le movia a C y si me animaba a hacer una chambita en este lenguaje, pues no pude decir que no. En primera porque siempre he querido aprender C, pese a que he aprendido a utilizar otros lenguajes primero. y, pues mi jefe sabiendo que no me la reviento tan bien en C, me da la oportunidad de hacerlo, y con un proyecto que servir??????? en el uso diario, o sea, no ser???????n meros ejemplitos los que estar??????© programando, asi que pues que mas podria yo pedir?.
    Bien, he de reconocer que me he tomado mi tiempo, no porque yo quisiera, ni porque sea talegas, que reconozco que lo soy, pero no por eso dejo de chambiar. Mas bien fue por cosas de punteros y fallos de segmento que se podrian medir en kilos :-P, de los cuales he sacado bastante provecho.
    En fin, el punto es que mi libro de C, del cual yo esperaba aprender lo tengo desde hace casi 4 a??????±os en mi casa, y nomas nada, si lo he leido, pero nunca puse en practica lo aprendido, hasta ahora, y veo que he aprendido mas en estas dos semanas de estar en chinga para sacar la chamba, que en 4 a??????±os de lectura pasiva. No cabe duda para mi, la mejor forma de aprender es practicando. ]]>
    http://islascruz.org/html/index.php/blog/show/La-mejor-manera-de-aprender-es-practicando.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/La-mejor-manera-de-aprender-es-practicando.html Tue, 27 Mar 2007 13:49:43 -0500
    <![CDATA[ Christine code clean bugfix ]]>

    bigfixing Christine

    I also integrate a "--devel" option in christine, that let you work with christine from the source code directory. I mean, checkout the christine code, then run autogen.sh, run configure, make, and then just run christine like this: "./christine --devel" from the top of the source directory. Useful for people (coff coff developers coff coff) that want to try, not to install.
    As always, my invitation to Check it out, test it, and fill our Bug tracker ]]>
    http://islascruz.org/html/index.php/blog/show/Christine-code-clean-bugfix.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine-code-clean-bugfix.html Fri, 23 Mar 2007 07:57:31 -0500
    <![CDATA[ Peleando con C ]]> Como Programar en C/C++" Que la neta si me est??????? sacando del apuro. ]]> http://islascruz.org/html/index.php/blog/show/Peleando-con-C.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Peleando-con-C.html Mon, 19 Mar 2007 17:12:00 -0500 <![CDATA[ Christine for today!! ]]>
  • Package lib_christine have been changed to libchristine.
  • Most of the bugs generated by the code clean are solved.
  • and....

  • http://www.christine-project.org/

    ]]>
    http://islascruz.org/html/index.php/blog/show/Christine_for_today.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine_for_today.html Wed, 14 Mar 2007 19:11:43 -0500
    <![CDATA[ Christine moves.. ]]>
  • demrit have been working in the code clean and he is doing a very great job.
  • He also create some clases like Singleton and Validator, and improve some others.
  • Christine has been moved from cvs to svn.
  • There are some ideas about the Plugins stuff, we are still researching.
  • We are three developers now (demrit, nibblesmx and me, although only demrit have been working in this week).
  • SVN code is broken by now but it will be fixed when the code clean gets done.
  • ]]>
    http://islascruz.org/html/index.php/blog/show/Christine_moves.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine_moves.html Fri, 09 Mar 2007 09:49:36 -0600
    <![CDATA[ Improved C launcher ]]> When I create the Christine launcher embedding Python into a C binary, I thought that the PyInitialize function creates the global environment and pases the arguments to the python script executed by PyRun_SimpleString(). Bud it doesn't. So, I have to use PyRun_String and create a Python list with the arguments and then, assign them to the sys.argv property in order to be used by the Python christine code.
    Thanks to Zodman and nibblesmx who help me with this C hell. ]]>
    http://islascruz.org/html/index.php/blog/show/Improved_C_launcher.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Improved_C_launcher.html Wed, 21 Feb 2007 07:56:22 -0600
    <![CDATA[ Py2exe ]]> Py2exe, meramente por cuestiones de trabajo, mas que por gusto (entiendase: "Estoy usando Windows por cuestiones de trabajo mas que por gusto"), como diria el buen v1s0r: "Primero comer que ser cristiano".
    En fin, este modulo extiende las opciones de otro modulo llamdo distutils, y aprovechandonos del archivo setup.py podemos pedirle a python (por medio de py2exe) que nos genere un binario en windows que aparte de la ventaja de ser binario (para quienes no quieren compartir el codigo) evita la dependencia con Python. Obviamente, tu progamita de 30K se te va a 4 megas o mas dependiendo de los modulos que necesita.
    Actualmente lo he ocupado para la chamba y aprovechando lo que ya sabia, pues hice lo mismo con mi programita de inventario en mi negocio, esto si, nomas por gusto.
    De ahi te creas tu instalador con el Nullsoft Scriptable Install System y vual???????, te codeas en Python felizmente, no expones tu codigo (si es un programa propietario) y tu cliente sigue feliz porque no necesitar??????? instalarse Python en su sistema (al menos no por ti).
    Habia mencionado que puedes incluso hacer servicios con esto?, Pues se puede, pero presta atencion a crear una clase con una propiedad de nombre "_svc_name_" para poder iniciar el servicio, si no, ]]>
    http://islascruz.org/html/index.php/blog/show/Py2exe.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Py2exe.html Fri, 02 Feb 2007 18:30:00 -0600
    <![CDATA[ God Bless the Free Software ]]> Anyway, I try to fix the code, and upload new packages, wishing they work now, and then allow me to launch christine 0.0.4 in the next weeks.
    Btw, SuSE Linux users, check this
    Is there any Ubuntu user trying to run Christine 0.0.3 ?.
    Fun! ]]>
    http://islascruz.org/html/index.php/blog/show/God_Bless_the_Free_Software.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/God_Bless_the_Free_Software.html Tue, 23 Jan 2007 15:14:43 -0600
    <![CDATA[ Christine 0.0.3 ]]> Esta es la tercera entrega de las versiones de desarrollo de Christine. De vuelta, esta es una version para quellos que quieren explorar Christine o para aquellos que no se pueden esperar para tener un reproductor Chido y ligero.
    He estado trabajando en la interface de plugins, incluso cuando esta en una etapa de desarrollo muy temprana puede ser util para alquien que ya est??????© pensando en algun plugin.
    El nuevo lanzador escrito en C evita esa linea de comandos de "python" en la tabla de procesos. Ahora veras "christine" en tu tabla.
    Cuando se utiliza el visualizador o se reproduce algun video el protector de pantallas se desactiva. (Solo funciona con xscreensaver, algun bondadoso que quiera aventarse el parche para hacer lo mismo con gnome-screensaver? [Yo no tengo gnome-screensaver instalado])
    Se puede descargar de aqui: [Download]
    Y no olvides reportar los bugs en el [Tracker] ]]>
    http://islascruz.org/html/index.php/blog/show/Christine_003.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine_003.html Mon, 22 Jan 2007 15:38:29 -0600
    <![CDATA[ Imprimiendo usando GTK ]]> GTK+ dentro de Linux tiene ya mucho tiempo con los usuarios, se ha dado gracias a Gnome, mas no por GTK. Hasta hace poco GTK+ carec??????­a de un API para impresi???????n, y muchos tenian que integrar Gnome para poder hacer uso de este servicio.
    Bien, a partir de la version 2.10 de GTK+ se cuenta con un API para imprimir que si bien por ahora se utiliza en sistemas UNIX se pretende que sea un sistema portable para imprimir, es decir que con el mismo codigo se pueda imprimir tanto en Unix como en Windows.
    Bien, hoy por la ma??????±ana, yo digo que fue por que madrugu??????© me avente un clavado en busqueda de documentacion para usar la API de impresiond e GTK (pygtk precisamente) y no encontre ni madres, mas que un ejemplo que vi en este documento (P???????ginas 12 y 13). Y usando ese ejemplo hice lo mismo en Python:
    #!/usr/bin/env python
    import gtk,cairo
    def draw_page(PrintOperation,PrintContext,Page):
        context = PrintContext.get_cairo_context()
        context.set_source_rgb(1,0,0)
        context.rectangle(0,0,PrintContext.get_width(),50)
        context.fill()
        context.set_source_rgb(0,0,0)
        context.move_to(90,75)
        context.line_to(60,80)
        context.curve_to(40,70,65,65,70,60)
        context.set_line_join(cairo.LINE_JOIN_ROUND)
        context.set_line_width(5)
        context.stroke()
    window = gtk.Window()
    window.connect("destroy",gtk.main_quit)
    op = gtk.PrintOperation()
    settings = gtk.PrintSettings()
    op.set_print_settings(settings)
    op.set_n_pages(1)
    op.set_unit(gtk.UNIT_MM)
    op.connect("draw_page",draw_page)
    op.connect("done",gtk.main_quit)
    response = op.run(gtk.PRINT_OPERATION_ACTION_PRINT_DIALOG)
    if response == gtk.PRINT_OPERATION_RESULT_APPLY:
        settings = op.get_print_settings()
    gtk.main()
     
    y el resultado a la hora de imprimir es este:

    Print dialog in GTK dsc05756.jpg

    Como ven, no es tan dificil, lo dificil es "dibujar" el documento con Cairo :-). En fin..
    Nota: No, no es degradado el rectangulo ese, mi tonner rojo ya esta valiendo madres. ]]>
    http://islascruz.org/html/index.php/blog/show/Imprimiendo_usando_GTK.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Imprimiendo_usando_GTK.html Mon, 22 Jan 2007 11:43:34 -0600
    <![CDATA[ christine with the C launcher ]]> Christine have at the time I'm writing this a C written launcher. But Why?. Ok, this is Why: Its cooler to see christine in the process table than python christine.py. And when you want to kill christine you don't have to look into the python processes the PID of the python process running christine, just "killall christine" or something, those Deskbar Applet users will thank this :-)
    It works to me, and I will apreciate if you check it, mainly for the compiling issues in the makefiles. Code is available in the CVS.

    Screenshot-2.png
    ]]>
    http://islascruz.org/html/index.php/blog/show/christine_with_the_C_launcher.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/christine_with_the_C_launcher.html Wed, 17 Jan 2007 21:10:01 -0600
    <![CDATA[ Incorporando python en nuestros proyectos en C ]]> para evitar que el pid sea python.
    Cuando corremos un programa en python a estilo python miscript.py y vemos la tabla de procesos veremos que el pid pertenece al programa "python" y dentro de sus argumentos tenemos el "miscript.py", incluso cuando ejecutemos nuestro script asi: "./myscript.py". Mayor problema, no vamos a estar mirando la tabla de procesos siempre, o si? ;-)
    El problema, al menos conmigo es que soy muy huevon para andar buscando el pid y cositas asi, yo prefiero un "killall python", lo malo es que me termina mantando otros procesos de python como mi shell interactiva con la que practico peque??????±as piezas de codigo, o el mendigo (chupa-recursos) deskbar :-P.
    La soluci???????n, empotrar Python en un "lanzador" en C. el ejemplo que les pondre es la forma mas raza, escuata y todo lo que se puedan imaginar, pero funciona >:-), es algo que ya hice con Christine
    Primero moveremos nustro lanzador original escrito en python a algun paquetin
    cp christine lib_christine/christine.py
    Luego creamos el lanzador en c:
    #include
    int
    main(int argc, char *argv[])
    {
      Py_Initialize();
      PyRun_SimpleString("from lib_christine.christine import *\n"
                         "a = christine()\n"
                         "a.main()\n");
      Py_Finalize();
      return 0;
    }
     
    compilamos y enlazamos:
    $ gcc -Wall -O2 -march=k8 -mtune=k8 -I/usr/include/python2.4/ -c christine.c -o christine.o

    $ gcc -Xlinker -export-dynamic christine.o /usr/lib/python2.4/config//libpython2.4.a -lnsl -ldl -lreadline -ltermcap -lieee -lpthread -lutil -lm -o christine
    y vual???????, listo :-).
    Screenshot-2.png
    ]]>
    http://islascruz.org/html/index.php/blog/show/Incorporando_python_en_nuestros_proyectos_en_C.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Incorporando_python_en_nuestros_proyectos_en_C.html Wed, 17 Jan 2007 18:22:47 -0600
    <![CDATA[ Trabajando con gstreamer:: Usando los Bins ]]> Ok, el Playbin solo permite empotrar un elemento de audio para el sink de audio, lo que nos impide meter dos elementos, digamos "autoaudiosink" y nuestro "ecualizador", Tambien seria un pedote escribir nuestro "audiosink" por completo, lo unico que queremos es empotrar un ecualizador sin tener que programar todo. Bien, aqui es donde entran los Bins.
    Un GstBin permite "empacar" elementos dentro de ??????©l. Como un GstBin es en si un elemento, este puede ser empotrado en el PlayBin. Para crear el Bin utilizaremos gst.element_factory_make("bin"). Luego agregaremos los sinks con el metodo "add".
    audio = gst.element_factory_make("autoaudiosink")
    bin = gst.element_factory_make("bin")
    bin.add(audio)
     
    Hasta aqui el bin ya tiene empacado el elemento "audio" que ahora es propiedad de bin, si se destruye bin se destruye al elemento "audio". Hasta aqui todo bien, la cuestion es que el mismo bin no cuenta con ningun pad. Un pad es un "conector" entre los elementos, si no hay pads no hay donde conectar.
    Es aqui donde entra el GhostPad, El GhostPad nos permite crear un pad sintener que crear el elemento que lo contendr???????, y podemos enlazarlo (conectarlo) a un pad que si se encuentre dentro de un elemento. Luego, agregamos este pad a algun elemento y vual???????!!.
    import gst
    audio = gst.element_factory_make("autoaudiosink")
    ecualizador = gst.element_factory_make("ecualizador") #elemento ficticio
    bin = gst.element_factory_make("bin")
    bin.add(audio)
    bin.add(ecualizador)
    audio.link(ecualizador)
    # enlazamos con el pad "sink" de audio
    # Note que el nombre del pad es "sink" esto es importante porque
    # playbin busca por el pad con nombre "sink"
    ghost_pad = gst.GhostPad("sink",audio.get_pad("sink"))
    bin.add_pad(ghost_pad)
    # En este punto el bin ya tiene un elemento adentro (audio) y tiene un pad para poder
    # ser conectado
    playbin = gst.element_factory_make("playbin")
    playbin.set_property("audio-sink",bin)
     
    El pad con nombre "src" no es necesario ser creado, el playbin lo har??????? para poder enlazar los elementos (audio,video,visualizaci???????n). ]]>
    http://islascruz.org/html/index.php/blog/show/Trabajando_con_gstreamer_Usando_los_Bins.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Trabajando_con_gstreamer_Usando_los_Bins.html Mon, 15 Jan 2007 15:10:54 -0600
    <![CDATA[ Trabajando con gstreamer::Creando un Playbin ]]> Gstreamer es muy flexible, y se trabaja con pipelines, que vendria siendo como un conducto por el cual nuestro archivo de audio/video ha de pasar para ser procesado y poder llegar a nuestra pantalla/bocinas, tecnicamente se construlle un pipeline, luego se crean y se enlazan elementos (fuentes, demuxers, sinks etc..), se enlazan los elementos.... y al final del tunel se ve la luz. Pero esto es mucho trabajo para aquellos que son noveles con gstreamer y puede ser algo tedioso otros.
    Afortundamente gstreamer incluye un elemento llamado "Playbin", un playbin es un pipeline ya hecho, con otras funciones que permiten especificar el sink de audio, el de video y el de visualizacion. automaticamente determina el de fuente y en caso de no definirse los elementos de audio y video utiliza unos por defecto.
    Con esto podriamos de manera sencillicima empotrar un "mini-reproductor" a nuestras aplicaciones, por ejemplo, cuando querramos tener una "vista previa" de un archivo de audio, podriamos empotrar un miniplayer que tenga un boton play y que toque (de ser posible) el archivo seleccionado, para saber si es o no el indicado.
    Para crear un playbin utilizaremos la funcion "element_factory_make" esta funcion nos crear??????? un objeto de tipo GstElement, digamos que vendria a ser algo asi como un Widget en Gtk.
    import gst
    playbin = gst.element_factory_make("playbin")
     
    Con esto tenemos un elemento GstPlaybin, que ya incluye el pipeline, demuxers etc.. lo que nos resta es tunerarlo. Podremos modificar el audio-sink y video-sink por medio de sus propiedades:
    audio_sink = gst.element_factory_make("gconfaudiosink")
    playbin.set_property("audio-sink",audio_sink)
    video_sink = gst.element_factory_make("gconfvideosink")
    playbin.set_property("video-sink",video_sink)
     
    No hay necesidad de enlazar los elementos, el playbin lo har??????? por si mismo :-). En este ejemeplo estamos usando los sinks de gconf, para los usuarios de Gnome, estos retornan el sink establecido con gstreamer-properties. otros sinks validos los pueden buscar con gstreamer-inspect |grep sink.
    Ahora.. como hago que el playbin toque algo?. Sencillo, el playbin tiene una propiedad llamada "uri", un uri describe la ubicacion de un archivo, puede ser un archivo local, o en algun servidor remoto, o tal vez sea un track dentro de un dvd, o un CD de audio. Un uri, define su "protocolo" al inicio, tal y como lo hacen las direcciones de las paginas web "http","https" u otros protocolos como "ftp","rsync", etc..
    ejemplos:
    uri = "file:///home/markuz/algunmp3.mp3"
    uri = "http://www.islascruz.org/algunvideo.ogg"
    uri = "cdda:///1"
    uri = "dvd:///4"
     
    Obviamente, la capacidad del playbin para poder parsear el uri y reproducir el objeto depende de los plugins instalados.
    Una vez hecho esto, podremos decirle al playbin cual archivo tocar.
    import gst
    playbin = gst.element_factory_make("playbin")
    uri = "file:///home/markuz/algunmp3.mp3"
    audio_sink = gst.element_factory_make("gconfaudiosink")
    playbin.set_property("audio-sink",audio_sink)
    video_sink = gst.element_factory_make("gconfvideosink")
    playbin.set_property("video-sink",video_sink)
    playbin.set_state(gst.STATE_READY) #El playbin debe estar listo
    playbin.set_property("uri",uri)
    playbin.set_state(gst.STATE_PLAYING)
     
    Listo, con esto empezar??????? a tocar :-).
    Otras propiedades del playbin se pueden conocer con gst-inspect playbin ]]>
    http://islascruz.org/html/index.php/blog/show/Trabajando_con_gstreamerCreando_un_Playbin.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Trabajando_con_gstreamerCreando_un_Playbin.html Sun, 14 Jan 2007 21:28:39 -0600
    <![CDATA[ Lazy days and Plugins ]]> Lazy days:
    I have been so lazy this days, this is something that I believe is temporal, just like one of those days that I may spend coding all the fucking day. And I know what to do, I know what needs to be done, and I would like to do it, but im so lazy.
    And that's why christine is taking to long in get mature. I spit some lines in the day but not a real work. I just didn't really feel so inspired.
    But.. There is something...
    Plugins:
    I have, in this few inspirations, work over the plugins stuff, Its still very very early but, I'm trying to make a god environment to become christine into a plugable application. At this time I'm just creating the public interface, but also converting the "show properties" action (menu: edit/show properties) that show the tags of the selected item in the library, to a plugin. So, isn't by now a lib_christine package module. Ok, here is the shot:

    Show properties

    Somebody with plugins implementation knownledge and good will to work over this stuff, give me an email :-). ]]>
    http://islascruz.org/html/index.php/blog/show/Lazy_days_and_Plugins.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Lazy_days_and_Plugins.html Sat, 13 Jan 2007 19:44:05 -0600
    <![CDATA[ Hablando del uso de seÃ?Æ?Ã?±ales. ]]> eso que puse en el post anteterior en christine, si te descargas el codigo del CVS de christine te dar???????s cuenta que aun utiliza gobject a la hora de importar los elementos, y he aqui la razon.
    Este aparato funciona bien, con pocas canciones, digamos unas 15 canciones me las importa en un chingadazo, digamos 1 segundo tirandole a 2 lo que con gobject tardaria unos 5 segundos cuando mucho, y se ve la barrita de progreso en chinga con 1/15, 2/15, 3/15 conforme se van importando con etiquetas y todo (recuerda que no se avisa que se cargue otro archivo hasta que se han encontrado las etiquetas), el problema es que cuando quiero cargar unos 175 archivos esta madre lo hace tan en chinga que por quien sabe que puta razon me satura el pinche playbin (discoverer.. recuerda, es un playbin a fin de cuentas) y me comete una falla de segmento debido de meterle tan rapido elementos al playbin.
    Ya intente utilizar gobject para retrazar la inserci???????n por unos cuantos milisegundos sin llegar a afectar tanto (unos 200 milisegundos serian suficientes), he tratado de usar threads y nomas no se que tranza.
    Alguien tiene una idea? alguien que tambien est??????© trabajando co gstreamer? ]]>
    http://islascruz.org/html/index.php/blog/show/Hablando_del_uso_de_seales.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Hablando_del_uso_de_seales.html Sun, 07 Jan 2007 21:24:23 -0600
    <![CDATA[ Utilizando las seÃ?Æ?Ã?±ales ]]> Gtk+ es genial para esto porque ya implementa un sistema de se??????±ales que podemos ajustar a nuestro programa.
    Por ejemplo, en christine a la hora de importar archivos los someto a un "descubridor", este chunche abre el archivo, busca por las etiquetas y avisa cuando hay etiquetas, luego, la biblioteca actualiza los campos con las etiquetas. En realidad no es mas que un playbin con fakesinks del cual tomo el bus y lo conecto a un watcher, cuando existe un mensaje de etiquetas agrego las respectivas etiquetas a la lista.
    Hasta aqui bien, pero al momento christine lo que hace al importar los archivos es utilizar un repetidor con "gobject.timeout_add", la ventaja es que funciona bien y es decentemente rapido, lo malo es que en CPUs con buenca capacidad no es enteramente aprovechada esta capacidad. Posible solucion, que se emita una se??????±al a quien llama cuando se descubran las etiquetas.
    Para hacer que nuestro objeto emita la se??????±al heredaremos de gtk.Widget y haremos esto:
    class library(gtk.Widget):
    ...
        def __init__(self):
            gobject.signal_new("tags-found",self,
                gobject.SIGNAL_RUN_LAST,
                gobject.TYPE_NONE,
                (gobject.TYPE_PYOBJECT,))
        def add_file(file):
            #algun codigo para agrear el archivo...
        def watcher(self,bus,message):
            # Algun codigo para manejar los mensajes
            self.emit("tags-found",self)
    def do_something(widget,userdata):
        #Codigo para manejar la se??????±al.
    li = library()
    li.connect("tags-found",do_something)
     
    Heredamos gtk.Widget para tener acceso a algunos elementos de gobject, si no se lo ponemos nos va a rebusnar sobre gobject.TYPE_PYOBJECT y utilizamos gobject.signal_new para definir nuestra se??????±al. Despu??????©s utilizamos self.emit para emitir la se??????±al. Obviamente, quien tenga una instancia a nuestro objeto debe conectar la se??????±al a un manejador.
    De esta forma nuestra clase library que resulta en un objeto heredado de gtk.Widget y no se empaqueta ni se muestra ni nada o aunque contenga otros widgets (por ejemplo, un gtk.TreeView y un gtk.TreeModel), puede emitir se??????±ales y puede alertar (en este ejemplo) que se han encontrado las etiquetas y que es hora de cargar un nuevo archivo. ]]>
    http://islascruz.org/html/index.php/blog/show/Utilizando_las_seales.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Utilizando_las_seales.html Sun, 07 Jan 2007 20:45:06 -0600
    <![CDATA[ Working in the plugins stuff. ]]> The plugins interface is still a mockup, and have to define public methods and properties available in the plugins to change the christine look and feel. At the moment, just let me show you how it looks like.

    Christine with a plugin

    I have also embed the lists queue and sources (and many others that may be) in the notebook. ]]>
    http://islascruz.org/html/index.php/blog/show/Working_in_the_plugins_stuff.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Working_in_the_plugins_stuff.html Wed, 03 Jan 2007 20:35:43 -0600
    <![CDATA[ Controlling Your Environment Makes You Happy ]]> MaoP por apuntarme a este enlace en donde el autor hace un __buen__ comentario sobre el dise??????±o de interfaces.
    A user interface is well-designed when the program behaves exactly how the user thought it would.
    Estoy de acuerdo con eso, aunque la forma en la que esta persona lo explica... mmm.. no tanto.
    Joel Spolsky en este capitulo menciona que el amigo inform???????tico (windowsero por tradicion y que se cree la gran piola porque hizo macros en word) de una ni??????±a (mac-quera porque le gusta lo bonito de la carcasa) se pone a mentotearle la madre a los de apple (en sentido figurado) porque no pudo hacer las cosas igual que en Windows. Veamos por que (miren que les estoy ahorrando una explicacion sobre el trabajo en una panaderia que tuvo este wey).
    Resulta que el amigo inform???????tico esta acostumbrado a usar Alt+F4 para cerrar sus ventanas, cuando en Mac, segun Joel (no me consta, nunca he tenido/usado una Mac) sirve para subir el volumen. El tipo queria redimensionar una ventana agarrandola por la orilla y moviendo el puntero, en mac esto no sirve y te mueve la ventana. El tipo esta acostumbrado a cerrar todo tipo de cuadro de dialogo con solo precionar la barra espaciadora, algo que hace por reflejos mas que por razon, y cuando quizo hacer eso en Mac, nomas no pudo.
    Bien, en esto se apoya Joel para decir que uno se siente bien cuando el usuario espera tener el control de las cosas, como el amigo inform???????tico no pudo hacer eso que hace en Windows pues se fue mentando madres, Ok, puede ser, pero con todo respeto, que usuario tan pendejo, si de antemano sabes que es Mac y no "Windows" debes saber que algo ha de cambiar, digo, no es lo mismo usar un Tsuru y un Cadillac.
    Lo digo porque, si bien estoy de acuerdo en que el usuario debe tener el control de lo que usa, no deberia tener un falso control de lo que usa. No porque en Mac las ventanas se cierren o redimensionen diferente que en windows quiere decir que la interface de usuario sea una porqueria, tal vez la chica macquera queria que asi fueran las cosas y ella si tenia el poder, el control de su ambiente de trabajo ????????a ver cambiele eso en Windows?.
    Y si a esas nos ponemos Windows, en mi humilde opinion no sirve, ????????porque tengo que hacer doble click en la barra de titulo para maximizar? cuando puedo presionar Ctrl+F10, y Ctrl+F5 para des-maximizar. ????????Por que debo tomar una orilla de la ventana para redimencionarla? si con Ctrl+Alt+Boton3 puedo redimencionar y sin tener que afinar mi punteria para agarrar bien la esquina/borde. ????????Por que debo tomar la barra de titulo para mover mi aplicacion? Cuando con Alt+Boton1 puedo hacerlo desde cualquier lugar de mi aplicaci???????n. Y vean que estos valores son programables en Metacity, asi que Yo si controlo mi ambiente.
    Un buen dise??????±o de inteface es el que te hace la vida mas facil, no el que te hace mas pendejo, y debe aceptar que no es universal, debe ser flexible y acoplarse al usuario.
    Y no me vengan con mamadas que de la productividad y jaladas asi. Que yo puedo leer mis correos mas en chinga con Evolution aunque me haya costado 10 minutos en configurarlo que en "abrir el puto messenger, meter mi nombre de usuario y contrase??????±a, esperar a que se abra la puta ventana de MSN Hoy y hacer click en uno de los correos para ver si se abre" cada vez que enciendo la computadora (por cada correo, porque no nomas manejo una cuenta). Uno es tan productivo como uno quiere, si no se puede hacer de una manera se debe poder de otra, no sean borregos al matadero. ]]>
    http://islascruz.org/html/index.php/blog/show/Controlling_Your_Environment_Makes_You_Happy.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Controlling_Your_Environment_Makes_You_Happy.html Thu, 28 Dec 2006 21:30:18 -0600
    <![CDATA[ You know what you do... ]]> gstreamer??. Bueno, pues yo no se como sacarle eso a gst. es algo complicado porque gst esta basado en plugins, cada plugin le agrega caracteristicas como por ejemplo, poder reproducir ogg, mp3 o videos en mpeg.
    En un principio a gusto nomas puse unos cuantos formatos como wmv, avi, mpg mpeg, mp3 para poder importarlos, pero, me estaba saltando otros que igual y no conozco y que gst si puede reproducir. Luego se me ocurrio decir, chingue su madre, que se importe todo, me vale verga... y pues tampoco fue lo mejor, terminabas importando archivos de texto o los Thumb.db que te deja el puto Windows.
    Asi que pa no estarme quebrando la puta cabeza puse una pesta??????±a en el cuadro de dialogo de christine, ahi los usuarios pueden agregar/quitar/modificar las extensiones de los archivos que desean que christine importe a la biblioteca, asi si terminan importando algo que no deberia ser importado es muy su pedo :-P. Tu sabes lo que haces.

    preferences
    ]]>
    http://islascruz.org/html/index.php/blog/show/You_know_what_you_do.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/You_know_what_you_do.html Wed, 27 Dec 2006 19:08:02 -0600
    <![CDATA[ What tha fuck? ]]> Pueden descargarlo de aqui ]]> http://islascruz.org/html/index.php/blog/show/What_tha_fuck.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/What_tha_fuck.html Mon, 25 Dec 2006 18:02:12 -0600 <![CDATA[ Christine for Christmas ]]> Estoy orgulloso de anunciar que Christine ha liberado su primera version inestable. La version 0.0.1, esta version aun en faces de desarrollo es completamente usable para los fines y objetivos que Christine define, ser un reproductor de audio y video bonito y chiquito para Gnome.
    Christine depende de Gstreamer, Python, GTK 2.10 y sus bindings para Python. Si se desea se puede utilizar libnotify para ver esos popups apuntando a un icono en el area de notificaci???????n. configurable desde el area de notificaci???????n.
    Christine aun esta en fases de desarrollo y aun le faltan cosas, aunque lo he estado utilizando desde hace ya un buen rato y parece que todo va bien.
    Hago la invitacion a los pythoneros que vean esto y que se interesen en cooperar con un proyecto sencillo, aun chico y en crecimiento.
    El paquete con el codigo fuente se puede conseguir en la p???????gina de descargas.
    Feliz Navidad :-)
    Update1:: Un peque??????±o error en la linea de comandos de gcc ha sido corregido y un nuevo paquetin te espera en la zona de descargas, gracias damog por apuntarlo. Cualquier error/bug favor de reportarlo al Bug Tracker. Gracias de nuevo y feliz navidad. ]]>
    http://islascruz.org/html/index.php/blog/show/Christmas_Christine.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christmas_Christine.html Sun, 24 Dec 2006 18:04:37 -0600
    <![CDATA[ Bug Hunter ]]> Uff, que dia!!, ayer estuv e hackiando en christine por ya no me acuerdo por que.. un errorcito que queria corregir, y que correg??????­, pero que ya no recuerdo cual era. A ultimas me salio un bugcito, propio de mi precipitacion al agregar una caracteristica y no hacer las pruebas adecuadas.
    Entre las coas que hice para corregir ese errorcito original tuve que borrar mi actual lista de canciones, asi que intente regenerarla, vaya, volver a importar todo el desmadre, cuando me voy dando cuenta que a las 300 canciones el uso del CPU se me iba al 90%, yo nomas dije Verga!!:-O.
    El problema es que tengo un metodo que me hace una busqueda dentro del modelo por algun archivo dado. Pues tambien se me ocurrio que cuando el elemento de busqueda sea igual a "" se hiciera saltara y seleccionara la cancion actual. Para poder hacer eso hay un metodo que se llaman jump_to y se le da el nombre actual, este hace la busquda usando el metodo de busqueda y luego utilizando el gtk.TreeIter almacenado en current_iter para poder crear un gtk.Path y saltar (y seleccionar) la fila.
    Pues esta cosa se estaba repitiendo cada vez que se insertaba un elemento en el modelo y yo ni encuenta, pero por que se repetia si yo no estaba haciendo una busqueda, estaba insertando elementos en el modelo. Bien, la respuesta es esta, cuando uno usa un gtk.TreeModelFilter y se insertan elementos este ejecuta el metodo asignado en TreeModelFilter.set_visible_func() para monstrar/esconder el nuevo elemento, lastima que no hace esto en la nueva fila que se ha insertado, sino que recorre tooooooodo el puto modelo.
    Obvio, para los 300 elementos insertados esta madre ya estaba pariendo chayote porque estaba dandole madres con gstreamer sacando las etiquetas de las canciones insertando elementos en el modelo y repasandolo 2 veces por segundo.
    En fin... una mega mamada que yo no me di cuenta de esa hasta las ultimas, estuve dale y dale y dale, megaoptimice mi pinche codigo pensando que era un pedo al importar, me refiero al usar la funcion de importar, buscar el tiempo de la cancion y las etiquetas etc.., y no, fue una cosa casi casi ajena, de haber sabido.... Todo el puto dia rompiendole su madre a christine y con un puto comentario lo hubiera borrado.
    Mierda.. me siento basurita, lo unico bueno de todo esto es que mejore christine en la busqueda de el puto bug ese.

    Another Christine screenshot
    ]]>
    http://islascruz.org/html/index.php/blog/show/Bug_Hunter.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Bug_Hunter.html Sat, 23 Dec 2006 21:09:03 -0600
    <![CDATA[ Christine and the i18n job ]]> christine, he subido algunos archivos .po al CVS y un peque??????±o script para sacar las cadenas traducibles de los descriptores de interface hechos con Glade-3 y los que se escriben directamente en el codigo, por ejemplo los titulos de las columnas.
    Hablando de Glade, usando glade 2 puedes pedirle a glade que todas las cadenas traducibles te las guarde en un archivo de texto plano, estas cadenas puedes ser facilmente obtenidas con xgettext usando la codificacion de C. Pues vaya relajo, que con Glade-3 estos archivos ya no se obtienen asi nomas, para poder obtenerlos es necesario usar directamente xgettext y utilizar el parametro "--from-code=Glade". En fin, asi si se pudo.
    Ahora tengo un peque??????±o problema, la ventana principal de chirstine, o sea, el mero mero reproductor no se traduce. Las cadenas traducidas estan instaladas, y para cargar los descriptores de interface utilizo un wrapper (clase glade_xml) que asigna el directorio de los "locales", y usa bindtextdomain, y textdomain. En todos los mendigos descriptores de interface funciona, menos en el de interface, los menus todos en ingles (menos los que usan elementos de stock), tooltips, etiquetas, etc.. todo en el idioma en el que lo puse en glade :-/ . Que ser??????? que esta fallando?
    En fin, sigo trabajando sobre esta cosa... ]]>
    http://islascruz.org/html/index.php/blog/show/Christine_and_the_i18n_job.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine_and_the_i18n_job.html Fri, 22 Dec 2006 16:51:16 -0600
    <![CDATA[ Christine clibrary ]]> modulo de mismo nombre en Christine.
    Debo decir que en Python, me sorprende que la velocidad pocas veces sea un problema :-), y que la diferencia de velocidad entre C y Python no es mucha, aun asi hice esta implementacion mas como prueba que como algo que es realmente necesario, es como un "pega y corre".
    Christine normalmente toma poco menos de 2 segundos en crear todo, desde cargarse las interfaces, crear el modelo y lo mas pesado, llenar el modelo con las 1751 canciones que tengo, que bueno, no son muchas. La diferencia no es mucha, pero repito, no son tantas canciones y si alguien por ahi mete unos 5000 elementos no quiero que espere 10 segundos a que se cargue christine.
    He aqui la prueba :-):
    pgen_model

    0

    set: /apps/christine/control/CONTROL_STAT 1

    Not to miniviewer

    set: /apps/christine/ui/small_view False

    set: /apps/christine/control/volume 0.5
    real 0m1.327s <==Hecho con Python

    user 0m1.057s

    sys 0m0.084s

    cgen_model

    0

    set: /apps/christine/control/CONTROL_STAT 1

    Not to miniviewer

    set: /apps/christine/ui/small_view False

    set: /apps/christine/control/volume 0.5
    real 0m0.990s <== Hecho con C

    user 0m0.785s

    sys 0m0.048s
    No elimine el metodo en python, simplemente hice un empapelado y al utilizar "--clibrary" como argumento en la linea de comandos ejecuta el metodo en C (cgen_model) mientras que ejecutando christine directamente carga con el metodo hecho en Python (pgen_model). El parametro "-q" hace que Christine se muera (sys.exit()) al terminar de cargar todo, obviamente nomas ves que aparece la ventana un segundo y zas, ya se fue.
    En fin, solo queria comentar esto :-). Igual y hace implementaciones en C de otros puntos criticos de Christine >:-) ]]>
    http://islascruz.org/html/index.php/blog/show/Christine_clibrary.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine_clibrary.html Thu, 14 Dec 2006 15:04:45 -0600
    <![CDATA[ Tengo que aprender C!! ]]> Working with AnjutaSi, su programador favorito (umj???????) no sabe C, es decir, no estoy tan perdido, pero solo se lo basico, lo mas basico de C, cosa que me medio ense??????±??????? un profesor en la universidad, lo unico que me sirve de consuelo es mis compa??????±ero de escuela estan mas pendejos que yo y no saben ni siquiera armar una funcion en C ni en algun otro lenguaje, vaya, no saben ni programar en Visual Basic (y eso para un ing. en sistemas es mucha mamada).
    Otra cosa que me sirve de consuelo es que se programar en otros lenguajes como PHP,Python y JavaScript, pero aun no se casi nada de Java que tambien tengo que aprender, y en el post de hoy C.
    Bien, pues ya empec??????©, a ver que tanto le avanzo, cosa de perderle el miedo, lo malo es que voy yo solito sobre esta onda a ver si no me confundo de mas. :-S ]]>
    http://islascruz.org/html/index.php/blog/show/Tengo_que_aprender_C.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Tengo_que_aprender_C.html Fri, 08 Dec 2006 15:51:00 -0600
    <![CDATA[ Christine con el display hecho en Cairo ]]> jugando con cairo y que pensaba incluir un display en Christine hecho con cairo, para quitarme de las etiquetas que se muestran y eliminar de paso el gtk.Scale que hasta hoy se usaba para ver el avance de la cancion.
    Bien, pues ya hoy en la tarde me puse a jugar con este desmadre hoy otra vez, y por fin puli un poquito mas el widget ese y lo incruste en christine ;-). Aun me falta pulirlo mas, pero tenia que presumir un poco :-P.

    christine

    Por cierto, es Apocalyptica, no Apocolytica, alguien me paso esa rola y le pusieron mal las etiquetas. ]]>
    http://islascruz.org/html/index.php/blog/show/Christine_con_el_display_hecho_en_Cairo.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Christine_con_el_display_hecho_en_Cairo.html Fri, 01 Dec 2006 22:08:06 -0600
    <![CDATA[ Inventario...(avance?) ]]> Se acuerda usted de esto, pues es una aplicacioncita que me hice hace unos cuantos meses para llevar el control de mis chucherias que tengo y que vendo en mi negocio, originalmente (y hasta el momento) esta pensado primordialmente para que cumpla su objetivo mera y razamente, o sea que no tiene todas esas mamadas y complicadeces que tiene esas aplicaciones comerciales porque simplemente No las necesito.
    Bien, continuando, la chucheria esta esta escrita en Python (ya lo sabias, pero como quiera va) y se conecta con una base de datos manejada por MySQL. Lo shido es que Python es multiplataforma, MySQL tambien, GTK Igual, PyGTK... yer, o sea, lo que necesita esta cosa para trabajar existe al menos en las dos plataformas que uso: Windows y Linux.
    Pues, bien, este mismo proyecto lo estoy agarrando de ejemplo para mi tesis, mi tesis habla sobre como desarrollar aplicaciones de manera rapida con Python, GTK y Glade, asi que es el ejemplo perfecto, porque aparte de ser un ejemplo sencillo, que escribi en unos cuantos dias, muestra el uso de la mayoria de los widgets de GTK (Windows, dialogs, Scrollbars, SpinButton, ToolBar, botones [checkbuton, normales, toolbutton], Modelos, Treeview, TextView, Frames, etc..). Peeeero, asi como estaba no me sirve, esta demasiadamente sencilla, ranfla y con un chingo de cosas que faltan por pulir y a las que no le dedique tiempo, por que?, porque soy webon.
    Bien, antier, ayer y hoy me puse a darle esta madre, tres dias, bueno, tres medios dias, me bastaron para pulir las cositas que me hacian falta (sin agrear mas desmadre), para que sea una aplicacion de uso mediano, completamente funcional y que ademas, me sirva para poner de ejemplo sencillo, porque tiene que ser lo suficientemente sencillo como para que alguien que se interese en aprender pueda comprenderlo.
    Bueno, el chiste es que la cosa ahi va, y les dejos las capturas de que la cosa esta funciona tanto con los buenos como con los no tan buenos.

    inventario The Systems
    inventario The Systems
    ]]>
    http://islascruz.org/html/index.php/blog/show/Inventarioavance.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Inventarioavance.html Fri, 24 Nov 2006 18:50:38 -0600
    <![CDATA[ Python y sus extensiones en C ]]> A pesar de que python es un lenguaje interpretado, es mucho mas rapido que otros lenguajes, y si esto no es suficiente, es posible escribir extensiones en C para las partes mas "rudas" del programa.
    Como todos saben (y si no ya lo va sa saber), estoy escribiendo un programita en Python que se llama Christine, que es un reproductor de audio y video basado en gstreamer y que utiliza GTK+ para la interfaz grafica, ok, una de mis preocupaciones con christine es hacer que la lista de elementos (musica y videos) se genere lo mas rapido posible, lo mismo con las busquedas.
    Los elementos se almacenan en un diccionario, que vendria siento un array por referencia (no indexado, donde no hay un orden en especifico y los elementos se llaman por un nombre de llave) , para agilizar las cosas actualmente utilizo el modulo cPicle. Este modulo crea un archivo de texto con algunos simbolos para poder almacenar un diccionario, lista, tupla, cadena, etc. cPicle es mas o menos la misma cosa que picle, la diferencia es que cPicle esta hecho completamente en C y por ende es mucho mas rapido que picle. Ok, pero una vez con el diccionario lo que sigue es llenar la lista de elementos (en un gtk.ListStore), para esto obtengo las llaves del diccionario, y despues hago una iteracion sobre las llaves para asi obtener los elementos del diccionario e ir insertando uno a uno en el modelo.
    Al momento he estado trabajando con una lista de cacines de poco mas de 1600 elementos y tarda uno o dos segundos en llenarme la lista, eso no es lo alarmante, lo que me preocupa es trabjar con christine con unos 10000 elementos?, claro, yo no creo tener tantos en una lista de reproduccion, pero hay que hacer las cosas para que aguanten. Asi que me puse a ver si podia hacer una extension en C para hacer este ciclo. Obviamente la creacion del modelo, los gtk.TreeIter, la inserci???????n y lo demas, esta practicamente hecho en C (aunque se usen los bindings de Python), lo que tal vez podria mejorar es a la hora de hacer el ciclo.
    No lo he implementado en christine, pero he hecho algo base, sobre todo para pruebas, y he visto que, tal vez porque la insersion de elementos en el modelo y creacion de iteradores esta hecho en C, o porque juego con funcions de Python desde C, el resultado no cambia mucho, incluso, en ocaciones (debido a otros procesos en mi equipo) Python hace las cosas mas rapidas. Ojo, esto con una diccionario de 1600 elementos e insertando en un modelo de una sola columna. En vista de que el resultado es casi casi el mismo, pues intente hacer lo mismo pero tomando como referencia un archivo de texto e iterar sobre cada uno de los caracteres que lo componen (eliminando los retornos de carro y los espacios en blanco).
    El elemento a tratar: el manual de bash (markuz$ man bash > texto;), una vez abierto el texto desde Python, se pasa este texto a una funcion en el modulo escrito en C, esta funcion devuelve un diccionario que se pasa la funcion que llenara el modelo. el resultado: C le gano a Python como por 1 segundo en todo el proceso (crear el diccionario y llenar el modelo). pero con unos 314227 elementos en lista. :-o, en fin. los resultados son estos:
    markuz$ time python libtest.py -c

    longitud del modelo: 314227
    real 0m7.478s

    user 0m7.182s

    sys 0m0.138s
    markuz$ time python libtest.py

    longitud del modelo: 314227
    real 0m8.582s

    user 0m8.268s

    sys 0m0.134s
    El parametro -c al llamar el script hace que este ejecute la funcion en C, si no se encuentra se hace todo con Python. Note que son 314227 elementos en la lista!!!!, quien tiene tantos elementos en la lista de reproduccion?, ni napster >:-).
    En fin... de que hacer las extensiones en C es mucho mas eficiente (con respecto a velocidad en proceso) si lo es, pero es mucho mas facil escribir en Python :-), asi que si no merece la pena hacer dicho esfuerzo no lo hagan XD. ahora que supongo que si toda la inserscion de elementos (gtk.ListStore.apend() y gtk.ListStore.set()) fuese escrita en Python el resultado estaria mucho mas marcado.
    Bien, en esto perdi el dia ayer, mas que nada en entender como hacer la extension, no soy muy bueno en C, y si me costo algo de trabajo :-/
    Codigo de Python
    Codigo de C ]]>
    http://islascruz.org/html/index.php/blog/show/Python_y_sus_extensiones_en_C.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Python_y_sus_extensiones_en_C.html Fri, 17 Nov 2006 15:38:30 -0600
    <![CDATA[ Sun Opens Java ]]> Sun Microsystems haya abierto el codigo de Java, para bien mas que para mal.



    Me parece perfecto que Sun haya elegido la GPL v.2 para su lenguaje :-) ]]>
    http://islascruz.org/html/index.php/blog/show/Sun_Opens_Java.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Sun_Opens_Java.html Mon, 13 Nov 2006 16:24:27 -0600
    <![CDATA[ Keep going ]]> test.py.png Sigo dandole a Cairo, hoy, aunque en menor medida, le di a esta madre para hacer una barra de progreso y poco a poco ir agarrandola para hacer el display que tanto quiero :-).
    En el programita anterior (continuacion del programa del post sobre cairo anterior) esta onda escribia en el "display" lo que uno escribia en la caja de texto, ahora la barra de progreso se llena/vacia de acuerdo a al valor entre 0 y 1 que se le indique en el SpinButton.
    Lo que queda es hacer que el texto de la cancion (lo que dice "Empty" en la imagen) se mueva (nomas por mamon) mientras que el slide se mueva de un lado pa otro conforme avanza la cancion, y aun mas me va a faltar hacer esas funciones de escala para que el cliente al hacer click sobre alguna posicion de la barra cambie la posicion de la cancion (y de la barra :-P).
    En fin... a ver en que avanzo ma??????±ana :-P. Deberia estar corrigiendo bugs en christine en lugar de estar viendo la forma de agregar mas >:-) ]]>
    http://islascruz.org/html/index.php/blog/show/Keep_going.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Keep_going.html Thu, 09 Nov 2006 21:36:51 -0600
    <![CDATA[ Aprendiendo a usar Cairo ]]> Cairo es una biblioteca que soporta multiples dispositivos de salida (X Window System, Win32, PostScript, PDF, SVG) y soporta de manera experimental algunos otros como OpenGL. Cairo esta dise??????±ado para producir una salida consistente en todos los dispositivos de salida y aprovechar las aceleracion por hardware cuando esta est??????© disponible.
    En fin, yo estoy desde hace un tiempecito tratando de empezar a crear mis widgets personalizados, si bien no para crear todo a base de widgets personalizados si para saber como diantres se hacen. Uno de los propositos es crear un "display" para las canciones que reproduce christine en lugar de un gtk.Label y un par de botones, proyectandome muy feo, tal vez algo como el display que tiene iTunes.
    Hoy me puse a jugar con esto, y la verdad, aunque al principio esta mas perdido que cualquier cosa, ya medio le estoy agarrando la onda, comenece con los tutos que estan en la pagina de pygtk.org y en el codigo de ejemplo en el cvs de PyGTK. widget.py
    Al final del dia (si, por que ya me dolio la cabeza, desde las 10 de la ma??????±ana que estoy aqui frente a la computadora - no miento, aqui com??????­-) me comprendi bien que es lo que hacia el mendigo ejemplo y le agregue la caracterisitica de que el texto se mueva de izquierda a derecha hasta desaparecer.
    #!/usr/bin/env python
    # test for writting a custom gtk-cairo widget

    import gtk, cairo, pango, gobject
    BORDER_WIDTH = 5
    POS_INCREMENT = 5
    class test(gtk.DrawingArea):
            def __init__(self,text="Empty"):
                    gtk.DrawingArea.__init__(self)
                    self.connect("expose-event",self.expose)
                    self.set_text(text)
                    fontw,fonth = self._layout.get_pixel_size()
                    self.wpos = 0
                    self.set_size_request(100,100)
                    gobject.timeout_add(200,self.move_text)
           
            def set_text(self,text):
                    self._layout = self.create_pango_layout(text)
                    self._layout.set_font_description(pango.FontDescription("Sans Serif 34"))
           
            def expose(self,widget,event):
                    try:
                            self.area = event.area
                    except:
                            pass
                    self.create_context()
                    self.draw(self.context)
                    return False
           
            def create_context(self):
                    self.context = self.window.cairo_create()
                    (self.x,
                    self.y,
                    self.w,
                    self.h) = self.area
                    self.context.rectangle(BORDER_WIDTH,
                                                            BORDER_WIDTH,
                                                            self.area.width -2*BORDER_WIDTH,
                                                            self.area.height -2*BORDER_WIDTH)
                    self.context.clip()
           
            def draw(self,context):
                    rect = self.get_allocation()
                    x = rect.x
                    y = rect.y
                    w = rect.width
                    h = rect.height
                    context.rectangle(BORDER_WIDTH,BORDER_WIDTH,
                                    w -2*BORDER_WIDTH,h - 2*BORDER_WIDTH)
                    context.set_source_rgb(1,1,1)
                    context.fill_preserve()
                    context.set_source_rgb(0,0,0)
                    context.stroke()
                    self.write_text()
                   
            def write_text(self):
                    x,y,w,h = self.allocation
                    fontw,fonth = self._layout.get_pixel_size()
                    self.context.move_to(self.wpos,(h-fonth)/2)
                    self.context.update_layout(self._layout)
                    self.context.show_layout(self._layout)
            def move_text(self):
                    if self.wpos > self.allocation.width:
                            self.wpos = 0
                    self.wpos += POS_INCREMENT
                    self.create_context()
                    self.draw(self.context)
                    return True
    class window:
            def __init__(self):
                    self.window = gtk.Window()
                    self.window.set_border_width(10)
                    self.window.connect("destroy",gtk.main_quit)
                    vbox = gtk.VBox(False,2)
                    a = test()
                    vbox.pack_start(a,True,True,2)
                    self.window.add(vbox)
                    entry = gtk.Entry()
                    entry.connect("changed",lambda widget: a.set_text(widget.get_text()))
                    vbox.pack_start(entry,True,False,2)
                    self.window.show_all()
            def main(self):
                    gtk.main()
    if __name__ == "__main__":
            a = window()
            a.main()

     

    Cairo based widget

    En fin... al menos salio pa poner el post del dia :-P. ]]>
    http://islascruz.org/html/index.php/blog/show/Aprendiendo_a_usar_Cairo.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Aprendiendo_a_usar_Cairo.html Wed, 08 Nov 2006 19:06:33 -0600
    <![CDATA[ Tareas en christine ]]> Christine poco a poco, a paso lento (a veces muy lento) esta alcanzando su madurez. Aunque a veces no tengo tiempo suficiente como para dedicarle, me gusta el proyecto y en realidad quiero que crezca. Y una de las cosas que mas me intereza es que sea usado por los demas, tiene sentido que lo use, porque a fin de cuentas el proyecto comenz??????? por que queria que el reproductor hiciera lo que yo quiero que haga, en fin, y como no tengo todo el tiempo del mundo y aparentemente no hay mucha gente interezada en el proyecto, pues he decidido hacer unas peque??????±as tareas, para quien tenga ganas de programar un poco, para quien quiera probar sus habilidades con Python o para quien simplemente quiera jugar.
    Las tareas son sencillas, y son las siguientes: Salvo de la primera tarea, ser??????? necesario obtener el codigo fuente, que facilmente lo podr???????n cachar del CVS, informaci???????n sobre como obtener el codigo se encuentra en esta pagina: http://sourceforge.net/cvs/?group_id=167966
    Hay un bugcito reportado en el bug tracker, quien quiera echarse un clavado y ayudarme a corregirlos aqui se los pongo. Si no sabes programar, pero quieres probarlo, adelante :-), por favor hazlo y reporta todos los bugs que encuentres en el tracker: http://sourceforge.net/tracker/?group_id=167966&atid=845044. ]]>
    http://islascruz.org/html/index.php/blog/show/Tareas_en_christine.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Tareas_en_christine.html Mon, 06 Nov 2006 20:52:56 -0600
    <![CDATA[ Mas capturas de Christine ]]>
    Christine with visulaizationsChristine with visulaizationsChristine with visulaizations
    ]]>
    http://islascruz.org/html/index.php/blog/show/Mas_capturas_de_Christine.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Mas_capturas_de_Christine.html Wed, 01 Nov 2006 21:36:40 -0600
    <![CDATA[ Volviendo a Christine ]]> villahermosa y obviamente en ese tiempo ni toque la computadora con aires de programar algo, solo la use para descargar las fotos y escuchar un poco de musica (tampoco queria romper christine entonces).
    Pero en esta semanita me he sentido con ganas de programar, y tomando en cuenta que estoy esperando la revision de la tesis para poder continuar, pues en este tiempecito me he dado a programar otra vez con christine.
    christine improvementsNo he hecho mucho, pero he logrado que importar archivos a la lista sea dos veces mas rapido, lo que en algunos equipos lentos podria tal vez (por limitantes de gstreamer) crear una falla de segmento y terminar la aplicaci???????n, pero para eso estoy pensando en habilitar un modo de "importado rapido", es decir, meter en la biblioteca todas las canciones/videos a importar de a putazo, con sus nombres feos de archivo (ej. cold_play_-_the_scientist) y despues en un proceso en segundo plano actualizar los datos con tiempo suficiente, digamos una cancion por segundo. Tomando en cuenta que el usuario pone la musica y se dedica a hacer otras cosas, pues eventualmente ver??????? que su biblioteca tiene todos los datos.
    Tuve un problemita con el paquete de gstreamer que se incluye en DroplineGnome porque no me reproducia los videos en formato mpeg, y resulto ser porque no tenia libmpeg2 instalado, y por lo tanto al compilar gst-plugins-ugly (que incluyen el plugin mpeg2dec) no compilaba mpeg2dec. Pues hasta que se pudo.
    Tambien he habilitado de nuevo el visualizador, que trabaja en mi maquina bastante bien, consume un poco de recursos (eleva el uso de mi cpu al ~33% por christine) pero funciona bien :-).
    christine improvements
    ]]>
    http://islascruz.org/html/index.php/blog/show/Volviendo_a_Christine.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Volviendo_a_Christine.html Wed, 01 Nov 2006 12:52:29 -0600
    <![CDATA[ Nuevo libro y Debianizando. ]]> Hoy por fin se me hizo ir a poza rica por una fuente de poder para una compu ranfla que estoy armando, aun no pueo creer que me cobraran 300 pesos por la fuente pero es que ya me urgia. En fin, pase por la libreria de siempre y me encontre con un librito que he estado buscando desde hace un buen rato: Sistemas Operativoss Dise??????±o e implementaci???????n. No es que quiera hacer mi propio sistema operativo, pero me interezan estos temas, y creo que es un buen lugar en donde puedo aprender, sobre todo leer codigo escrito en C y aprender demasiado de este. En la misma libreria igual vi un par de libros mas de Tanenbaum sobre redes y organizacion de computadoras, que luego comprare tambien.
    Debian in a Bad monitorPor otro lado, retomando lo de la compu armada, estoy montandome un peque??????±o servidor proxy con Debian y Squid, esto para repartir de manera mas equitativa el ancho de banda del negocio porque luego hay cada cliente que se pega con 5 ventanas de YouTube u otros que se ponen a descargar como locos, y dejan a los pobres cuates que solo quieren checar su correo sin chance de salir siquiera. Agarre la compu mas ranfla porque practicamente ni la voy a tocar, instalo, configuro y ahi estara para la posteridad :-P. cucusa es mi Unix :-) ]]>
    http://islascruz.org/html/index.php/blog/show/Nuevo_libro_y_Debianizando.html markuz@islascruz.org (Marco Antonio Islas Cruz) http://islascruz.org/html/index.php/blog/show/Nuevo_libro_y_Debianizando.html Sat, 28 Oct 2006 19:47:53 -0500
    <![CDATA[ Como loco.. ]]> christine y gpkg, por el momento tengo que dedicarle un poco mas de tiempo a lo que me ha de dar de tragar, como bien me dijo el buen visor: Primero comer que ser cristiano en fin, prefiero dedicar un poco mas de tiempo las cosas que me van a redituar un poco de dinero y si tengo tiempo le dedico a christine y gpkg.
    La tesis me tiene un poco atareado, con eso de que hay que cambiarle todo para que sea mas "entendible", menos t??????©cnica y que aun asi describa todo lo que yo necesito que describa, aunque encuentro esto bastante dificil, pues mi tesis trata sobre desarrollo de aplicaciones en Python utilizando Pygtk y Glade y hablar de un lenguaje de programacion y sus herramientas resulta ser por naturaleza bastante t??????©cnico. En fin... tengo que hacerla.
    Por otro lado he estado trabajando en un peque??????±o proyecto, que si todo sale como yo espero en un par de semanas a mas tardar estar??????? montado y podr??????? por fin ver