/[pcsclite]/website/matrix.py
ViewVC logotype

Diff of /website/matrix.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 3388 by rousseau, Thu Mar 26 15:22:43 2009 UTC revision 4245 by rousseau, Wed Jun 3 13:03:29 2009 UTC
# Line 26  import time Line 26  import time
26    
27  pp = pprint.PrettyPrinter(indent=4)  pp = pprint.PrettyPrinter(indent=4)
28    
29  def merge(*input):  html_escape_table = {
30      """      "&": "&",
31      merge all the lists passed as argument      '"': """,
32      """      "'": "'",
33      return reduce(list.__add__, input, list())      ">": ">",
34        "<": "&lt;",
35        }
36    
37    def html_escape(text):
38        """Produce entities within text."""
39        L=[]
40        for c in text:
41            L.append(html_escape_table.get(c,c))
42        return "".join(L)
43    
44  def parse_reader(path, reader):  def parse_reader(path, reader):
45      """      """
# Line 58  def parse_all(path, reader_list): Line 67  def parse_all(path, reader_list):
67    
68      return readers      return readers
69    
70  def parse_ini(path, inifile):  def parse_ini(path, section):
71      """      """
72      parse a foobas.ini file to extract all informations      parse a foobar.ini file to extract all informations
73      """      """
74      config = ConfigParser.ConfigParser()      config = ConfigParser.ConfigParser()
75      # do not use the default case insensitive transform for key value      # do not use the default case insensitive transform for key value
76      config.optionxform = str      config.optionxform = str
77      config.read(inifile)      config.read(section + ".ini")
78      reader_list = config.sections()      reader_list = config.sections()
79    
80      readers = parse_all(path, reader_list)      readers = parse_all(path, reader_list)
81      for r in readers.keys():      for r in readers.keys():
82            readers[r]['section'] = section
83            readers[r]['iManufacturer'] = html_escape(readers[r]['iManufacturer'])
84          for o in config.options(r):          for o in config.options(r):
85              readers[r][o] = config.get(r, o)              if o == 'features':
86                    # for the features we use a list
87                    readers[r][o] = [ config.get(r, o) ]
88                else:
89                    readers[r][o] = config.get(r, o)
90    
91            bPINSupport = int(readers[r]['bPINSupport'], 16)
92            if bPINSupport != 0 and not 'features' in readers[r]:
93                readers[r]['features'] = list()
94            if bPINSupport & 1:
95                readers[r]['features'].append("PIN Verification")
96            if bPINSupport & 2:
97                readers[r]['features'].append("PIN Modification")
98    
99        #pp.pprint(readers["GemPCPinpad.txt"])
100      return readers      return readers
101    
102  def check_list(path, reader_list):  def check_list(path, reader_list):
103        """
104        Check that all .txt files are listed
105        """
106      cwd = os.getcwd()      cwd = os.getcwd()
107      os.chdir(path)      os.chdir(path)
108      real_list = glob.glob("*.txt")      real_list = glob.glob("*.txt")
# Line 95  def check_list(path, reader_list): Line 122  def check_list(path, reader_list):
122    
123      # some USB descriptor are not listed in readers.txt?      # some USB descriptor are not listed in readers.txt?
124      if len(real_list) > 0:      if len(real_list) > 0:
125          raise Exception("readers %s are not listed" % real_list)          print "Reader(s) not listed in any .ini file:"
126            print "\n".join(real_list)
127            print ""
128    
129    def check_supported(path, all_readers):
130        """
131        Check that all .txt files are mentionned in supported_readers.txt
132        """
133        supported_readers = file(path + "supported_readers.txt").readlines()
134        # convert in a long string and in uppercase
135        s = "".join(supported_readers).upper()
136    
137        unlisted = list()
138        for r in all_readers.keys():
139            pattern = "%s:%s" % (all_readers[r]['idVendor'], all_readers[r]['idProduct'])
140            if not pattern.upper() in s:
141                unlisted.append(pattern + " " + r)
142    
143        if len(unlisted) > 0:
144            print "Reader(s) not in supported_readers.txt"
145            print "\n".join(unlisted)
146            print ""
147        #pp.pprint(supported_readers)
148    
149  def get_by_manufacturer(readers):  def get_by_manufacturer(readers):
150        """
151        return a dict of the readers grouped by manufacturer
152        d['manufacturer'] is a list of the manufacturer's readers
153        """
154      d = {}      d = {}
155      for r in readers.keys():      for r in readers.keys():
156          d.setdefault(readers[r]['iManufacturer'], []).append(r)          d.setdefault(readers[r]['iManufacturer'], []).append(r)
157      return d      return d
158    
159  def generate_page(section, readers):  def generate_page(section, title, comment, readers):
160        """
161        generate a web page for the corresponding section
162        """
163      # sort the readers by manufacturers      # sort the readers by manufacturers
164      manufacturer_readers = get_by_manufacturer(readers)      manufacturer_readers = get_by_manufacturer(readers)
165      manufacturers = list(manufacturer_readers)      manufacturers = list(manufacturer_readers)
166        # sort the manufacturers list alphabetically
167      manufacturers.sort(key=str.lower)      manufacturers.sort(key=str.lower)
168    
169      template = templayer.HTMLTemplate(section + ".template")      template = templayer.HTMLTemplate("webpage.template")
170      file_writer = template.start_file(file=file(section + ".html", "w"))      file_writer = template.start_file(file=file(section + ".html", "w"))
171      main_layer = file_writer.open(date=time.asctime())      main_layer = file_writer.open(date=time.asctime(),
172            title=title, comment=comment, section=section)
173    
174      # for each manufacturer      # for each manufacturer
175      for m in manufacturers:      for m in manufacturers:
176          main_layer.write_layer('manufacturer', manufacturer=m)          main_layer.write_layer('manufacturer', manufacturer=m)
# Line 126  def generate_page(section, readers): Line 184  def generate_page(section, readers):
184                  idProduct = readers[r]['idProduct'],                  idProduct = readers[r]['idProduct'],
185                  image = "img/" + readers[r].get('image', "no_image.png"))                  image = "img/" + readers[r].get('image', "no_image.png"))
186    
187                note_layer.write_layer('descriptor', descriptor = "readers/%s" % r)
188    
189              url = readers[r].get('url', "")              url = readers[r].get('url', "")
190              if url:              if url:
191                  note_layer.write_layer('url',                  note_layer.write_layer('url',
192                      url = url,                      url = url,
193                      manufacturer = m,                      manufacturer = m,
194                      product = readers[r]['iProduct'])                      product = readers[r]['iProduct'])
195    
196              features = readers[r].get('features', "")              features = ", ".join(readers[r].get('features', ""))
197              if features:              if features:
198                  note_layer.write_layer('features', features = features)                  note_layer.write_layer('features', features = features)
199    
# Line 143  def generate_page(section, readers): Line 203  def generate_page(section, readers):
203    
204      file_writer.close()      file_writer.close()
205    
206    def generate_table(readers, field, index, fields):
207        """
208        generate a web page with all the reader attributes
209        readers are in the order given by index
210        """
211        header = """<?xml version="1.0" encoding="UTF-8"?>
212    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
213    <html>
214      <head>
215        <title>%s</title>
216        <link rel="stylesheet" type="text/css" href="default.css">
217        <link rel="stylesheet" type="text/css" href="matrix.css">
218      </head>
219      <body>"""
220        footer = """
221    <script type="text/javascript">
222    var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
223    document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
224    </script>
225    <script type="text/javascript">
226    try {
227    var pageTracker = _gat._getTracker("UA-2404298-2");
228    pageTracker._trackPageview();
229    } catch(err) {}</script>
230        <p>Ludovic Rousseau</p>
231      </body>
232    </html>"""
233        documentation = """
234        <p>Click on the column header to sort by that column.</p>
235        <p>The background color indicates the section of the reader:</p>
236        <table border="1" summary="color codes">
237        <tr><td>supported</td>
238        <td bgcolor="#a0ffff">should work</td>
239        <td bgcolor="#ffa0a0">unsupported</td></tr></table>
240        """
241    
242        file = open(field + ".html", "w")
243        title = "Readers sorted by '%s' field" % field
244        file.write(header % title)
245    
246        file.write("<h1>" + title + "</h1>")
247        file.write(documentation)
248    
249        file.write('<table border="1" summary="">\n')
250    
251        file.write('<tr>')
252        file.write("<th>#</th>")
253        for f in fields:
254            file.write("<th><a href='%s'>%s</a></th>" % (f+".html", f))
255        file.write('</tr>\n')
256    
257        num = 0
258        for r in index:
259            num += 1
260            if readers[r]['section'] == "unsupported":
261                file.write('<tr bgcolor="#ffa0a0">')
262            elif readers[r]['section'] == "shouldwork":
263                file.write('<tr bgcolor="#a0ffff">')
264            else:
265                file.write('<tr>')
266            file.write("<td>%d</td>" % num)
267            for f in fields:
268                if f == 'iProduct':
269                    file.write("<td><a href='%s.html#%s%s'>%s</a></td>" % (readers[r]['section'], readers[r]['idVendor'], readers[r]['idProduct'], readers[r][f]))
270                elif f == 'iManufacturer':
271                    file.write('<td><a onmouseover="">%s<img src="%s" alt="image"></a></td>' % (readers[r][f], "img/" + readers[r].get('image', "no_image.png")))
272                elif f == 'image':
273                    file.write('<td><img src="%s" height="100" alt="image"></td>' % ("img/" + readers[r].get('image', "no_image.png")))
274                else:
275                    file.write("<td>%s</td>" % readers[r].get(f, ""))
276            file.write('</tr>\n')
277    
278        file.write('</table>\n')
279    
280        file.write("<hr><p>Generated: %s</p>" % time.asctime())
281    
282        file.write(footer)
283        file.close()
284    
285    def generate_tables(readers):
286        """
287        generate all the web page tables with all the fields values
288        """
289        fields = [ 'section', 'iManufacturer', 'iProduct', 'image', 'idVendor',
290                'idProduct', 'bNumEndpoints', 'bInterfaceClass', 'bcdCCID',
291                'bMaxSlotIndex', 'bVoltageSupport', 'dwProtocols',
292                'dwDefaultClock', 'dwMaximumClock', 'dwDataRate',
293                'dwMaxDataRate', 'dwMaxIFSD', 'dwSynchProtocols',
294                'dwMechanical', 'dwFeatures', 'dwMaxCCIDMessageLength',
295                'bClassGetResponse', 'bClassEnveloppe', 'wLcdLayout',
296                'bPINSupport', 'bMaxCCIDBusySlots', 'features', 'note' ]
297    
298        for f in fields:
299            index = list()
300            for r in readers.keys():
301                index.append([readers[r].get(f, ""), r])
302            if f == 'section':
303                # hack to sort in the order supported, shouldwork, unsupported
304                index = [(s.replace('supported', 'asupported'),r) for s,r in index]
305            if f in ['dwDefaultClock', 'dwMaximumClock', 'dwDataRate',
306                    'dwMaxDataRate', 'dwMaxIFSD', 'dwMaxCCIDMessageLength']:
307                # convert from text to decimal
308                index = [(float(s.split(' ')[0])*1000,r) for s,r in index]
309            index.sort()
310            sorted_fields = list(fields)
311            sorted_fields.remove(f)
312            sorted_fields.insert(0, f)
313            generate_table(readers, f, [r for f, r in index], sorted_fields)
314    
315  if __name__ == "__main__":  if __name__ == "__main__":
316      path = "../trunk/Drivers/ccid/readers/"      path = "../trunk/Drivers/ccid/readers/"
317    
318      supported_readers = parse_ini(path, "supported.ini")      supported_readers = parse_ini(path, "supported")
319      shouldwork_readers = parse_ini(path, "shouldwork.ini")      shouldwork_readers = parse_ini(path, "shouldwork")
320      unsupported_readers = parse_ini(path, "unsupported.ini")      unsupported_readers = parse_ini(path, "unsupported")
321      reader_list = merge(supported_readers.keys(),  
322              shouldwork_readers.keys(), unsupported_readers.keys())      # all_readers contain the union of the 3 lists
323      #pp.pprint(reader_list)      all_readers = dict(supported_readers)
324      check_list(path, reader_list)      all_readers.update(shouldwork_readers)
325        all_readers.update(unsupported_readers)
326    
327        check_list(path, all_readers.keys())
328        check_supported(path, all_readers)
329    
330        generate_page("supported", "Supported CCID readers/ICCD tokens", "If you are a reader manufacturer and your reader is not listed here then contact me at ludovic.rousseau@free.fr", supported_readers)
331        generate_page("shouldwork", "Should work but untested by me", "The CCID readers and ICCD tokens listed bellow should work with the driver but have not be validated by me. I would like to get these readers to perform test and validation and move them in the supported list above. If you are one of the manufacturers, please, contact me at ludovic.rousseau@free.fr.", shouldwork_readers)
332        generate_page("unsupported", "Unsupported or partly supported CCID readers", "These readers have problems or serious limitations.", unsupported_readers)
333    
334      generate_page("supported", supported_readers)      generate_tables(all_readers)

Legend:
Removed from v.3388  
changed lines
  Added in v.4245

  ViewVC Help
Powered by ViewVC 1.1.5