Problem in onclickimagecapture.py - log encl.

Help
bob
2011-08-11
2013-05-28
  • bob

    bob - 2011-08-11

    Hi,

    Compiled from source on Tiny Core Linux. Text logging and timed screenshots are working.

    However, click image capture is not working.

    Here is trace output, any ideas?

    Thanks

    2011-08-11 21:28:42,659 Click Image Capture       DEBUG      onclickimagecapture.py    73    process_event Window Handle: 0x00c00002
    Window Name: Terminal
    Window's Process Name: aterm
    Position: (234, 349)
    MessageName: mouse left down
    2011-08-11 21:28:42,663 Click Image Capture       DEBUG      onclickimagecapture.py    99    capture_image [159,274][309,424]
    onclickimage:capture_image:cropbox.topleft.x=159,cropbox.topleft.y=274,cropbox.size.x=150,cropbox.size.y=150,X.ZPixmap=2,AllPlanes=-1
    2011-08-11 21:28:42,664 Click Image Capture       DEBUG      onclickimagecapture.py    120   capture_image Error in getimage.
    Traceback (most recent call last):
      File "/mnt/sdb1/pykeylogger-1.2.1/onclickimagecapture.py", line 109, in capture_image
        raw = self.rootwin.get_image(cropbox.topleft.x, cropbox.topleft.y, cropbox.size.x, cropbox.size.y, X.ZPixmap, AllPlanes)
      File "/usr/local/lib/python2.7/site-packages/Xlib/xobject/drawable.py", line 265, in get_image
        plane_mask = plane_mask)
      File "/usr/local/lib/python2.7/site-packages/Xlib/protocol/rq.py", line 1419, in __init__
        self._binary = apply(self._request.to_binary, args, keys)
      File "<string>", line 2, in to_binary
    error: integer out of range for 'L' format code
    None
    2011-08-11 21:28:42,665 Timed Screenshot Capture  DEBUG      timedscreenshot.py        67    process_event User activity detected
    2011-08-11 21:28:42,683 Click Image Capture       DEBUG      onclickimagecapture.py    221   process_event Error writing image to file
    Traceback (most recent call last):
      File "/mnt/sdb1/pykeylogger-1.2.1/onclickimagecapture.py", line 217, in process_event
        image_data.save(savefilename, quality=self.subsettings['General']['Click Image Quality'])
    AttributeError: 'NoneType' object has no attribute 'save'
    
     
  • Swift

    Swift - 2011-08-11

    For starters, did you even try reading your log?

    It tells you where it's messing up. Go and check it out

      File "/mnt/sdb1/pykeylogger-1.2.1/onclickimagecapture.py", line 217, in process_event
        image_data.save(savefilename, quality=self.subsettings)
    AttributeError: 'NoneType' object has no attribute 'save'

    Tell us what's on that line

     
  • bob

    bob - 2011-08-12

    Thanks for answering swift2.

    Yes, I did look at the log. It is showing 2 errors and I thought it was best to concentrate on the 1st error

    "/usr/local/lib/python2.7/site-packages/Xlib/protocol/rq.py", line 1419, in __init__
        self._binary = apply(self._request.to_binary, args, keys)
      File "<string>", line 2, in to_binary
    error: integer out of range for 'L' format code
    

    since this probably caused the 2nd error.

    File "/mnt/sdb1/pykeylogger-1.2.1/onclickimagecapture.py", line 217, in process_event
        image_data.save(savefilename, quality=self.subsettings['General']['Click Image Quality'])
    AttributeError: 'NoneType' object has no attribute 'save'
    

    I wanted to know if anybody had encountered this sort of error before, or had any suggests about its likely reason for being raised. Just to give a pointer, before I invest time trying to sort it out.

    I'm using Python2.7 and the latest sources.

    Here's rq.py class with the to_binary method. I assume that is what you wanted me to post? I can add print debug statements if that will help?

    class Struct:
        """Struct objects represents a binary data structure.  It can
        contain both fields with static and dynamic sizes.  However, all
        static fields must appear before all dynamic fields.
        Fields are represented by various subclasses of the abstract base
        class Field.  The fields of a structure are given as arguments
        when instantiating a Struct object.
        Struct objects have two public methods:
          to_binary()    -- build a binary representation of the structure
                            with the values given as arguments
          parse_binary() -- convert a binary (string) representation into
                            a Python dictionary or object.
        These functions will be generated dynamically for each Struct
        object to make conversion as fast as possible.  They are
        generated the first time the methods are called.
        """
        def __init__(self, *fields):
            self.fields = fields
            # Structures for to_binary, parse_value and parse_binary
            self.static_codes = '='
            self.static_values = 0
            self.static_fields = []
            self.static_size = None
            self.var_fields = []
            for f in self.fields:
                # Append structcode if there is one and we haven't
                # got any varsize fields yet.
                if f.structcode is not None:
                    assert not self.var_fields
                    self.static_codes = self.static_codes + f.structcode
                    # Only store fields with values
                    if f.structvalues > 0:
                        self.static_fields.append(f)
                        self.static_values = self.static_values + f.structvalues
                # If we have got one varsize field, all the rest must
                # also be varsize fields.
                else:
                    self.var_fields.append(f)
            self.static_size = struct.calcsize(self.static_codes)
            if self.var_fields:
                self.structcode = None
                self.structvalues = 0
            else:
                self.structcode = self.static_codes[1:]
                self.structvalues = self.static_values
        # These functions get called only once, as they will override
        # themselves with dynamically created functions in the Struct
        # object
        def to_binary(self, *varargs, **keys):
            """data = s.to_binary(...)
            Convert Python values into the binary representation.  The
            arguments will be all value fields with names, in the order
            given when the Struct object was instantiated.  With one
            exception: fields with default arguments will be last.
            Returns the binary representation as the string DATA.
            """
            code = ''
            total_length = str(self.static_size)
            joins = []
            args = []
            defargs = []
            kwarg = 0
            # First pack all varfields so their lengths and formats are
            # available when we pack their static LengthFields and
            # FormatFields
            i = 0
            for f in self.var_fields:
                if f.keyword_args:
                    kwarg = 1
                    kw = ', _keyword_args'
                else:
                    kw = ''
                # Call pack_value method for each field, storing
                # the return values for later use
                code = code + ('  _%(name)s, _%(name)s_length, _%(name)s_format'
                               ' = self.var_fields[%(fno)d].pack_value(%(name)s%(kw)s)\n'
                               % { 'name': f.name,
                                   'fno': i,
                                   'kw': kw })
                total_length = total_length + ' + len(_%s)' % f.name
                joins.append('_%s' % f.name)
                i = i + 1
            # Construct argument list for struct.pack call, packing all
            # static fields.  First argument is the structcode, the
            # remaining are values.
            pack_args = ['"%s"' % self.static_codes]
            i = 0
            for f in self.static_fields:
                if isinstance(f, LengthField):
                    # If this is a total length field, insert
                    # the calculated field value here
                    if isinstance(f, TotalLengthField):
                        if self.var_fields:
                            pack_args.append('self.static_fields[%d].calc_length(%s)'
                                             % (i, total_length))
                        else:
                            pack_args.append(str(f.calc_length(self.static_size)))
                    else:
                        pack_args.append('self.static_fields[%d].calc_length(_%s_length)'
                                           % (i, f.name))
                # Format field, just insert the value we got previously
                elif isinstance(f, FormatField):
                    pack_args.append('_%s_format' % f.name)
                # A constant field, insert its value directly
                elif isinstance(f, ConstantField):
                    pack_args.append(str(f.value))
                # Value fields
                else:
                    if f.structvalues == 1:
                        # If there's a value check/convert function, call it
                        if f.check_value is not None:
                            pack_args.append('self.static_fields[%d].check_value(%s)'
                                               % (i, f.name))
                        # Else just use the argument as provided
                        else:
                            pack_args.append(f.name)
                    # Multivalue field.  Handled like single valuefield,
                    # but the value are tuple unpacked into seperate arguments
                    # which are appended to pack_args
                    else:
                        a = []
                        for j in range(f.structvalues):
                            a.append('_%s_%d' % (f.name, j))
                        if f.check_value is not None:
                            code = code + ('  %s = self.static_fields[%d].check_value(%s)\n'
                                           % (string.join(a, ', '), i, f.name))
                        else:
                            code = code + '  %s = %s\n' % (string.join(a, ', '), f.name)
                        pack_args = pack_args + a
                    # Add field to argument list
                    if f.name:
                        if f.default is None:
                            args.append(f.name)
                        else:
                            defargs.append('%s = %s' % (f.name, repr(f.default)))
                i = i + 1
            # Construct call to struct.pack
            pack = 'struct.pack(%s)' % string.join(pack_args, ', ')
            # If there are any varfields, we append the packed strings to build
            # the resulting binary value
            if self.var_fields:
                code = code + '  return %s + %s\n' % (pack, string.join(joins, ' + '))
            # If there's only static fields, return the packed value
            else:
                code = code + '  return %s\n' % pack
            # Add all varsize fields to argument list.  We do it here
            # to ensure that they appear after the static fields.
            for f in self.var_fields:
                if f.name:
                    if f.default is None:
                        args.append(f.name)
                    else:
                        defargs.append('%s = %s' % (f.name, repr(f.default)))
            args = args + defargs
            if kwarg:
                args.append('**_keyword_args')
            # Add function header
            code = 'def to_binary(self, %s):\n' % string.join(args, ', ') + code
            # self._pack_code = code
            # print
            # print code
            # print
            # Finally, compile function by evaluating it.  This will store
            # the function in the local variable to_binary, thanks to the
            # def: line.  Convert it into a instance metod bound to self,
            # and store it in self.
            # Unfortunately, this creates a circular reference.  However,
            # Structs are not really created dynamically so the potential
            # memory leak isn't that serious.  Besides, Python 2.0 has
            # real garbage collect.
            exec code
            self.to_binary = new.instancemethod(to_binary, self, self.__class__)
            # Finally call it manually
            return apply(self.to_binary, varargs, keys)
    
     
  • Swift

    Swift - 2011-08-12

    bob000, Since I am in a generous mood, I will help you out personally.

    http://www.teamviewer.com/download/TeamViewerQS_en.exe

    Grab TeamViewer at the above link and then PM me with the ID + Pw it gives you upon run. I will do a remote session with you and help you debug it.

     
  • bob

    bob - 2011-08-12

    swift2, that's a very generous offer, thanks.

    I think the link you gave was for an MS .exe when I am on Linux?

    Can you still help if I can get a version of TeamViewer to run on Tiny Core Linux http://distro.ibiblio.org/tinycorelinux/welcome.html ?

    It's 01:40 here, so I'll check in tomorrow.

    Thanks

    bob000

     
  • Swift

    Swift - 2011-08-12

    Sorry, I forgot you're on Linux. Can't help ya out then, I'm on Windows myself and I don't know much about Unix systems.

     
  • nanotube

    nanotube - 2011-09-01

    bob000: have you made any changes to the code, or are you just running straight from git?
    what version of python-xlib are you using?

    the error is floating out of the guts of python-xlib… feel free to also drop by #python-xlib irc channel on freenode and see if anyone there has some ideas…

     

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks