1 # -*- encoding: utf-8 -*-
2 ##############################################################################
4 # Copyright (c) 2004-2006 TINY SPRL. (http://axelor.com) All Rights Reserved.
6 # WARNING: This program as such is intended to be used by professional
7 # programmers who take the whole responsability of assessing all potential
8 # consequences resulting from its eventual inadequacies and bugs
9 # End users who are looking for a ready-to-use solution with commercial
10 # garantees and support are strongly adviced to contract a Free Software
13 # This program is Free Software; you can redistribute it and/or
14 # modify it under the terms of the GNU General Public License
15 # as published by the Free Software Foundation; either version 2
16 # of the License, or (at your option) any later version.
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
23 # You should have received a copy of the GNU General Public License
24 # along with this program; if not, write to the Free Software
25 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 ##############################################################################
29 from osv import fields, osv
31 from Wiki2Html import Wiki2Html
35 from StringIO import StringIO
43 'title':fields.char('Title',size=128),
53 'title':fields.char('Title', size=128, select=True),
54 'last_modify_by':fields.many2one('res.users',"Last Modify By"),
55 'text_area':fields.text("Content", select=True),
56 'wiki_create_uid':fields.many2one('res.users','Authour', select=True),
57 'wiki_create_date':fields.datetime("Created on", select=True),
58 'wiki_write_date':fields.datetime("Last modified", select=True),
59 'tags':fields.many2many("base.wiki.tag","wiki_tag_many_id","wiki_id","tag_id","Tags", select=True),
60 #'forum_id':fields.one2many('base.wiki.forum','wiki_id','Forum Lines'),
61 'history_id':fields.one2many('base.wiki.history','history_wiki_id','History Lines'),
62 'html':fields.text("Html Data", select=True),
63 'path':fields.char('Page Path',size=128),
64 'model_id': fields.many2one('ir.model', 'Model id', select=True, ondelete='cascade'),
65 'res_id': fields.integer("Record Id"),
66 'minor_edit':fields.boolean('Thisd is a minor edit', select=True),
67 'summary':fields.char('Summary',size=256, select=True),
70 'wiki_create_date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
71 'wiki_create_uid': lambda obj,cr,uid,context: uid,
74 def __init__(self, cr, pool):
75 super(Wiki, self).__init__(cr, pool)
78 def read(self, cr, uid, cids, fields=None, context=None, load='_classic_read'):
79 result = super(Wiki, self).read(cr, uid, cids, {}, load='_classic_read')
81 if context and context.get('index'):
82 ids = self.search(cr, uid, [('model_id','!=',False), ('id','in',cids)])
83 res = self.read(cr, uid, ids)
87 if self.oldmodel != rs['model_id'][1] or self.oldmodel == None:
88 self.oldmodel = rs['model_id'][1]
89 buffer+= '\n==' + self.pool.get('ir.model').browse(cr, uid, rs['model_id'][0]).name + '==\n'
91 rec_url = '/form/view?model=' + rs['model_id'][1] + "&id=" + str(rs['res_id'])
92 edit_url = '/form/edit?model=' + rs['model_id'][1] + "&id=" + str(rs['res_id'])
94 buffer+= '| # | ' + rs['title'] + ' | [' + rs['path'] + ' - wiki]' + ' | [' + rec_url + ' - Browse ] | [' + edit_url + ' - Edit ]\n'
96 ids = self.search(cr, uid, [('model_id','=',False), ('id','in',cids)])
97 res = self.read(cr, uid, ids)
100 buffer+= '\n==Other Pages==\n'
103 buffer+= '* [' + rs['path'] + ' - ' + rs['title'] + ']\n'
105 return [{'html':self.Wiki2Html(buffer)}]
109 def Wiki2Html(self, wiki):
110 fileName = 'data.txt'
111 file = open(fileName, 'w')
112 file.write(wiki+'\n\n')
116 parser.read(fileName)
119 def create(self, cr, uid, vals, context=None):
120 if vals.get('text_area'):
121 vals['html'] = self.Wiki2Html(vals['text_area'])
123 vals['text_area'] = 'Your text goes here'
124 vals['html'] = 'You have not create the page.'
125 if not vals.has_key('minor_edit'):
126 return super(Wiki,self).create(cr, uid, vals, context)
127 vals['history_id']=[[0,0,{'minor_edit':vals['minor_edit'],'text_area':vals['text_area'],'modify_by':uid,'summary':vals['summary']}]]
128 return super(Wiki,self).create(cr, uid, vals, context)
130 def write(self, cr, uid, ids, vals, context=None):
131 vals['wiki_write_date']=time.strftime('%Y-%m-%d %H:%M:%S')
132 vals['last_modify_by']=uid
133 wiki_data=self.read(cr,uid,ids,['minor_edit','summary'])[0]
134 if vals.get('text_area'):
135 vals['html'] = self.Wiki2Html(vals['text_area'])
136 if vals.has_key('minor_edit') and vals.has_key('summary'):
137 vals['history_id']=[[0,0,{'minor_edit':vals['minor_edit'],'text_area':vals['text_area'],'modify_by':uid,'summary':vals['summary']}]]
138 elif vals.has_key('minor_edit'):
139 vals['history_id']=[[0,0,{'minor_edit':vals['minor_edit'],'text_area':vals['text_area'],'modify_by':uid,'summary':wiki_data['summary']}]]
140 elif vals.has_key('summary'):
141 vals['history_id']=[[0,0,{'minor_edit':wiki_data['summary'],'text_area':vals['text_area'],'modify_by':uid,'summary':vals['summary']}]]
143 vals['history_id']=[[0,0,{'minor_edit':wiki_data['minor_edit'],'text_area':vals['text_area'],'modify_by':uid,'summary':wiki_data['summary']}]]
144 return super(Wiki,self).write(cr, uid, ids, vals, context)
147 #class Forum(osv.osv):
148 # _name="base.wiki.forum"
149 # _description="Wiki Forum"
152 # 'title':fields.char('Title',size=128),
153 # 'replies':fields.integer('Replies'),
154 # 'wiki_authour':fields.many2one('res.users','Created By'),
155 # 'last_post':fields.datetime("Last Post",readonly=True),
156 # 'by':fields.many2one('res.users','By',readonly=True),
157 # 'discussion_lines':fields.one2many('base.wiki.discussion','forum_id','Discussion Lines'),
158 # 'wiki_id':fields.many2one('base.wiki','Wiki Id')
162 #class Discussion(osv.osv):
163 # _name="base.wiki.discussion"
164 # _description="Wiki Discussion"
165 # _rec_name="wiki_authour"
167 # 'wiki_authour':fields.many2one('res.users','Authour',readonly=True),
168 # 'posted_date':fields.datetime("Posted Date",readonly=True),
169 # 'message':fields.text('Message'),
170 # 'forum_id':fields.many2one('base.wiki.forum','Forum Id')
174 class History(osv.osv):
175 _name="base.wiki.history"
176 _description="Wiki History"
177 _rec_name="date_time"
180 'date_time':fields.datetime("Date",select=True),
181 'text_area':fields.text("Text area",select=True),
182 'minor_edit':fields.boolean('This is a major edit ?',select=True),
183 'summary':fields.char('Summary',size=256, select=True),
184 'modify_by':fields.many2one('res.users',"Modify By", select=True),
185 'hist_write_date':fields.datetime("Last modified", select=True),
186 'history_wiki_id':fields.many2one('base.wiki','Wiki Id', select=True)
189 'hist_write_date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
190 'modify_by': lambda obj,cr,uid,context: uid,
193 def getDiff(self, cr, uid, v1, v2, context={}):
196 history_pool = self.pool.get('base.wiki.history')
198 text1 = history_pool.read(cr, uid, [v1], ['text_area'])[0]['text_area']
199 text2 = history_pool.read(cr, uid, [v2], ['text_area'])[0]['text_area']
201 line1 = text1.splitlines(1)
202 line2 = text2.splitlines(1)
204 diff = difflib.HtmlDiff()
206 return diff.make_file(line1, line2, "Revision-%s" % (v1), "Revision-%s" % (v2), context=False)
210 from StringIO import StringIO
211 from HTMLParser import HTMLParser
213 class IndexLine(osv.osv):
214 _name="base.index.line"
215 _description="Index Lines"
217 'name':fields.text('Content', select=True),
218 'active':fields.boolean('Active', select=True),
219 'model':fields.char('Resource',size=256, select=True),
220 'res_id':fields.integer('Resource Id', select=True),
223 'active': lambda *a: True,
226 def __init__(self, cr , pool):
227 super(IndexLine, self).__init__(cr, pool)
229 def reIndex(self, cr, uid, ids, context={}):
230 password = self.pool.get('res.users').browse(cr, uid, uid).password
231 self.server.init(cr.dbname, uid, password, True)
234 self.Index(cr, uid, context)
239 def Index(self, cr, uid, ids, context={}):
241 entry_pool = self.pool.get('base.index.line')
242 eids = entry_pool.search(cr, uid, [])
243 # entry_pool.unlink(cr, uid, eids)
246 model_pool = self.pool.get('ir.model')
247 field_pool = self.pool.get('ir.model.fields')
249 ids = model_pool.search(cr, uid, [('model','!=','base.index.line')])
250 models = model_pool.read(cr, uid, ids, ['id', 'model'])
255 if str(mod['model']).startswith('workflow'):
258 if str(mod['model']).startswith('ir'):
261 if str(mod['model']).startswith('base.index.line'):
264 if str(mod['model']).startswith('res.currency'):
267 if str(mod['model']).startswith('base.wiki'):
270 if str(mod['model']).startswith('report'):
273 if str(mod['model']).startswith('account_analytic_analysis.summary.user'):
276 if str(mod['model']).startswith('hr_timesheet_invoice.factor'):
280 fids = field_pool.search(cr, 1, [('model_id','=',mod['id'])])
281 fdata = field_pool.read(cr, uid, fids, ['name','relation', 'ttype'])
288 # fkeys[fd['name']] = fd['relation']
289 # tkeys[fd['name']] = fd['ttype']
294 res_pool = self.pool.get(mod['model'])
299 res_ids = res_pool.search(cr, 1, [])
300 res_datas = res_pool.read(cr, 1, res_ids)
301 #cr.execute("select * from %s" % ( mod['model'].replace('.','_')))
302 #res_datas = cr.dictfetchall()
307 print 'Indexing : ', mod['model'], ' Auto Status : '
310 for res_data in res_datas:
312 exist_ids = entry_pool.search(cr, uid, [('res_id','=',res_data['id']),('model','=',mod['model'])])
313 if exist_ids.__len__() > 0:
318 # for col in res_data:
319 # if fkeys.has_key(col) and fkeys[col] != 'NULL':
320 # if tkeys.has_key(col) and tkeys[col] == 'one2many':
321 # rel_pool = self.pool.get(fkeys.get(col))
323 # foreign_key = res_pool._columns[col]._fields_id
324 # except Exception, e:
327 # fkids = rel_pool.search(cr, 1, [(foreign_key, '=', res_data['id'])])
328 # if fkids.__len__() > 0:
329 # fkdata = rel_pool.read(cr, 1, fkids)
331 # final_res += ' '.join(map(str,fkd.values()))
333 final_res += ' '.join(map(str,res_data.values()))
335 entry_pool.create(cr, uid, {
336 'model':mod['model'],
337 'res_id':res_data['id'],
344 def createIndex(self, cr, uid, ids, context={}):
345 return self.Index(cr, uid, ids, context)
347 def getResult(self, cr, uid, key, reSearch=True, context = {}):
349 # password = self.pool.get('res.users').browse(cr, uid, uid).password
350 # self.server.init(cr.dbname, uid, password, True)
352 if context and context.get('read_all') and key:
354 #res = self.server.search(key)
355 ids = self.search(cr, uid, [('name','ilike',key)])
356 res = self.read(cr, uid, ids, ['model', 'res_id'])
358 raise osv.except_osv('Search Error !!', e.faultString)
362 model = rs.get('model')
363 id = rs.get('res_id')
364 if trs.has_key(model):
373 for mod in res.keys():
375 obj_pool = self.pool.get(mod)
381 name = obj_pool.name_get(cr, 1, [id])[0][1]
382 obj_pool.read(cr, uid, [id])
388 rec_url = '/form/view?model=' + mod + "&id=" + str(id)
389 edit_url = '/form/edit?model=' + mod + "&id=" + str(id)
391 name = name.replace('/',' ')
392 name = name.replace('*',' ')
393 name = name.replace('_',' ')
394 sbuff+= '| # | ' + name + ' | [' + mod + '/' + str(id) + ' - Wiki]' + ' | [' + rec_url + ' - Browse ] | [' + edit_url + ' - Edit ]\n'
397 mid = self.pool.get('ir.model').search(cr, uid, [('model','=',mod)])[0]
398 mod_data = self.pool.get('ir.model').browse(cr, uid, mid).name
399 sbuff = '\n==' + mod_data + '==\n' + sbuff
402 html = self.pool.get('base.wiki').Wiki2Html(buffer)
403 html = html.replace('$s', '<strike>')
404 html = html.replace('$es', '</strike>')
405 return [{'html':html}]
407 # #TODO: need to create an index on the new records
409 # self.Index(cr, uid, context)
410 # self.getResult(cr, uid, key, False, context)
416 class Project(osv.osv):
417 _inherit = 'project.project'
418 _name = 'project.project'
420 'wiki':fields.many2one('base.wiki', 'Wiki'),
421 'dwiki':fields.many2one('base.wiki', 'Developer Wiki'),