Sandy Carter (http://www.savoirfairelinux.com) has proposed merging lp:~savoirfairelinux-openerp/openupgrade-addons/7.0 into lp:openupgrade-addons.
Requested reviews: OpenUpgrade Committers (openupgrade-committers) For more details, see: https://code.launchpad.net/~savoirfairelinux-openerp/openupgrade-addons/7.0/+merge/190413 Handling migration of wiki to document_page. Groups turned into parent pages with type 'category' Wiky syntax converted to html using specifically made python port of Wiki.js Leftover from 6.1 after Upgrade: - Dashboards - OpenERP Web mobile - Process - web Dashboard Missing from 7.0 after Upgrade: - Enterprise Process - View Editor Lost data: - wiki_wiki.tags - wiki_wiki.minor_edit - wiki_wiki.review - wiki_wiki.summary - wiki_wiki.toc - wiki_wiki.section - wiki_wiki_history.minor_edit - wiki_wiki.summary - wiki_make_index - wiki_wiki_page_open Known issues: Views are messed up after upgrade, this is resolved by installing 'Enterprise Process' after the upgrade. -- https://code.launchpad.net/~savoirfairelinux-openerp/openupgrade-addons/7.0/+merge/190413 Your team Savoir-faire Linux' OpenERP is subscribed to branch lp:~savoirfairelinux-openerp/openupgrade-addons/7.0.
=== added file 'document_page/migrations/7.0.1.0.1/post-migration.py' --- document_page/migrations/7.0.1.0.1/post-migration.py 1970-01-01 00:00:00 +0000 +++ document_page/migrations/7.0.1.0.1/post-migration.py 2013-10-10 16:19:03 +0000 @@ -0,0 +1,280 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2013 Savoir-faire Linux +# (<http://www.savoirfairelinux.com>). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +############################################################################## + +from openerp.openupgrade import openupgrade +from openerp import pooler, SUPERUSER_ID + + +def migrate_wiki_to_html(cr, pool): + document_page_obj = pool.get('document.page') + wiky = Wiky() + cr.execute("""\ +SELECT id, content +FROM document_page +WHERE content is not NULL; +""") + for page_line_id, content in cr.fetchall(): + document_page_obj.write( + cr, SUPERUSER_ID, [page_line_id], + {'content': wiky.process(content)} + ) + + [email protected]() +def migrate(cr, version): + pool = pooler.get_pool(cr.dbname) + migrate_wiki_to_html(cr, pool) + +""" +Wiky.py - Python library to converts Wiki MarkUp language to HTML. + Based on Wiki.js by Tanin Na Nakorn + +Copyright © 2013 Sandy Carter <[email protected]> +This work is free. You can redistribute it and/or modify it under the +terms of the Creative Commons Attribution 3.0 Unported License. +(http://creativecommons.org/licenses/by/3.0/legalcode) +""" + +import re + +re_h3 = re.compile("^===[^=]+===$") +re_h2 = re.compile("^==[^=]+==$") +re_h1 = re.compile("^=[^=]+=$") +re_indent = re.compile("^:+") +re_hr = re.compile("^-{4}") +re_ul = re.compile("^\*+ ") +re_ol = re.compile("^#+ ") +re_ul_ol = re.compile("^(\*+|#+) ") +re_ul_li = re.compile("^(\*+|##+):? ") +re_ol_li = re.compile("^(\*\*+|#+):? ") +re_ul_ol_li = re.compile("^(\*+|#+):? ") +re_youtube = re.compile("^(https?://)?(www\.)?youtube.com/(watch\?(.*)v=|embed/)([^&]+)") +re_b_i = re.compile("'''''(([^']|([^']('{1,4})?[^']))+)'''''") +re_b = re.compile("'''(([^']|([^'](''?)?[^']))+)'''") +re_i = re.compile("''(([^']|([^']'?[^']))+)''") + + +class Wiky: + def __init__(self, link_image=None): + self.link_image = link_image + + def process(self, wikitext): + lines = wikitext.split("\n") + html = "" + i = 0 + while i < len(lines): + line = lines[i] + if re_h3.match(line): + html += "<h3>%s</h3>" % line[3:-3] + elif re_h2.match(line): + html += "<h2>%s</h2>" % line[2:-2] + elif re_h1.match(line): + html += "<h1>%s</h1>" % line[1:-1] + elif re_hr.match(line): + html += "<hr/>" + elif re_indent.match(line): + start = i + while i < len(lines) and re_indent.match(lines[i]): + i += 1 + i -= 1 + html += self.process_indent(lines[start: i + 1]) + elif re_ul.match(line): + start = i + while i < len(lines) and re_ul_li.match(lines[i]): + i += 1 + i -= 1 + html += self.process_bullet_point(lines[start: i + 1]) + elif re_ol.match(line): + start = i + while i < len(lines) and re_ol_li.match(lines[i]): + i += 1 + i -= 1 + html += self.process_bullet_point(lines[start: i + 1]) + else : + html += self.process_normal(line) + html += "<br/>\n" + i += 1 + return html + + def process_indent(self, lines): + html = "\n<dl>\n" + i = 0 + while i < len(lines): + line = lines[i] + html += "<dd>" + this_count = len(re_indent.match(line).group(0)) + html += self.process_normal(line[this_count:]) + + nested_end = i + j = i + 1 + while j < len(lines): + nested_count = len(re_indent.match(lines[j]).group(0)) + if nested_count <= this_count: + break + else: + nested_end = j + j += 1 + + if nested_end > i: + html += self.process_indent(lines[i + 1: nested_end + 1]) + i = nested_end + + html += "</dd>\n" + i += 1 + html += "</dl>\n" + return html + + def process_bullet_point(self, lines): + if not len(lines): + return "" + html = "<ul>" if lines[0][0] == "*" else "<ol>" + html += '\n' + i = 0 + while i < len(lines): + line = lines[i] + html += "<li>" + this_count = len(re_ul_ol.match(line).group(1)) + html += self.process_normal(line[this_count+1:]) + + # continue previous with #: + nested_end = i + j = i + 1 + while j < len(lines): + nested_count = len(re_ul_ol_li.match(lines[j]).group(1)) + if nested_count < this_count: + break + elif lines[j][nested_count] == ':': + html += "<br/>" + self.process_normal(lines[j][nested_count + 2:]) + nested_end = j + else: + break + j += 1 + i = nested_end + + # nested bullet point + nested_end = i + j = i + 1 + while j < len(lines): + nested_count = len(re_ul_ol_li.match(lines[j]).group(1)) + if nested_count <= this_count: + break + else: + nested_end = j + j += 1 + + if nested_end > i: + html += self.process_bullet_point(lines[i + 1: nested_end + 1]) + i = nested_end + + # continue previous with #: + nested_end = i + j = i + 1 + while j < len(lines): + nested_count = len(re_ul_ol_li.match(lines[j]).group(1)) + if nested_count < this_count: + break + elif lines[j][nested_count] == ':': + html += self.process_normal(lines[j][nested_count + 2:]) + nested_end = j + else: + break + j += 1 + i = nested_end + html += "</li>\n" + i += 1 + html += "</ul>" if lines[0][0] == "*" else "</ol>" + html += '\n' + return html + + def process_url(self, txt): + css = ('style="background: url(\"%s\") no-repeat scroll ' + 'right center transparent;padding-right: 13px;"' + % self.link_image) if self.link_image else '' + try: + index = txt.index(" ") + url = txt[:index] + label = txt[index + 1:] + except ValueError: + label = url = txt + return """<a href="%s" %s>%s</a>""" % (url, css, label) + + @staticmethod + def process_image(txt): + try: + index = txt.index(" ") + url = txt[:index] + label = txt[index + 1:] + except ValueError: + url = txt + label = "" + return '<img src="%s" alt="%s" />' % (url, label) + + @staticmethod + def process_video(url): + m = re_youtube.match(url) + if not m: + return "<b>%s is an invalid YouTube URL</b>" % url + url = "http://www.youtube.com/embed/" + m.group(5) + return '<iframe width="480" height="390" src="%s" frameborder="0" allowfullscreen=""></iframe>' % url + + def process_normal(self, wikitext): + # Image + while True: + try: + index = wikitext.index("[[File:") + end_index = wikitext.index("]]", index + 7) + wikitext = (wikitext[:index] + + self.process_image(wikitext[index + 7:end_index]) + + wikitext[end_index + 2:]) + except ValueError: + break + + # Video + while True: + try: + index = wikitext.index("[[Video:") + end_index = wikitext.index("]]", index + 8) + wikitext = (wikitext[:index] + + self.process_video(wikitext[index+8:end_index]) + + wikitext[end_index + 2:]) + except ValueError: + break + + # URL + for protocol in ["http","ftp","news"]: + end_index = -1 + while True: + try: + index = wikitext.index("[%s://" % protocol, end_index + 1) + end_index = wikitext.index("]", index + len(protocol) + 4) + wikitext = (wikitext[:index] + + self.process_url(wikitext[index+1:end_index]) + + wikitext[end_index+1:]) + except ValueError: + break + + # Bold, Italics, Emphasis + wikitext = re_b_i.sub("<b><i>\g<1></i></b>", wikitext) + wikitext = re_b.sub("<b>\g<1></b>", wikitext) + wikitext = re_i.sub("<i>\g<1></i>", wikitext) + + return wikitext === added file 'document_page/migrations/7.0.1.0.1/pre-migration.py' --- document_page/migrations/7.0.1.0.1/pre-migration.py 1970-01-01 00:00:00 +0000 +++ document_page/migrations/7.0.1.0.1/pre-migration.py 2013-10-10 16:19:03 +0000 @@ -0,0 +1,118 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2013 Savoir-faire Linux +# (<http://www.savoirfairelinux.com>). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +############################################################################## + +from openerp.openupgrade import openupgrade + +column_drops = [ + ('wiki_wiki', 'tags'), + ('wiki_wiki', 'minor_edit'), + ('wiki_wiki', 'review'), + ('wiki_wiki', 'summary'), + ('wiki_wiki', 'toc'), + ('wiki_wiki', 'section'), + ('wiki_wiki_history', 'minor_edit'), +] + +column_renames = { + 'wiki_wiki': [ + ('text_area', 'content'), + ], + 'wiki_groups': [ + ('template', 'content'), + ], + 'wiki_wiki_history': [ + ('text_area', 'content'), + ('wiki_id', 'page_id'), + ], +} + +table_renames = [ + ('wiki_wiki', 'document_page'), + ('wiki_wiki_history', 'document_page_history'), + ('wiki_create_menu', 'document_page_create_menu'), +] + +model_renames = [ + ('wiki.wiki', 'document.page'), +] + + +def precreate_type_content(cr): + """Pre-create the 'type' column with 'category' as the value""" + cr.execute("""\ +ALTER TABLE wiki_wiki ADD COLUMN type character varying; +COMMENT ON COLUMN wiki_wiki.type IS 'Type';\ +""") + cr.execute("""UPDATE wiki_wiki SET type = 'content';""") + + +def precreate_combine_wiki_groups_wiki_wiki(cr): + """Put wiki_wiki content into wiki_groups, then delete wiki_groups, conserve parent_id""" + cr.execute("""ALTER TABLE wiki_wiki ADD COLUMN old_id integer;""") + cr.execute("""\ +INSERT INTO wiki_wiki(create_uid, create_date, write_date, name, content, type, old_id) +SELECT create_uid, create_date, write_date, name, content, 'category' AS type, id +FROM wiki_groups +ORDER BY id ASC;""") + cr.execute("""\ +UPDATE wiki_wiki w +SET parent_id = (SELECT id FROM wiki_wiki WHERE old_id = w.group_id LIMIT 1) +WHERE group_id IS NOT null;\ +""") + openupgrade.drop_columns(cr, [('wiki_wiki', 'group_id'), ('wiki_wiki', 'old_id')]) + + +def precreate_approver_gid(cr): + """Pre-create the 'approver_gid' column""" + cr.execute("""\ +ALTER TABLE document_page ADD COLUMN approver_gid integer; +COMMENT ON COLUMN document_page.approver_gid IS 'Approver group';\ +""") + cr.execute("""\ +ALTER TABLE document_page + ADD CONSTRAINT document_page_approver_gid_fkey FOREIGN KEY (approver_gid) + REFERENCES res_groups (id) MATCH SIMPLE + ON UPDATE NO ACTION ON DELETE SET NULL;\ +""") + + +def precreate_approval_required(cr): + """Pre-create the 'approval_required' column""" + cr.execute("""\ +ALTER TABLE document_page ADD COLUMN approval_required boolean; +COMMENT ON COLUMN document_page.approval_required IS 'Require approval';\ +""") + + [email protected]() +def migrate(cr, version): + openupgrade.drop_columns(cr, column_drops) + openupgrade.rename_columns(cr, column_renames) + precreate_type_content(cr) + precreate_combine_wiki_groups_wiki_wiki(cr) + openupgrade.rename_tables(cr, table_renames) + openupgrade.rename_models(cr, model_renames) + precreate_approver_gid(cr) + precreate_approval_required(cr) + cr.execute("""DROP TABLE wiki_wiki_page_open;""") + cr.execute("""DROP TABLE wiki_make_index;""") + cr.execute("""DROP TABLE wiki_groups""")
-- Mailing list: https://launchpad.net/~savoirfairelinux-openerp Post to : [email protected] Unsubscribe : https://launchpad.net/~savoirfairelinux-openerp More help : https://help.launchpad.net/ListHelp

