8dbbce0e2ce3915febb4c47348e7cb1e30bdbc80
[odoo/odoo.git] / addons / base_module_quality / pylint_test / pylint_test.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #    
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
6 #
7 #    This program is free software: you can redistribute it and/or modify
8 #    it under the terms of the GNU Affero General Public License as
9 #    published by the Free Software Foundation, either version 3 of the
10 #    License, or (at your option) any later version.
11 #
12 #    This program is distributed in the hope that it will be useful,
13 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 #    GNU Affero General Public License for more details.
16 #
17 #    You should have received a copy of the GNU Affero General Public License
18 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.     
19 #
20 ##############################################################################
21
22 import os
23
24 from tools import config
25 from tools.translate import _
26 from base_module_quality import base_module_quality
27
28 class quality_test(base_module_quality.abstract_quality_check):
29
30     def __init__(self):
31         super(quality_test, self).__init__()
32         self.name = _("Pylint Test")
33         self.note = _("""This test uses Pylint and checks if the module satisfies the coding standard of Python. See http://www.logilab.org/project/name/pylint for further info.\n """)
34         self.bool_installed_only = False
35         self.min_score = 30
36         return None
37
38     def run_test(self, cr, uid, module_path):
39         config_file_path = config['addons_path']+'/base_module_quality/pylint_test/pylint_test_config.txt'
40         list_files = os.listdir(module_path)
41         for i in list_files:
42             path = os.path.join(module_path, i)
43             if os.path.isdir(path):
44                 for j in os.listdir(path):
45                     list_files.append(os.path.join(i, j))
46
47         count = 0
48         score = 0.0
49         dict_py = {}
50         flag = False
51         self.result_details += '''<html><body><head>%s</head>'''%(self.get_style())
52         for file_py in list_files:
53             if file_py.split('.')[-1] == 'py' and not file_py.endswith('__init__.py') and not file_py.endswith('__terp__.py'):
54                 if not flag:
55                     flag = True
56                 file_path = os.path.join(module_path, file_py)
57                 try:
58                     import pylint
59                     res = os.popen('pylint --rcfile=' + config_file_path + ' ' + file_path).read()
60                 except:
61                     self.error = True
62                     import netsvc
63                     netsvc.Logger().notifyChannel('Pylint:', netsvc.LOG_WARNING, "Is pylint correctly installed? (http://pypi.python.org/pypi/pylint)")
64                     self.result += _("Error. Is pylint correctly installed? (http://pypi.python.org/pypi/pylint)")+"\n"
65                     return None
66                 count += 1
67 #                leftchar = -1
68 #                while res[leftchar:leftchar+1] != ' ' and leftchar-1 <= 0:
69 #                    leftchar -= 1
70 #                rightchar = -10
71 #                while res[rightchar:rightchar+1] != '/' and rightchar+1 <= 0:
72 #                    rightchar += 1
73                 try:
74 #                    score += float(res[leftchar+1:rightchar])
75                     scr = res.split("Your code has been rated at")[1].split("</div>")[0].split("/")[0]
76                     score += float(scr)
77                     #self.result += file + ": " + res[leftchar+1:rightchar] + "/10\n"
78                     dict_py[file_py] = [file_py, scr]
79                 except:
80                     score += 0
81                     #self.result += file + ": "+_("Unable to parse the result. Check the details.")+"\n"
82                     dict_py[file_py] = [file_py, _("Unable to parse the result. Check the details.")]
83                 replace_string = ''
84                 replace_string += res
85                 replace_string = replace_string.replace('''<div''', '''<div class="divstyle" ''')
86                 replace_string = replace_string.replace('''<h1''', '''<h1 style="font-size:188%" class="head" ''')
87                 replace_string = replace_string.replace('''<h2''', '''<h2 style="font-size:150%" class="head" ''')
88                 replace_string = replace_string.replace('''<h3''', '''<h3 style="font-size:132%" class="head" ''')
89                 replace_string = replace_string.replace('''<h4''', '''<h4 style="font-size:116%" class="head" ''')
90                 replace_string = replace_string.replace('''<h5''', '''<h5 style="font-size:100%" class="head" ''')
91                 replace_string = replace_string.replace('''<h6''', '''<h6 style="font-size:80%" class="head" ''')
92                 replace_string = replace_string.replace('''<table''', '''<table class="tablestyle" ''')
93                 replace_string = replace_string.replace('''<th''', '''<th class="tdatastyle" ''')
94                 replace_string = replace_string.replace('''<td''', '''<td class="tdatastyle" ''')
95                 self.result_details += replace_string
96
97         if not flag:
98             self.error = True
99             self.result = _("No python file found")
100             return None
101         self.result_details += '</body></html>'
102         average_score = count and score / count or score
103         self.score = (max(average_score, 0)) / 10
104         if self.score*100 < self.min_score:
105             self.message = 'Score is below than minimal score(%s%%)' % self.min_score
106         self.result = self.get_result(dict_py)
107         return None
108
109     def get_result(self, dict_py):
110         header = ('{| border="1" cellspacing="0" cellpadding="5" align="left" \n! %-40s \n! %-10s \n', [_('File Name'), _('Result (/10)')])
111         if not self.error:
112             return self.format_table(header, data_list=dict_py)
113         return ""
114
115 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: