Re: [casetta] Ideas for version 0.4 of casetta /GPLv3

[ Thread Index | Date Index | More lists.tuxfamily.org/casetta Archives ]


Florian Birée a écrit :
Hello,

Because you've started the thread I should have started, I begin by the
draft of the todo list of casetta 0.4 (with your propositions - see my
comments in answer of them):
  
Sorry, I don't want to take your job or to force you to act quickly. Don't feel obliged to answer to my mails so rapidly and to work until 2 o'clock in the morning !
# casetta
- needed items
* Full support of graph 65 (included the support of all g65 data, their
support in the transfer tool, and in all file formats)
- less important items
* Picture Extractor from backups (using the Fabien ANDRE's code?)
* List/Matrix extractor from backup
* Better img_to_basic function
* Add the support of all Fa-124 formats (for the compatibility with
graph 85/fx-9860G)
- optional items
* Try to make a picture to drawstat function. It may be difficult.
(About drawstat: http://www.casioland.net/forum/viewtopic.php?t=662
(french) and http://www.casiocalc.org/?showtopic=2078 (english))
* Depending of the advancement of the xfer9860 project, write a wrapper
for xfer9860 in a casetta transfer tool. This also depend of if I (or
any casetta developer/contributor) can get a graph 85
(See the discussion with xfer9860 developer:
https://sourceforge.net/forum/forum.php?thread_id=1753286&forum_id=682488 )

# casetta_cli
- needed items
* New arguments parser using the optparse python module
- optional items
* Add the support of the xfer9860 wrapper for command line arguments

# gasetta
- needed items
* New arguments parser using the optparse python module
* Create a list/matrix/etc editor
- optional items
* Improve the picture editor (drag'n drop to draw, etc)
* Make a 'drawstat editor' to make easily drawstat pictures (if the
picture to drawstat function is impossible to create)
* If the wrapper for xfer9860 work, make a special interface for it
(need to display the content of the calculator memory, etc)

I think also to implement a compatibility system, to check if the data
to be transferred is compatible with your casio calculator. I'll start a
new thread about this subject (but not this night).
This roadmap looks good to me !
About Casetta
Could you move making a better img_to_basic to optional items. I am not sure I will suceed. :-) I looked at the link about drawsats. I didn't know this system...
This is really faster than drawing F-Lines (To draw 100 squares (with 20 pixels side), it takes ~40s with F-lines and ~30s with drawstats). I will try to create an algorithm to transform Pictures to drawstat.

I saw (on the forum thread), that you want to integrate a  C tool (xfer9860) with Casetta... As you said there are various ways to do that...
1. Using command line. This is simple but not very good... (Python modules : os, subprocess (the best),pexpect (for software who don't used stdin/stdout/stderr))
2. Natively open c libraries using the ctypes python module. I think this is the best solution, good and not too complicated.I have one example, in which we import the native C fopen library : (As I saw there is only functions and not classes)

from ctypes import *

libc = cdll.LoadLibrary("libc.so.6")

# C Function : FILE * fopen(const char name[], const char mode[]) # FILE * is a pointer on a FILE structure
py_fopen = libc.fopen
fopen.argtypes = [c_char_p,c_char_p] # Takes two C strings : I don't if you have ever programmed in C, but in C, string are table of char and in C, table are    pointers (eg : char *var is exactly the same as char var[])
fopen.restype = c_int

# Using this function
f = fopen("test.dat","w") # Be careful : f cannot be now used as a python pseudo-file object

3.  Use the the dl module. This is a good choice for *nix (very simple to use) be it is not compatible with Windows.
4. Using "adaptators" like swig, sip (Used by PyQT) and boost-python (C++). This a good solution but quite complicated !
 

Fabien ANDRE a écrit :
  
Hello,

About casetta website, I would like to mention that the link to the web
svn repository is broken :
The link on this page (http://casetta.tuxfamily.org/download) points to
:
http://svnweb.tuxfamily.org/listing.php?repname=casetta+%28casetta%29&path=%2F&sc=0
The good link seems to be :
http://svnweb.tuxfamily.org/listing.php?repname=casetta/casetta&path=%2F&sc=0
(Tuxfamily svn repository was reorganized ?)
    
I'll fix it.
  
There is also an ENORMOUS problem on the french presentation page. Yes, there is not screenshot !
  
I have some ideas/proposals for casetta 0.4 (I insist on this point,
they are just ideas :-) :
    
All ideas are welcome!

  
- Reorganize the transfer tool (devices_serial.py), casio link
management module (cas.py) and the data manager (data.py)...
    
  
_*Cas.py*_
/What I propose to do :
/Create classes in cas.py, which derives from classes of data.py and add
methods to these classes which have the same usefulness as the current
functions.

For example, for programs we could have (in cas.py) : See cas-exple.py
in attachements.
    
(The attachment has disappear...)
  
It has disappeared because I didn't add it. I always forget them because I am too absent-minded ! anyway, you perfectly understood what I meant !
Of course, same thing have to be done for all classes of data.py. Using
this new """architecture""", when implementing a new raw format, you
just need to modify one class... Maybe, it would be good to also create
a generic TransferableData class.
    
I've create devices_serial.py and cas.py by converting the perl code
from cafix into pyhton. The organization is more or less the same
(cas.py contain the code used for the transfer and for the cas file
format, devices_serial contain the transfer stuff).

You object model seems to be very better. I'm OK to try this
re-organization, maybe in a branch of the repository. It'll be the first
big work on the 0.4 version.
  
OK, let's start working in this new branch !

  
The only function which cannot be transformed into a method is :
det_data_format. But I don't like the way it works. Why does it return a
string : header_type rather than directly an object (Which is created
after in receive data of devices_serial.py ?)) See cas-exple.py in
Attachements
    
Do you want to speak about cas.get_header_format?
As you wrote, this function cannot be integrated in the object model,
but it can return object, and more: it can do test provided by
transferable-data classes. With this, the cas.get_header_format just has
to get the list of transferable-data classes, and for each test if the
header match.
It's the better and more object-oriented way I see to do this.
  
Yes, that's the function I was speaking about...Your idea is good..
  
_*Devices_serial.py
*_Keep cool ! For this file I don't want to change everything like the
previous :-D
I would like to change some part of the file :
In send_data() function :
            raw_data_list = [data.raw_data[0:1028],
                             data.raw_data[1028:2056],
                             data.raw_data[2056:3084],
                             data.raw_data[3084:4112]]
        elif data.__class__ == datacls.Matrix or data.__class__ ==
datacls.List or data.__class__ == datacls.SimlEquationMatrix or
data.__class__ == datacls.PolyEquationMatrix:
            raw_data_list = data.get_raw_data_list()
        else:
            raw_data_list = [data.raw_data]
I would like to replace this by : raw_data_list =
data.get_raw_data_list(). This means each Transferable object in cas.py,
should have a method who returns a list of data to be transferred even
if this list contains only one element
    
No problem. Good suggestion.

  
In receive_data() function :
                ## List/Matrix management specific block
                if ( data_type == 'list' or data_type == 'matrix' or
data_type == 'simlequation-matrix' or data_type == 'polyequation-matrix'
) and (index-13)%14==0 and index <= data_len-14:
                    # Checksum test
                    calc_crc=self.get_byte()
                    filereceived.write(calc_crc)
                    if abs(255 - (crc % 256)) + 1 == ord(calc_crc):
                        self.send_byte('\x06')
                        crc=0
                        resp=self.get_byte()
                        filereceived.write(resp)
                        if resp != '\x3a':
                            raise errors.BadAnswerFromCalc(resp)
                    else:
                        raise errors.ChecksumError()

                ## Screencapture management specific block
                if data_type == 'screencapture' and sub_type == 'color' \
                        and (index == 1024 or index == 2048):
                    resp2 = self.get_byte()
                    self.send_byte('\x06')
                    resp2 = self.get_byte()
                    crc = 0

                ## Picture management specific block
                if data_type == 'picture' and (index + 1) % 1028 == 0 \
                        and index != 0 and index + 1 < data_len:
                    # IMAGE / color screencapture
                    newcrc = ord(self.get_byte())
                    crc = abs(255 - (crc % 256)) + 1
                    if not newcrc == crc :
                        raise errors.ChecksumError()
                    crc = 0
                    self.send_byte('\x06')
                    resp2 = self.get_byte()
                    if not resp2 == '\x3a':
                        raise errors.BadAnswerFromCalc(resp2)
                #if data_type == 1 and bytesproc + 1 == 62684:
                #    print 'byte 62684 of a backup : send 0x06'
                #    send_byte('\x06')
                raw_data += byte
I think each Transferable object should have a method return the indexes
where the transmission needs to be stopped but I am not sure of how to
do that.
"Talk is cheap. Show me the code"
    
Or maybe with something like:
if mydata.is_transfered(index):
    # checksum stuff

We must check what an is_transfered function can need as argument.
  
Yes, that's a good idea. is_transfered should return True or False...
  
_*Data.py
*_The worst is before you. I don't want to change anything in this file.
;-) Just add some things ! Maybe we should create a generic FileObject
management class which could manage File List, Variable Files, Y=Data
Files and son.
    
Yes, it's probably the better option. I haven't take the time to really
read your code about new data.py objects (I'm moving to a new flat, and
that take time :-) ), but it seems to be good.

  
Yes, developing casetta is not urgent... There are things more important !

  
My other proposals (I am pretty sure you will agree with them) for
casetta 0.4 are :
- Full support ? For Graph65
    
No problem, it'll be the main goal of the 0.4 version.

  
- Picture Extractor from backups (I have one, which uses the white sheet
to detect a picture in a backup because color bytes and son are not
stored in backups). It is not so bad..
    
If we are sure to not extract non-picture data, no problem. It's easy to
implement it with regular _expression_.
  
I have already implemented it (I have a draft on my HDD,), but I am not really sure it only extract picture data. That's the problem. For now it extracts all pictures plus the "draw memory" which is stored exactly like a picture. But I have to test it more...
  
- List/Matrix extractors from backup
    
No problem (have you begin to see where they are stored in the
calculator memory?)
  
Yes I have started to do so. I think we can use what I call the special code : http://casetta.tuxfamily.org/formats/raw
  
- Better img_to_basic function
    
No problem if you have some idea to improve it. I'll not work on this
functionality until a full support of all casio models in casetta :-)
  
I understand theses function (img_to_basic, backup extractor) are optional and that it is not the main aim of casetta. But they are cool features which make the software better :-)

And... what's your opinion about GPLv3? Asher256 and I are ok to switch
in GPLv3 only, your are the last author of casetta code, your choice
will be the choice for the project!
  
To be completely honest, I had not read the GPLv3 license when it was out. I have just read the French translation (and the link you gave in a previous mail, which is an excellent document)...
About that, the first thing I want to say is that I am not a legal expert and I don't understand the whole content of the license ! So I trusted the author of Veni Vedi Libri article. I think there are some very interesting improvements in this license (according to me) :

* The license is now more "legally secure"
* More international

* Rejection of DRM in general (I hate DRM, I think this is really stupid)
* Article 11 about e Patents.  Let me give you my opinion about patents : I am not especially against the idea of patents, I think this is normal that people could protect their work, and this therefore encourages innovation... But, I disagree with software patents (at least with the way they are defined today) for many reasons. First, they are too general, too large and it is very difficult for non-programmers to juge if a software method is really and innovation. I mean, because a software is just a succession of very simple logical structure,  it is very difficult to define what can be patented. This led to very stupid patents on : icons, double-click, keyboard use in a navigator, virtual desktop etc... And this blocks innovation ! Moreover, the current system just  give an advantage to very big societies who have lots of money, to make lawsuits (For example errrrrr.... This begins by Micro and ends by soft) and pay lawyers. There are other reasons but these are the main two.

There are some points I disgree with in this license :
 * Tivozation. I think a software license should only protect software ! However, this is only mentioned in the preamble an there is no formal obligation so that's OK
* I don't under stand why "Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying."

As you see, there are more improvements than points I disagree with so finally, I agree to switch my code to "GPLv3 only" !

About a forum

I agree with the idea of a forum. This is definitely more convenient than a mailing list ! But, I think this is not the right time, it may be good to wait until wa have better support for more calculators and more functionnalities

Yours,

--
Fabien ANDRE aka Xion345
Linux User #418689 -- fabien.andre.g@xxxxxxxxxx -- xion345@xxxxxxxxxxxxx
I'm always right. This time I'm just even more right than usual. ( Linus Torvalds, July 14, 2005 )
## Just an example for programs
class TransferableProgram(datacls.Program):
    header_len = 49
    def __init__(self,name = '', raw_data = '', date = None, password = "", use_base = False)
        datacls.Program.__init__(self, name, raw_data, date, password, use_base, header)
        self.header = header
        self.length = 0
    ### Methods used when sending a newly created Program 
    def build_header():
        self.update_len()
        header = 'TXT\x00PG'
        header += chr(data_len / (256 ** 3))
        header += chr((data_len % 256 ** 3) / (256 ** 2))
        header += chr((data_len % 256 ** 2) / 256)
        header += chr(data_len % 256) # 0 -> 9
        header += data.name[:8] + '\xff' * (8 - len(data.name[:8])) #10->17
        header += '\xff' * 8
        header += data.password[:8] + '\xff' * (8 - len(data.password[:8]))
        if data.use_base:
            header += 'BN'
        else:
            header += 'NL'
        header += '\xff' * 12
    def update_len(self): 
        self.lenght = len(self.raw_data) + 2

    ### Methods used when receiving a Program 
    def get_data_len(self):
        std_len = ord(header[6]) * (256 ** 3) + ord(header[7]) * (256 ** 2) + ord(header[8]) * 256 + ord(header[9]) - 2
        self.length = std_len
        return self.length
    def fill_metadata(self):
        if self.header != "":
            # Password
            data.password = header[26:34].replace('\xff', '')
            # Base:
            if header[34:36] == 'BN':
                data.use_base = True
            else:
                data.use_base = False
        else:
            raise SpecificError
def get_data_format(header): # Rename it ? get_data_object ?
    sub_type = None
    type_id = header[0:3]
    sub_id = header[4:6]
    if type_id == "MEM" and sub_id == "BU":
        return TransferableBackup
    elif type_id == "IMG" and sub_id == "PC":
        return TransferablePicture
    elif type_id == "TXT" and sub_id == "PG":
        return TransferableProgram
    ## Etc...




Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/