Marco Islas Blog

tips and tricks

  • GTG tips and tricks (link)

    I'm getting used to , and I found this tips and tricks: GTG tips and tricks.
  • Compressed XMLRPC on python

    This post is about something I did on ICTC, we are developing some applications that communicate with each others on over the network and we thought on compressed XMLRPC. I have been looking about this on Google, but didn't really found something. So, I try by myself and this is the result.

    First, allow me to explain a bit more about xmlrpc. XMLRPC is nothing more than a remote call using the HTTP protocol the POST method and XML as content, then, the server do its work and return something in the same way. THen the client parses this xml and create the result in a native way. Just like if that method where in your program. This offer a language independece (the server may be written in some language and several clients in many other languages).

    Then, implementing compressed xml should not be that difficult, I mean.. HTTP support the "Accept-Encoding" header and that should do the job. But hey... xmlrpclib does not include gzip support, so, we are going to do it.

    The server part should subclass SimpleXMLRPCServer and in the constructor we are going to create a inner class that will be a request Handler, this handler is based on SimpleXMLRCPRequestHandler and implements the do_POST method, this method is called everytime something is sent to the server (on every call).

    In do_POST method we are responsible for fetching the data, decompress it, parse it, handle the response and then send the reply to the client. This isn't so hard (check the code). The important part here is that we check for the "accept-encoding" header and that the vale of that header (if exists) is "gzip", if this is true then use zlib to decompress the data and when we have the result of the call, compress it using zlib and send it to the client.

    def do_POST(self):
            if self.headers.has_key('accept-encoding') and \
                            self.headers['accept-encoding'] == 'gzip':
                    # check if the path ir right
                    if not self.is_rpc_path_valid():
                            self.report_404()
                            return
                    try: #Try to get the data
                            max_chunk_size = 10*1024*1024
                            size_remaining = int(self.headers["content-length"])
                            L = []
                            while size_remaining>0:
                                    chunk_size = min(size_remaining, max_chunk_size)
                                    L.append(self.rfile.read(chunk_size))
                                    size_remaining -= len(L[-1])
                            data = ''.join(L)
                            data = zlib.decompress(data) #Decompress
                            response = self.server._marshaled_dispatch(
                                            data, getattr(self, '_dispatch', None)
                                            )
                    except:
                            #Should be good to registre the exception somewhere
                            pass
                    else:
                            #We have an answer...
                            #Let's compress it
                            response = zlib.compress(response)
                            self.send_response(200)
                            self.send_header("Content-type", "text/xml")
                            self.send_header("Content-length", str(len(response)))
                            #As the call was compressed, then we compress the
                            #Answer too. Be sure to set the compressed header.
                            self.send_header("Accept-Encoding","gzip")
                            self.end_headers()
                            self.wfile.write(response)
                            #Close the connection
                            self.wfile.flush()
                            self.connection.shutdown(1)
            else:
                    return SimpleXMLRPCRequestHandler.do_POST(self)
     

    This take us the the other part of the call, the client. The client must implement gzip compression too. The client part is a bit simplier, you just have to subclass xmlrpclib's Transport and and in the "request" method compress the request_body before sending it. Obviously you have to append the "accept-encoding" header to the http connection. Once you have the result you have to check for the "accept-encoding" header too, if it is there, decompress using zlib's methods.

    def request(self, host, handler, request_body, verbose=0):
            '''
            Encargado de manejar los request, envia los datos y recibe
            las repuestas, por lo que aqui se hace la compresion de datos
            y posteriormente se envian los datos recibidos a
            la funcion self._parse_response o self._parse_gzipped_response
            de acuerdo al caso.
            Mas informacion:
            http://docs.python.org/library/xmlrpclib.html
            '
    ''
            h = self.make_connection(host)
            if verbose:
                    h.set_debuglevel(1)
            self.send_request(h, handler, request_body)
            self.send_host(h, host)
            self.send_user_agent(h)
            #Compress if GZIP_ENCODED is true
            if GZIP_ENCODED:
                    #Don't forget to set the header!
                    h.putheader('Accept-Encoding','gzip')
                    request_body = zlib.compress(request_body)
            self.send_content(h, request_body)
           
            errcode, errmsg, headers = h.getreply()
            if errcode != 200:
                    raise ProtocolError(
                                    host + handler,
                                    errcode, errmsg,
                                    headers
                                    )
            self.verbose = verbose
            try:
                    sock = h._conn.sock
            except AttributeError:
                    sock = None
            # Revisar si la respuesta incluye los encabezados de
            # compresion y si este es gzip
            if headers.has_key('accept-encoding') and \
                            headers['accept-encoding'] == 'gzip':
                    return self._parse_gzipped_response(h.getfile(), sock)
            return self._parse_response(h.getfile(), sock)
     
    The whole code and a small example is here: ictcxmlrpc.tar.bz2
  • Quick note about Chrome on Ubuntu

    If you don't have any sound while playing videos, you can use this trick in your shell
    sudo ln -s /usr/lib/mozilla/plugins /opt/google/chrome/plugins
    Then restart chrome and you are done
  • Dan Pink




    Just listen to him.
  • Python MySQldb little trick

    if you are using Python and MySQLdb you may find that using special chars like ñ or ó break the program raising an DecodeError because character xxx is not in the range...
    MySQLdb has a way to set the charset for the connection but it is useless if you are using MySQL prior to 4.1. If you are having problems with this, then try doing this:
    import MySQLdb
    import sys
    reload(sys)
    sys.setdefaultencoding('latin-1')
     
    Replace "latin-1" with your desired encoding and try it.
  • 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.




    Read More...
  • 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.
  • apt reminder no. 1

    Limit your download rate in apt.
    As root,
    alias apt-get="apt-get -o Acquire::http::Dl-Limit=80"
  • 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

    Read More...
  • 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
twitter logo